Was ist der Primärschlüssel in einer Zeittabelle?

7

Wenn ich das folgende Tabellendesign verwende, um den Verlauf zu erfassen ...:

CREATE TABLE MyTable (
    insertion_timestamp TIMESTAMP,
    deleted_flag BOOLEAN,
    natural_key INT,
    attribute VARCHAR
);

... was soll dann der Primärschlüssel sein?

(Der Verlaufsmechanismus ist INSERT-only: Aktualisierte Zeilen werden mit einem anderen eingefügt insertion_timestamp, und gelöschte Zeilen werden mit einem anderen Zeitstempel eingefügt und auf deleted_flaggesetzt true.)

Ich denke PRIMARY KEY (insertion_timestamp, deleted_flag, natural_key), aber der einzige Grund für das Einschließen deleted_flagbesteht darin, die Möglichkeit zu berücksichtigen, dass eine Zeile eingefügt und dann (weich) sofort gelöscht wird, früher als das nächste Häkchen der Granularität des TIMESTAMPDatentyps. Das fühlt sich übermäßig paranoid an ...

jl6
quelle
1
Ich mag es nicht, Spaltennamen mit ihren Datentypen zu versehen. Ich denke , ich ziehe insertedAt, isActive( !deleted_flag).
Uhrwerk-Muse
Faire Punkte beides.
6.

Antworten:

3

Ich denke PRIMARY KEY (insertion_timestamp, deleted_flag, natural_key), aber der einzige Grund für das Einfügen von deleted_flag besteht darin, die Möglichkeit zu berücksichtigen, dass eine Zeile eingefügt und dann sofort (weich) gelöscht wird, früher als das nächste Häkchen der Granularität des TIMESTAMPDatentyps. Das fühlt sich übermäßig paranoid an ...

Ich weiß nicht, ob es zu paranoid ist, aber es ist vernünftig, nur festzulegen, dass keine zwei Zeilen dasselbe insertion_timestampund dasselbe teilen dürfen natural_key, und es in die Verantwortung der Kunden zu legen, die die Einfügungen ausführen, um den Randfall zu behandeln. Es vereinfacht die Verwendung der Tabelle erheblich, wenn Sie davon ausgehen können, dass diese Kombinationen eindeutig sind. Außerdem ist es in dem von Ihnen vorgeschlagenen dreigliedrigen Schlüssel schwierig, die Zeilen im dreifach-paranoiden Fall zu ordnen, in dem zwei sofortige "weiche" Löschvorgänge in einer Zeile vorhanden sind.

Meine Empfehlung wäre also PRIMARY KEY (natural_key, insertion_timestamp)(in dieser Reihenfolge - aber ich vermute natural_key, dass sie öfter abgefragt wird, was falsch sein könnte).

Außerdem sollten Sie die folgenden Ergänzungen ernsthaft in Betracht ziehen:

  1. Fügen Sie inactive_timestampden Tabellen eine Spalte hinzu. Auf diese Weise können Sie nach Zeilen abfragen, die zu einem bestimmten Zeitpunkt aktiv waren.
  2. Überlegen Sie genau, was die Zeitstempel bedeuten. Soll die Tabelle die Geschichte der realen Werte darstellen ("Joes Telefonnummer war bis zum 22. Januar 555-5555, ab dem 22. Januar 666-6666") oder die Geschichte der Änderungen an einem "ewigen" Wert? Ihr Schema sieht nach letzterem aus, aber stellen Sie sicher, dass Sie verstehen, welches benötigt wird.
Luis Casillas
quelle
Danke für deine Antwort. 1. Das würde die Abfrage einfacher und wahrscheinlich schneller machen, aber ich versuche gerade, das Modell vollständig zu normalisieren. 2. Ich kenne bitemporale Methoden. Mein Beispiel ist der einfachste Fall. 3. Könnten Sie das Problem der Zeilenreihenfolge näher erläutern, auf das Sie sich im dreifach paranoiden Fall beziehen?
16.
3

In vielen Anwendungen ist es üblich, eine von der Datenbank automatisch generierte Nummer wie eine Sequenznummer als PK zu verwenden. Wenn die Tabelle keinen natürlichen Schlüssel hat und Sie keinen künstlichen Schlüssel verwenden möchten (wie ich vorgeschlagen habe) und die Tabelle keine übergeordnete Tabelle ist, müssen Sie überhaupt keine PK erstellen (Sie können dies trotzdem tun) Erstellen Sie nicht eindeutige Indizes für eine beliebige Kombination von Spalten.

Keine Chance
quelle