Ich müsste Änderungen des Produktpreises nachverfolgen, damit ich die Datenbank nach einem Produktpreis zu einem bestimmten Datum abfragen kann. Die Informationen werden in einem System verwendet, das historische Audits berechnet, sodass der richtige Preis für das richtige Produkt basierend auf dem Kaufdatum zurückgegeben werden muss.
Ich würde es vorziehen, Postgres beim Aufbau der Datenbank zu verwenden.
Ich brauche mit dem Design der Datenbank, aber alle Best-Practice-Vorschläge sind auch willkommen.
database-design
best-practices
Gunnar Norred
quelle
quelle
prices
erstellen Sie eine Tabelleprices_history
mit ähnlichen Spalten. Hibernate Envers kann dies für Sie automatisierenAntworten:
Wenn ich das Szenario angemessen verstehe, sollten Sie eine Tabelle definieren, die eine Preiszeitreihe enthält . Daher stimme ich zu, dass dies viel mit dem zeitlichen Aspekt der Datenbank zu tun hat, mit der Sie arbeiten.
Geschäftsregeln
Beginnen wir mit der Analyse der Situation auf konzeptioneller Ebene. Also, wenn in Ihrer Geschäftsdomäne,
dann bedeutet das das
Das in Abbildung 1 gezeigte IDEF1X- Diagramm zeigt ein solches Szenario, obwohl es stark vereinfacht ist:
Logisches Layout des Expositorys
Das folgende Design auf logischer SQL-DDL-Ebene, das auf dem IDEF1X-Diagramm basiert, zeigt einen praktikablen Ansatz, den Sie genau an Ihre eigenen Anforderungen anpassen können:
Die
Price
Tabelle enthält einen zusammengesetzten PRIMARY KEY, der aus zwei Spalten besteht, dhProductNumber
(wiederum eingeschränkt als FOREIGN KEY, auf den verwiesen wirdProduct.ProductNumber
) undStartDate
(unter Angabe des bestimmten Datums, an dem ein bestimmtes Produkt zu einem bestimmten Preis gekauft wurde ). .Für den Fall , dass Produkte an unterschiedlichen gekauft Preisen im gleichen Tag statt der
StartDate
Spalte können Sie einen als gekennzeichnet sind ,StartDateTime
dass hält die Sofort , wenn ein bestimmte Artikel in einem exakten erworben wurde Preis . Der PRIMARY KEY müsste dann als deklariert werden(ProductNumber, StartDateTime)
.Wie gezeigt, handelt es sich bei der oben genannten Tabelle um eine gewöhnliche Tabelle, da Sie die Operationen SELECT, INSERT, UPDATE und DELETE deklarieren können, um ihre Daten direkt zu bearbeiten. Daher (a) kann die Installation zusätzlicher Komponenten vermieden werden, und (b) kann in allen verwendet werden die wichtigsten SQL-Plattformen mit einigen Anpassungen, falls erforderlich.
Datenmanipulationsbeispiele
Um einige Manipulationen exemplifizieren , die nützlich erscheinen, lassen Sie uns sagen , dass Sie die folgenden Daten in den eingefügt haben
Product
undPrice
Tabellen dargestellt:Da es sich bei dem
Price.EndDate
um einen ableitbaren Datenpunkt handelt, müssen Sie ihn genau über eine abgeleitete Tabelle abrufen, die als Ansicht erstellt werden kann, um die „vollständige“ Zeitreihe zu erstellen, wie im Folgenden veranschaulicht:Dann die folgende Operation, die direkt aus dieser Ansicht auswählt
liefert die nächste Ergebnismenge:
Nehmen wir nun an, dass Sie daran interessiert sind, die gesamten
Price
Daten für dieProduct
primär identifizierten bisProductNumber
1750 amDate
2. Juni 2017 zu erhalten . Wenn Sie sehen, dass einePrice
Zusicherung (oder Zeile) während des gesamten Intervalls , das von (i)StartDate
bis (ii) bis zu (ii) läuft, aktuell oder wirksam istEndDate
, dann diese DML-Operationergibt die folgende Ergebnismenge
die diese Anforderung adressiert.
Wie gezeigt,
PriceWithEndDate
spielt die Ansicht eine entscheidende Rolle beim Abrufen der meisten ableitbaren Daten und kann auf ziemlich gewöhnliche Weise AUSGEWÄHLT werden.Unter Berücksichtigung der Tatsache, dass Ihre bevorzugte Plattform PostgreSQL ist, enthält dieser Inhalt der offiziellen Dokumentationsseite Informationen zu „materialisierten“ Ansichten , die dazu beitragen können, die Ausführungsgeschwindigkeit mithilfe von Mechanismen auf physikalischer Ebene zu optimieren, falls dieser Aspekt problematisch wird. Andere SQL-Datenbankverwaltungssysteme (DBMS) bieten physische Instrumente, die sich sehr ähnlich sind, obwohl möglicherweise andere Begriffe verwendet werden, z. B. "indizierte" Ansichten in Microsoft SQL Server.
Sie können die besprochenen DDL- und DML-Codebeispiele in Aktion in dieser Datenbank-Geige und in dieser SQL-Geige sehen .
Ähnliche Resourcen
In diesen Fragen und Antworten wird ein Geschäftskontext erörtert , der die Änderungen der Produktpreise umfasst, jedoch einen größeren Umfang aufweist, sodass Sie ihn möglicherweise von Interesse finden.
Diese Stapelüberlauf-Posts decken sehr relevante Punkte in Bezug auf den Typ einer Spalte ab, die ein Währungsdatum in PostgreSQL enthält.
Antworten auf Kommentare
Die oben vorgeschlagene Methode adressiert eine Geschäftsdomäne mit den zuvor beschriebenen Merkmalen und wendet folglich Ihren Vorschlag an, die
EndDate
Spalte als Tabelle zu deklarieren, die sich von einem „Feld“ unterscheidet. DiesPrice
würde bedeuten, dass die logische Struktur der Datenbank dies tun würde nicht korrekt sein reflektieren des konzeptionelle Schemas und ein konzeptionelles Schema muss definiert und mit Präzision reflektiert werden, einschließlich der Differenzierung von (1) Basisinformationen aus (2) ableitbaren Informationen.Abgesehen davon würde eine solche Vorgehensweise zu einer Vervielfältigung führen, da die
EndDate
dann aufgrund (a) einer ableitbaren Tabelle und auch aufgrund (b) der genannten BasistabellePrice
mit der daher dupliziertenEndDate
Spalte erhalten werden könnte. Während dies eine Möglichkeit ist, sollte ein Praktiker, wenn er sich für diesen Ansatz entscheidet, die Datenbankbenutzer entschieden vor den damit verbundenen Unannehmlichkeiten und Ineffizienzen warnen. Eine dieser Unannehmlichkeiten und Ineffizienzen ist beispielsweise die dringende Notwendigkeit, einen Mechanismus zu entwickeln, der jederzeit sicherstellt, dass jederPrice.EndDate
Wert gleich dem derPrice.StartDate
Spalte der unmittelbar aufeinanderfolgenden Zeile für denPrice.ProductNumber
vorliegenden Wert ist.Im Gegensatz dazu ist die Arbeit zur Erstellung der fraglichen abgeleiteten Daten, wie ich sie dargelegt habe, ehrlich gesagt überhaupt nicht speziell und muss (i) die korrekte Entsprechung zwischen den logischen und konzeptuellen Abstraktionsebenen der Datenbank gewährleisten und (ii) ) Gewährleistung der Datenintegrität, wobei beide Aspekte, wie bereits erwähnt, ausgesprochen wichtig sind.
Wenn der Effizienzaspekt, von dem Sie sprechen, mit der Ausführungsgeschwindigkeit einiger Datenmanipulationsvorgänge zusammenhängt, muss er an der geeigneten Stelle verwaltet werden, dh auf physischer Ebene, z. B. über eine vorteilhafte Indizierungsstrategie, die auf (1) basiert ) die besonderen Abfragetendenzen und (2) die besonderen physikalischen Mechanismen, die vom DBMS verwendet werden. Andernfalls wird ein robustes System (dh ein wertvolles organisatorisches Gut) leicht zu einer nicht zuverlässigen Ressource, wenn die entsprechende konzeptionell-logische Zuordnung geopfert und die Integrität der beteiligten Daten beeinträchtigt wird.
Diskontinuierliche oder disjunkte Zeitreihen
Andererseits gibt es Umstände, unter denen das Beibehalten der
EndDate
einzelnen Zeilen in einer Zeitreihentabelle nicht nur bequemer und effizienter ist, sondern auch gefordert wird , obwohl dies natürlich ausschließlich von den geschäftsumgebungsspezifischen Anforderungen abhängt. Ein Beispiel für diese Art von Umständen ergibt sich, wennIch habe dieses Szenario in dem in Abbildung 2 gezeigten IDEF1X-Diagramm dargestellt .
In diesem Fall
Price
muss die hypothetische Tabelle auf ähnliche Weise deklariert werden:Und ja, dieses logische DDL-Design vereinfacht die Verwaltung auf physischer Ebene, da Sie eine Indexierungsstrategie erstellen können, die die
EndDate
Spalte (die, wie gezeigt, in einer Basistabelle deklariert ist) in relativ einfacheren Konfigurationen umfasst.Dann eine SELECT-Operation wie die folgende
kann verwendet werden, um die gesamten
Price
Daten für dieProduct
hauptsächlich bisProductNumber
1750 amDate
2. Juni 2017 identifizierten abzuleiten .quelle
Ich glaube, Sie werden sich Temporal Tables ansehen wollen . Diese bieten Funktionen, mit denen Sie genau das tun können, wonach Sie suchen, und sind in Postgres mit den richtigen Erweiterungen verfügbar.
Dieses Konzept scheint auch ziemlich DB-unabhängig zu sein, da es auf einer Vielzahl von RDBMS-Plattformen angeboten wird .
quelle
Ich habe hier eine Antwort gegeben , die relativ einfach ist und keine speziellen Erweiterungen der Datenbank erfordert (daher funktioniert sie mit jeder Datenbank).
quelle