Wofür werden Negativschlüssel verwendet?

12

Etwas neu in der Verwendung von Standard-SQL-Datenbanken (derzeit hauptsächlich mit MySQL).

Wann und warum ist es sinnvoll, eine Tabelle mit negativen (oder eher signierten) Schlüsseln zu indizieren?

Garet Claborn
quelle
5
Zuallererst, wer abstimmt, ohne ein Feedback zu hinterlassen, macht einen schlechten Dienst. Als nächstes die Antwort auf diese ausgezeichnete Frage.
jcolebrand
1
Dieses Thema ist faszinierend. Ich persönlich habe noch nie von diesem Konzept gehört. Diese Frage hätte niemals abgelehnt werden dürfen. +1 von mir für die Einführung dieses Konzepts.
RolandoMySQLDBA

Antworten:

13

Ein Primärschlüssel ist nur ein Wert, den wir als den Wert festgelegt haben, der in einem Datensatz von größter Bedeutung ist. Unabhängig davon, ob dieser Schlüssel ein vorzeichenbehaftetes int, ein vorzeichenloses int, ein String, ein Blob (tatsächlich gibt es Grenzen) oder eine UUID (oder wie auch immer es heute heißt) ist, die Tatsache ist immer noch, dass es sich um einen Schlüssel handelt und dass es sich handelt die Sache von äußerster Wichtigkeit.

Da wir nicht gezwungen sind, nur positiv ausgerichtete Zahlen für unsere Schlüssel zu verwenden, ist es sinnvoll zu berücksichtigen, dass ein vorzeichenbehafteter int nur auf ~ 2 Milliarden steigt, während ein vorzeichenloser int auf ~ 4 Milliarden steigt. Es ist jedoch nichts Falsches daran, ein vorzeichenbehaftetes int zu verwenden, den Anfangswert auf ~ -2 Milliarden zu setzen und ein Inkrement von eins zu setzen. Nach ~ 2 Milliarden Datensätzen werden Sie "Null" treffen und dann werden Sie zu ~ 2 Milliarden weitermachen.

Warum es hilfreich wäre, "negative Schlüssel" in einer Tabelle zu haben, ist die gleiche Frage wie "Warum ist es hilfreich, Schlüssel in einer Tabelle zu haben". Der "Wert" eines Schlüssels hat keinen Einfluss auf seinen Status als Schlüssel. Ein Schlüssel ist ein Schlüssel ist ein Schlüssel.

Wichtig ist, ob der Schlüssel gültig ist.

Ich kann einige Gründe dafür nennen, warum es sinnvoll wäre, negative Schlüssel zuzulassen:

Was wäre, wenn Sie Retouren in einem Verkaufssystem als negative Kundenauftragsnummern angeben möchten, die mit der positiven Kundenauftragsnummer übereinstimmen, wodurch die Korrelation vereinfacht wird (dies ist naiv und schlecht gestaltet, funktioniert jedoch im Sinne einer "Tabellenkalkulation").

Was ist, wenn Sie eine Benutzertabelle haben möchten und angeben, dass diejenigen mit negativen Zahlen systemgesteuert wurden (SO führt genau dies für Chat-Feed-Benutzer aus).

Ich könnte weitermachen, aber der einzige Grund, warum die negative Zahl von Bedeutung ist, ist, wenn Sie oder ich ihr Bedeutung zuweisen. Abgesehen davon gibt es keinen wichtigen Grund dafür, dass der Wert eines Schlüssels Einfluss auf den Schlüssel selbst hat.

jcolebrand
quelle
Bearbeitet das 'Nischenereignis'-Bit, da es mehr als wahrscheinlich ein Missverständnis aufgrund von Unerfahrenheit ist. Interessant zu lesen. Ich hatte ein wenig die Vorstellung, dass es eine Situation geben würde, in der der negative Wert des Schlüssels irgendwie nützlich für die Codierung ist (d. H., Ohne zu entscheiden, dass dies eine bestimmte Sache bedeutet), aber dies ist sehr nützlich, wenn Sie eine starke Aufteilung in zwei Gruppen und don haben
Ich
1
@Garet ~ Also machst du einen guten Punkt: "Der Wert des Schlüssels war irgendwie nützlich beim Codieren" und ich benutze meine Schlüssel von Zeit zu Zeit auf diese Weise, aber das hat nichts mit dem Datenbankaspekt zu tun. Die Datenbank ist ein Lagerhaus. Die Anwendung, die die Daten verwendet, kümmert sich dagegen um die Werte . Aber ja, dieser +/- Boolesche Wert ist ein toller Trick. Ich habe gesehen, dass er so oft für einen solchen Effekt verwendet wurde.
jcolebrand
2
-1 für den Hinweis, dass solche dualen Zielwerte alles andere als eine schlechte Idee sind. Du brauchst ein int und ein bool? Verwenden Sie ein Int und ein Bool.
Jack sagt, versuchen Sie topanswers.xyz
1
@JackPDouglas Ich kann mich nicht erinnern, die Leute dazu ermutigt zu haben. Ich kann mich strikt daran erinnern, dass das Feld und seine Daten zwei verschiedene Dinge sind. Vielen Dank, dass Sie zumindest konstruktives Feedback zu Ihrer Ablehnung gegeben haben, aber ich kann nicht sagen, dass diese Beobachtung im Lichte des Konzepts "Wofür werden negative Schlüssel verwendet?" . Ich wollte hervorheben, wie diese Dinge in der Anwendungsebene verwendet werden, aber in der Datenbankebene haben sie keine Bedeutung.
Jcolebrand
1
@JackPDouglas ~ Ich habe dieses spezielle Beispiel verwendet, weil es eine sehr bekannte Site (ein Netzwerk von Sites) gibt, von der Sie vielleicht gehört haben, dass sie genau das tut "Trick". Überprüfen Sie diesen Benutzer dba.stackexchange.com/users/-1/community und teilen Sie mir seine ID mit. Ich kann Ihnen fast versichern, dass die Benutzer-ID der Primärschlüssel (und in vielen anderen Tabellen ein Fremdschlüssel) ist. Nur weil es für Sie ein schlechtes Anwendungsdesign ist, heißt das noch lange nicht, dass es nicht gültig ist. Aber noch einmal, das ist nicht db design, das ist domain design. Zugegeben, die
DB-
10

