Que faire lorsqu'un champ d'une table se rapproche de l'entier 32 bits maximum signé ou non signé?

14

Dans une base de données donnée contenant des enregistrements utilisateur sous la forme d'un champ d'auto-incrémentation unique (pour les besoins de l'exemple, les messages inter-utilisateurs) ... que faire le moment venu et qu'il approche du nombre maximum signé ou non signé du type de données actuel? (INT 32 bits)? Je suppose que le serveur de base de données déborderait lorsqu'il essaierait d'attribuer le numéro (2∧32) -1 à l'entrée suivante, alors, comment éviter que cela se produise (sans changer le type de données, pour le bien de la question) et continuer à ajouter des enregistrements? Qu'est-ce que tu ferais?

Pourquoi devrais-je utiliser des INT et non, par exemple, des VARCHARS?

Cela fait plusieurs jours que je ne me suis pas posé cette question hypothétique et j'aimerais savoir ce qu'un professionnel ferait.

AeroCross
la source

Réponses:

12

Vous utiliserez généralement des entiers plutôt que des varchars car ils consomment moins d'espace, ont un schéma de tri bien compris et sont rapides à indexer, etc. Les entiers sont des types de données naturels d'un processeur, et donc les performances sont généralement optimales. En général, un entier fait 4 octets, ce qui équivaut à seulement 4 caractères dans un varchar (non unicode).

Si vous craigniez de manquer d'espace avec un type INT, essayez BIGINT, qui vous donne des nombres à 8 octets. La limite est assez énorme, et vous manquerez probablement d'espace disque avant d'atteindre cette limite d'enregistrements :-) Les performances de BIGINT vont également être très bonnes, d'autant plus que de nombreux serveurs sont désormais également 64 bits. .

La réponse à la première partie de votre question sur ce qui se passe lorsque vous manquez d'INT n'est pas simple, surtout comme vous l'avez dit sans changer le type de données en BIGINT. Fondamentalement, vous ne pouvez pas faire grand-chose et ce que vous pouvez faire est très limité par la nature des données de votre base de données. Quels enregistrements ont une clé étrangère pour ces données? Avez-vous toujours besoin de toutes les données de cette table et des enregistrements associés? En supposant que vous puissiez archiver une grande partie des données initiales (et ses données associées), la seule chose que je peux suggérer est de déplacer les données hors de la table (disons les 1 à X premiers enregistrements), puis réinitialiser la graine d'identité à 1. Il y a toutes sortes de raisons que je ne recommanderais pas - par exemple, il y a beaucoup de bits de code que j'ai vu qui font des choses comme vérifier la valeur maximale d'un champ id, pour voir ce qui vient d'être ajouté, et cela ne fonctionnerait pas (et ne devrait pas être fait). De plus, les gens supposent que l'enregistrement N a été créé avant N + 1. Pas de réponse facile je pense.

Enfin, je ne sais pas pour MySQL, mais SQL Server donnerait une erreur de débordement si vous atteigniez la limite.

Miles D
la source
1
Je suis satisfait d'une réponse aussi détaillée. Merci pour l'explication de l'accord avec VARCHAR, INT et BIGINT. La question étant hypothétique, je me demande ce qui se passerait si la limite BIGINT était également atteinte. La question a été soulevée par un message que j'ai vu sur Facebook en utilisant les INT et en atteignant la limite, et je le vois comme tout à fait possible. L'archivage fonctionnerait, ou créerait une deuxième table avec une instruction conditionnelle (qui, comme vous l'avez dit, nécessiterait également la mise à jour des scripts, et ce serait assez complexe). Dans l'ensemble, excellente réponse. J'apprécie le temps pris.
AeroCross
9

Un point négligé est que de nombreuses personnes commencent le numéro automatique ou l'identité à 1, perdant ainsi la moitié de la plage possible immédiatement (pour signé)

Vous redéfiniriez simplement le nombre pour commencer à -1, incrémenter -1 dans ce cas.

Sans doute, si vous vous attendiez à remplir votre colonne d'identité, vous devriez avoir conçu cela et utilisé un type de données plus large au début.

Voir cette question récente sur SO: SQL Server 2008: que s'est-il passé si l'identité dépasse une valeur maximale de int?

gbn
la source
Il est logique que j'utilise un type de données plus large (pour une table qui ferait COMME CETTE quantité de données), mais comme c'était une question hypothétique, je voulais un aperçu. S'il est signé, cela peut fonctionner (mais je serais un peu bizarre d'avoir une clé primaire avec des nombres négatifs, à mon humble avis) et je pense que c'est assez intelligent. Cela donnerait le temps au DBA d'archiver les données positives et de recommencer. Si non signé, eh bien ... problèmes.
AeroCross
Alternativement à l'utilisation d'un incrément de -1 à partir de -1, commencez par (-2147483648) et incrémentez de 1. Mais oui, après avoir traversé INT_MAX, vous êtes assez bien arrosé et devez revoir le design et supprimer l'ancien index en le remplaçant avec un nouveau plus grand. et si vous passez BIGINT non signé alors je veux venir travailler dans votre équipe;)
jcolebrand
PostgreSQL utilise des séquences pour générer des numéros d'identification; l'instruction CREATE SEQUENCE vous permet de spécifier CYCLE, qui se terminera simplement si vous atteignez la valeur maximale. (Ou la valeur minimale, si vous allez dans l'autre sens.) L'option CYCLE est maintenant dans les normes SQL. (Depuis au moins 2003.)
Mike Sherrill 'Cat Recall'
4

Débordement BIGINT? Haha. Découvrez d'abord comment atteindre l'immortalité. INT UNSIGNED (4 milliards) est déjà assez difficile à atteindre. 100 INSERTs par seconde approcheraient d'un débordement INT en un an. BIGINT prendrait plusieurs milliards d'années.

Pour corriger: ALTER TABLE foo MODIFY COLUMN id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT; Mais cela prendra des heures car il copiera sur la table (qui compte près de 4 milliards de lignes, non?) Et reconstruira tous les index secondaires. Planifier à l'avance.

Généralement, lorsque vous essayez de stocker un nombre trop grand pour un champ (par exemple, 999 dans un TINYINT UNSIGNED), il le plafonnera silencieusement au maximum pour le champ (255 dans ce cas). Il peut y avoir un "avertissement", mais la plupart des gens ne prennent pas la peine de vérifier les avertissements. S'il s'agit d'un champ UNIQUE ou s'il existe des CLÉS ÉTRANGÈRES, vous pourriez obtenir une erreur plus grave.

CHAR ou VARCHAR est tronqué en silence à l'espace disponible.

Rick James
la source