Ich habe kürzlich das Konzept von ROWGUID untersucht und bin auf diese Frage gestoßen . Diese Antwort gab einen Einblick, hat mich aber zu einem anderen Kaninchenbau geführt, mit der Erwähnung, den Primärschlüsselwert zu ändern.
Mein Verständnis war schon immer, dass ein Primärschlüssel unveränderlich sein sollte, und meine Suche seit dem Lesen dieser Antwort ergab nur Antworten, die die gleichen wie eine bewährte Vorgehensweise widerspiegeln.
Unter welchen Umständen muss ein Primärschlüsselwert geändert werden, nachdem der Datensatz erstellt wurde?
database-design
primary-key
5 voll
quelle
quelle
Antworten:
Wenn Sie den Namen einer Person als Primärschlüssel verwenden und deren Name geändert wird, müssen Sie den Primärschlüssel ändern. Dies wird
ON UPDATE CASCADE
verwendet, da es die Änderung im Wesentlichen auf alle verknüpften Tabellen kaskadiert , die Fremdschlüsselbeziehungen zum Primärschlüssel haben.Beispielsweise:
A
SELECT
gegen beide Tische:Kehrt zurück:
Wenn wir die
PersonKey
Spalte aktualisieren und Folgendes erneut ausführenSELECT
:wir sehen:
Wenn
UPDATE
wir den Plan für die obige Anweisung betrachten, sehen wir deutlich, dass beide Tabellen durch eine einzelne Aktualisierungsanweisung aufgrund des Fremdschlüssels aktualisiert werden, der wie folgt definiert istON UPDATE CASCADE
:Klicken Sie auf das Bild, um es deutlicher zu sehen
Zuletzt bereinigen wir unsere temporären Tabellen:
Die bevorzugte 1 Möglichkeit, dies mit Ersatzschlüsseln zu tun, wäre:
Der Vollständigkeit halber ist der Plan für die Aktualisierungsanweisung sehr einfach und zeigt einen Vorteil gegenüber Ersatzschlüsseln: Im Gegensatz zu jeder Zeile, die den Schlüssel in einem Natural-Key-Szenario enthält , muss nur eine einzige Zeile aktualisiert werden:
Die Ausgabe der beiden
SELECT
obigen Anweisungen lautet:Im Wesentlichen ist das Ergebnis in etwa gleich. Ein wesentlicher Unterschied besteht darin, dass der breite natürliche Schlüssel nicht in jeder Tabelle wiederholt wird, in der der Fremdschlüssel vorkommt. In meinem Beispiel verwende ich eine
VARCHAR(200)
Spalte, um den Namen der Person zu speichern, was die Verwendung einesVARCHAR(200)
überall erforderlich macht . Wenn viele Zeilen und Tabellen den Fremdschlüssel enthalten, wird viel Speicher verschwendet. Hinweis: Ich spreche nicht davon, dass Speicherplatz verschwendet wird, da die meisten Leute sagen, dass Speicherplatz so billig ist, dass er im Wesentlichen frei ist. Speicher ist jedoch teuer und verdient es, geschätzt zu werden. Wenn Sie eine 4-Byte-Ganzzahl für den Schlüssel verwenden, wird viel Speicherplatz gespart, wenn Sie die durchschnittliche Namenslänge von etwa 15 Zeichen berücksichtigen.Tangential zu der Frage, wie und warum sich Schlüssel ändern können, ist die Frage, warum natürliche Schlüssel anstelle von Ersatzschlüsseln gewählt werden. Dies ist eine interessante und vielleicht wichtigere Frage, insbesondere, wenn Leistung ein Entwurfsziel ist. Siehe meine Frage dazu hier .
1 - http://weblogs.sqlteam.com/mladenp/archive/2009/10/06/Warum-Ich-präferiere-surrogate-keys-instead-of-natural-keys-in.aspx
quelle
Während Sie einen natürlichen und / oder veränderlichen Schlüssel als PK verwenden können, führt dies nach meiner Erfahrung zu Problemen, die häufig durch die Verwendung eines PK verhindert werden können, der diese Bedingungen erfüllt:
Beispielsweise versuchen viele Unternehmen in den USA, Sozialversicherungsnummern als persönliche ID-Nummern (und PKs) in ihren Systemen zu verwenden. Dann treten folgende Probleme auf: Dateneingabefehler, die zu mehreren zu reparierenden Datensätzen führen, Personen ohne SSN, Personen, deren SSN von der Regierung geändert wurde, Personen mit doppelten SSNs.
Ich habe jedes einzelne dieser Szenarien gesehen. Ich habe auch Firmen gesehen, die nicht wollten, dass ihre Kunden "nur eine Nummer" sind, was bedeutete, dass ihre PK "First + Middle + Last + DOB + Zip" oder ein ähnlicher Unsinn war. Sie haben zwar genug Felder hinzugefügt, um fast die Eindeutigkeit zu gewährleisten, aber ihre Abfragen waren entsetzlich, und die Aktualisierung eines dieser Felder bedeutete, Probleme mit der Datenkonsistenz zu beseitigen.
Nach meiner Erfahrung ist eine von der Datenbank selbst generierte PK fast immer eine bessere Lösung.
Ich empfehle diesen Artikel für zusätzliche Hinweise: http://www.agiledata.org/essays/keys.html
quelle
Der Primärschlüssel kann geändert werden, wenn eine Synchronisierung erforderlich ist. Dies kann der Fall sein, wenn Sie einen nicht verbundenen Client haben und die Daten in bestimmten Intervallen mit dem Server synchronisiert werden.
Vor ein paar Jahren habe ich an einem System gearbeitet, in dem alle Ereignisdaten auf dem lokalen Computer negative Zeilen-IDs hatten, z. B. -1, -2 usw. Bei der Synchronisierung der Daten mit dem Server wurde die Zeilen-ID auf dem Server auf den Server angewendet Klient. Angenommen, die nächste Zeilen-ID auf dem Server war 58. Dann würde -1 zu 58, -2 zu 59 und so weiter. Diese Zeilen-ID-Änderung würde auf alle untergeordneten FK-Datensätze auf dem lokalen Computer kaskadiert. Der Mechanismus wurde auch verwendet, um zu bestimmen, welche Datensätze zuvor synchronisiert wurden.
Ich sage nicht, dass dies ein gutes Design war, aber es ist ein Beispiel dafür, wie sich der Primärschlüssel im Laufe der Zeit ändert.
quelle
Jedes Design, bei dem das
PRIMARY KEY
regelmäßig geändert wird, ist ein Rezept für eine Katastrophe. Der einzige gute Grund für eine Änderung wäre der Zusammenschluss von zwei zuvor getrennten Datenbanken.Wie von @MaxVernon hervorgehoben, können gelegentliche Änderungen auftreten - dann verwenden
ON UPDATE CASCADE
, obwohl die meisten Systeme heutzutage eine ID als Ersatz verwendenPRIMARY KEY
.Puristen wie Joe Celko und Fabian Pascal (eine Seite, der man unbedingt folgen sollte) sind mit der Verwendung von Ersatzschlüsseln nicht einverstanden, aber ich denke, dass sie diesen Kampf verloren haben.
quelle
Stabilität ist eine wünschenswerte Eigenschaft für einen Schlüssel, aber es ist eine relative Sache und keine absolute Regel. In der Praxis ist es oft nützlich, die Werte von Schlüsseln zu ändern. In relationaler Hinsicht sind Daten nur über ihre (Super-) Schlüssel identifizierbar. Wenn es nur einen Schlüssel in einer gegebenen Tabelle gibt, dann ist die Unterscheidung zwischen A) Ändern eines Schlüsselwerts oder B) Ersetzen der Reihe von Zeilen in einer Tabelle durch eine ähnliche oder andere Reihe von Zeilen, die andere Schlüsselwerte enthalten, im wesentlichen eher eine Frage der Semantik als der Logik.
Ein interessanteres Beispiel ist der Fall einer Tabelle mit mehreren Schlüsseln, bei der sich die Werte eines oder mehrerer dieser Schlüssel möglicherweise im Verhältnis zu anderen Schlüsselwerten ändern müssen. Nehmen Sie das Beispiel einer Employee-Tabelle mit zwei Schlüsseln: LoginName und Badge Number. Hier ist eine Beispielzeile aus dieser Tabelle:
Wenn ZoeS ihren Ausweis verliert, erhält sie möglicherweise einen neuen Ausweis und eine neue Ausweisnummer:
Später könnte sie beschließen, ihren Anmeldenamen zu ändern:
Beide Schlüsselwerte veränderten sich - im Verhältnis zueinander. Es ist zu beachten, dass es nicht unbedingt einen Unterschied macht, welches als "primär" eingestuft wird.
In der Praxis ist "Unveränderlichkeit", dh absolut nie eine Änderung eines Wertes, unerreichbar oder zumindest unmöglich zu überprüfen. In dem Maße, in dem Änderungen überhaupt einen Unterschied bewirken, ist es wahrscheinlich am sichersten anzunehmen, dass sich ein Schlüssel (oder ein Attribut) ändern muss.
quelle
Interessanterweise bietet die verknüpfte Frage zu ROWGUID einen eigenen Anwendungsfall: Wenn in Datenbanken, die synchronisiert werden müssen, widersprüchliche Primärschlüssel vorliegen. Wenn Sie zwei Datenbanken haben, die abgeglichen werden müssen, und diese Sequenzen für Primärschlüssel verwenden, möchten Sie, dass einer der Schlüssel geändert wird, damit er eindeutig bleibt.
In einer idealen Welt würde dies niemals passieren. Sie würden zunächst GUIDs für die Primärschlüssel verwenden. Realistisch gesehen ist es jedoch möglich, dass Sie zu Beginn des Entwurfs noch nicht einmal über eine verteilte Datenbank verfügen. Die Konvertierung in GUIDs war möglicherweise eine Maßnahme, die im Folgenden als vorrangig eingestuft wurde, da sie eine höhere Auswirkung hatte als die Implementierung des Schlüsselupdates. Dies kann vorkommen, wenn Sie über eine große Codebasis verfügen, die von Ganzzahlschlüsseln abhängt und für die Konvertierung in die GUID eine umfangreiche Überarbeitung erforderlich ist. Es gibt auch die Tatsache, dass spärliche GUIDs (GUIDs, die nicht sehr nah beieinander liegen, was passiert, wenn Sie sie zufällig generieren, wie Sie sollten) Probleme für bestimmte Arten von Indizes verursachen können, was bedeutet, dass Sie die Verwendung vermeiden möchten sie als Primärschlüssel (erwähnt von Byron Jones ).
quelle
Ein mögliches Szenario ist, dass Sie über Partner mit einer eindeutigen ID verfügen und wissen, dass sie nicht über Partner hinweg dupliziert werden, da sie einen eindeutigen Startcharakter haben. Die Partner laden Daten in eine Mastertabelle. Dort werden Datensätze verarbeitet und anschließend eine Master-ID vergeben. Benutzer benötigen Zugriff auf die Datensätze, sobald sie geladen sind, auch wenn sie noch nicht verarbeitet wurden. Sie möchten, dass die Master-ID auf der verarbeiteten Bestellung basiert und nicht immer in der Reihenfolge verarbeitet wird, in der die Datensätze geladen wurden. Ich weiß, ein bisschen erfunden.
quelle
Stellen Sie sich eine Situation vor, in der jemand die NIN (National Insurance Number) als Primärschlüssel gewählt hat und auf irgendeine Weise ein Bediener eine Zeile mit der falschen NIN einfügt. Nach dem Einfügen des Werts gibt es zwei Möglichkeiten, um den Fehler zu beheben:
quelle