Was tun, wenn sich ein Feld in einer Tabelle der maximalen vorzeichenbehafteten oder vorzeichenlosen 32-Bit-Ganzzahl nähert?
14
In jeder Datenbank, die Benutzerdatensätze in Form eines eindeutigen Auto-Inkrement-Felds enthält (zum Beispiel Nachrichten zwischen Benutzern) ... was zu tun ist, wenn die Zeit gekommen ist und sich die maximale vorzeichenbehaftete oder vorzeichenlose Zahl nähert des aktuellen Datentyps? (Ein 32-Bit-INT)? Ich vermute, dass der Datenbankserver überlaufen würde, wenn er versucht, dem nächsten Eintrag die (2 -132) -1-Zahl zuzuweisen. Wie kann man dies vermeiden (ohne den Datentyp zu ändern, um der Frage willen) und Weitere Datensätze hinzufügen? Was würden Sie tun?
Warum sollte ich INTs verwenden und nicht beispielsweise VARCHARS?
Es ist einige Tage her, seit ich mir diese hypothetische Frage gestellt habe und ich möchte wissen, was ein Fachmann tun würde.
Sie würden im Allgemeinen Ganzzahlen anstelle von Varchars verwenden, da diese weniger Speicherplatz beanspruchen, gut verstandene Sortiermuster aufweisen, die schnell indiziert werden können usw. Ganzzahlen sind natürliche Datentypen einer CPU, und daher ist die Leistung im Allgemeinen optimal. Normalerweise besteht eine Ganzzahl aus 4 Bytes, was nur 4 Zeichen in einem (Nicht-Unicode-) Varchar entspricht.
Wenn Sie befürchten, dass Ihnen mit einem INT-Typ der Speicherplatz ausgeht, versuchen Sie es mit BIGINT, bei dem Sie 8-Byte-Zahlen erhalten. Das Limit dafür ist ziemlich groß, und Ihnen würde wahrscheinlich der Speicherplatz ausgehen, bevor Sie dieses Limit erreicht haben :-) Die Leistung von BIGINT wird auch sehr gut sein, zumal viele Server jetzt auch 64-Bit sind .
Die Antwort auf den ersten Teil Ihrer Frage, was passiert, wenn Sie in INTs ausgehen, ist nicht einfach, besonders wie Sie sagten, ohne den Datentyp in BIGINT zu ändern. Grundsätzlich können Sie nicht viel tun, und was Sie möglicherweise tun können, hängt stark von der Art der Daten in Ihrer Datenbank ab. Welche Datensätze sind mit Fremdschlüsseln für diese Daten versehen? Benötigen Sie noch alle Daten in dieser Tabelle und die zugehörigen Datensätze? Unter der Annahme, dass Sie viele der ursprünglichen Daten (und die zugehörigen Daten) archivieren können, kann ich nur vorschlagen, die Daten aus der Tabelle zu verschieben (sagen wir die ersten 1 bis X Millionen Datensätze) und dann Zurücksetzen des Identitäts-Seeds auf 1. Es gibt viele Gründe, die ich jedoch nicht empfehlen würde - zum Beispiel habe ich viele Code-Bits gesehen, die zum Beispiel den Maximalwert eines ID-Felds prüfen. zu sehen, was gerade hinzugefügt wurde, und das würde nicht funktionieren (und sollte nicht getan werden). Außerdem wird davon ausgegangen, dass Datensatz N vor N + 1 erstellt wurde. Keine einfache Antwort, denke ich.
Schließlich weiß ich nichts über MySQL, aber SQL Server würde einen Überlauffehler auslösen, wenn Sie das Limit erreichen.
Ich freue mich über eine so ausführliche Antwort. Vielen Dank für die Erklärung des VARCHAR-, INT- und BIGINT-Deals. Da die Frage hypothetisch ist, frage ich mich, was passieren würde, wenn auch die BIGINT-Grenze erreicht wird. Die Frage wurde von einem Beitrag aufgeworfen, den ich über Facebook mit INTs gesehen habe und der das Limit erreicht hat, und den ich für absolut möglich halte. Die Archivierung würde funktionieren oder eine zweite Tabelle mit einer bedingten Anweisung erstellen (die, wie Sie sagten, auch die Aktualisierung von Skripten erfordern würde und ziemlich komplex wäre). Insgesamt eine gute Antwort. Ich weiß die Zeit zu schätzen.
AeroCross
9
Ein übersehener Punkt ist, dass viele Leute die automatische Nummer oder Identität bei 1 beginnen und somit sofort die Hälfte des möglichen Bereichs verlieren (für signierte).
Sie definieren die Zahl einfach neu, um bei -1 zu beginnen. In diesem Fall erhöhen Sie -1.
Wenn Sie jemals damit gerechnet haben, Ihre Identitätsspalte auszufüllen, sollten Sie dies einplanen und zu Beginn einen breiteren Datentyp verwenden.
Es ist logisch, dass ich einen breiteren Datentyp verwende (für eine Tabelle, die genau so viele Daten enthält), aber da es sich um eine hypothetische Frage handelt, wollte ich einen Einblick. Wenn es signiert ist, könnte das funktionieren (aber ich wäre ein bisschen seltsam, wenn ich einen Primärschlüssel mit negativen Zahlen hätte, IMHO), und ich denke, es ist ziemlich clever. Es würde dem DBA Zeit geben, die positiven Daten zu archivieren und erneut zu starten. Wenn nicht unterschrieben, na ja ... Probleme.
AeroCross
Alternativ zur Verwendung eines -1-Inkrements von -1 können Sie bei (-2147483648) beginnen und um 1 inkrementieren. Aber ja, nachdem Sie INT_MAX gekreuzt haben, sind Sie ziemlich zufrieden und müssen das Design überarbeiten und den alten Index entfernen, der ihn ersetzt mit einem neuen größeren. und wenn du BIGINT ohne Vorzeichen überholst, dann möchte ich mit deinem Team arbeiten;)
jcolebrand
PostgreSQL verwendet Sequenzen, um ID-Nummern zu generieren. Mit der Anweisung CREATE SEQUENCE können Sie CYCLE angeben, das sich nur umgibt, wenn Sie den Maximalwert erreichen. (Oder der Mindestwert, wenn Sie in die andere Richtung gehen.) Die Option CYCLE ist jetzt in den SQL-Standards enthalten. (Seit mindestens 2003.)
Mike Sherrill 'Cat Recall'
4
Überlauf BIGINT? Haha. Finde zuerst heraus, wie du Unsterblichkeit erreichen kannst. INT UNSIGNED (4 Milliarden) ist schwer zu erreichen. 100 INSERTs pro Sekunde würden in einem Jahr fast zu einem INT-Überlauf führen. BIGINT würde mehrere Milliarden Jahre dauern.
Behebung: ALTER TABLE foo ÄNDERN SPALTE ID BIGINT UNSIGNED NICHT NULL AUTO_INCREMENT; Dies wird jedoch Stunden dauern, da die Tabelle (die fast 4 Milliarden Zeilen enthält, richtig?) Kopiert und alle Sekundärindizes neu erstellt werden. Vorausplanen.
Wenn Sie im Allgemeinen versuchen, eine Zahl zu groß für ein Feld zu speichern (z. B. 999 in einem TINYINT UNSIGNED), wird sie stillschweigend auf das Maximum für das Feld begrenzt (in diesem Fall 255). Möglicherweise gibt es eine "Warnung", aber die meisten Leute machen sich nicht die Mühe, Warnungen zu überprüfen. Wenn es sich um ein EINZIGARTIGES Feld handelt oder es sich um AUSLÄNDISCHE SCHLÜSSEL handelt, wird möglicherweise ein schwerwiegenderer Fehler angezeigt.
CHAR oder VARCHAR wird stillschweigend auf den verfügbaren Speicherplatz gekürzt.
Ein übersehener Punkt ist, dass viele Leute die automatische Nummer oder Identität bei 1 beginnen und somit sofort die Hälfte des möglichen Bereichs verlieren (für signierte).
Sie definieren die Zahl einfach neu, um bei -1 zu beginnen. In diesem Fall erhöhen Sie -1.
Wenn Sie jemals damit gerechnet haben, Ihre Identitätsspalte auszufüllen, sollten Sie dies einplanen und zu Beginn einen breiteren Datentyp verwenden.
Siehe die aktuelle Frage zu SO: SQL Server 2008: Was ist passiert, wenn die Identität einen Maximalwert von int überschreitet?
quelle
Überlauf BIGINT? Haha. Finde zuerst heraus, wie du Unsterblichkeit erreichen kannst. INT UNSIGNED (4 Milliarden) ist schwer zu erreichen. 100 INSERTs pro Sekunde würden in einem Jahr fast zu einem INT-Überlauf führen. BIGINT würde mehrere Milliarden Jahre dauern.
Behebung: ALTER TABLE foo ÄNDERN SPALTE ID BIGINT UNSIGNED NICHT NULL AUTO_INCREMENT; Dies wird jedoch Stunden dauern, da die Tabelle (die fast 4 Milliarden Zeilen enthält, richtig?) Kopiert und alle Sekundärindizes neu erstellt werden. Vorausplanen.
Wenn Sie im Allgemeinen versuchen, eine Zahl zu groß für ein Feld zu speichern (z. B. 999 in einem TINYINT UNSIGNED), wird sie stillschweigend auf das Maximum für das Feld begrenzt (in diesem Fall 255). Möglicherweise gibt es eine "Warnung", aber die meisten Leute machen sich nicht die Mühe, Warnungen zu überprüfen. Wenn es sich um ein EINZIGARTIGES Feld handelt oder es sich um AUSLÄNDISCHE SCHLÜSSEL handelt, wird möglicherweise ein schwerwiegenderer Fehler angezeigt.
CHAR oder VARCHAR wird stillschweigend auf den verfügbaren Speicherplatz gekürzt.
quelle