Wenn es um Identitäts- oder Autonummerierungsspalten geht, sollte der Wert selbst keine Bedeutung haben. (manchmal schon, wie in den von drachenstern erwähnten Chat-Usern von SO, die ich vor mir selbst gemacht habe)

Im Allgemeinen verlieren Sie jedoch die Hälfte Ihrer Reichweite, wenn Sie Ganzzahlen mit Vorzeichen verwenden.
Siehe: Was tun, wenn sich ein Feld in einer Tabelle der maximalen vorzeichenbehafteten oder vorzeichenlosen 32-Bit-Ganzzahl nähert?

Ein weiteres Beispiel: In kleinen Replikationsszenarien gibt die Verwendung negativer Werte für einen Standort und positiver Werte für einen anderen implizites Wissen über die Quelle einer bestimmten Zeile.

gbn
quelle
und stellen Sie sicher, dass Sie die eingegebenen Werte an jedem Standort irgendwie einschränken, da Sie sonst in ein schreckliches Chaos geraten, wenn sich herausstellt, dass Ihr "implizites Wissen" falsch ist.
Jack sagt, versuchen Sie topanswers.xyz
@JackPDouglas: würden Sie NOT FOR REPLICATION verwenden zu vermeiden Werte auf der falschen Seite zu erzeugen
GBN
zusammen mit Check-Einschränkungen ? Gibt es auch ein MySQL (oder ein anderes) Analogon von NOT FOR REPLICATIONdem Sie wissen?
Jack sagt, versuchen Sie topanswers.xyz
@JackPDouglas: sorry, nicht sicher nicht SQL Server
GBN
8

Nicht alle Datenbanksysteme unterstützen sogar Integer-Typen ohne Vorzeichen, wobei MSSQL einer der Typen ist, bei denen dies nicht der Fall ist. In diesen Fällen sind negative Werte in Ganzzahlschlüsselfeldern nur möglich, weil sie im Typ möglich sind (Sie können Regeln oder Trigger verwenden, um sie zu blockieren, wie in diesem Beispiel gezeigt , aber es ist wahrscheinlich nicht erforderlich, den Aufwand für die Durchsetzung solcher Regeln zu erhöhen jedes inters / update).

Für die Datenbank spielt der tatsächliche Wert eines Primärschlüssels keine Rolle, solange er in der Tabelle eindeutig ist. -42 und 42 sind nur zwei verschiedene Zahlen in der gleichen Weise, wie es 42 und 69 sind - die Bedeutung wird nur auf die Negativität oder nicht auf den Wert durch Ihren Code übertragen.

Die Nichtunterstützung von Integer-Typen ohne Vorzeichen ist wahrscheinlich eine Entwurfsentscheidung, die auf der Reduzierung der Komplexität beruht. Das heißt, zwei verschiedene 32-Bit-Integer-Typen müssen sich nicht darum kümmern, Bereiche beim Zuweisen von Werten zwischen ihnen zu überprüfen. Die Anzahl der möglichen Indizes in einem Auto-Inkrement-Feld, beginnend mit 0 oder 1, ist zwar auf die Hälfte begrenzt, was bei einem vorzeichenlosen Typ (~ 2e9 statt ~ 4e9) möglich wäre, dies ist jedoch selten ein bedeutendes Problem (falls Sie es wahrscheinlich benötigen) Eine Reihe von Schlüsselwerten dieser Größenordnung haben Sie wahrscheinlich ohnehin für einen 64-Bit-Typ gewählt, insbesondere wenn Sie eine 64-Bit-Architektur verwenden, bei der solche Werte nicht weniger effizient verarbeitet werden als 32-Bit-Werte Wenn Sie aus Platzgründen bei 32-Bit bleiben, können Sie das Inkrement bei -2.147.483.647 beginnen.

David Spillett
quelle
Yup, ich denke, wir haben diesen Grund schon einmal abgehandelt
jcolebrand
tinyint ist ohne Vorzeichen (0 .. 255). Normalerweise erstelle ich eine Check-Einschränkung für Ganzzahlspalten, um sicherzustellen, dass die Werte nicht negativ sind, da zwangsläufig Code geschrieben wird, der dies implizit voraussetzt, und seltsame Fehler auftreten, wenn sich ein negativer Wert einschleicht.
Ed Avis