2017-09-22 22 views
1

Je fais un peu de recherche pour un problème qui pourrait survenir un jour. Disons que vous avez une table InnoDB MySQL avec un identifiant et un champ de nom. le champ id a BIGINT (20) et est AUTO_INCREMENT plus sa clé primaire. Que faites-vous dans le cas où cette table est pleine, ce qui signifie que nous avons atteint la limite de l'identifiant et qu'aucun numéro d'incrémentation automatique ne peut plus être généré.Que faire si la valeur d'incrémentation automatique atteint sa limite?

+0

'code'tinyint: 1 octet, -128 à +127/0 à 255 (non signé) smallint: 2 octets, -32,768 à +32,767/0 à 65,535 (non signé) mediumint: 3 octets, -8,388,608 à 8,388,607/0 à 16,777,215 (unsigned) int/nombre entier: 4 octets, -2 147 483 648 à +2 147 483 647/0 à 4 294 967 295 (non signé) bigint: 8 octets, -9,223,372,036,854,775,808 à 9,223,372,036,854,775,807/0 à 18,446,744,073,709,551,615 (non signé) 'code' –

+1

Ensuite, vous convertissez le bigint en un b non signé igint. Quand c'est plein, vous avez probablement mis le record d'avoir le plus de données dans une base de données MySQL. En supposant que vous ne plaisantez pas avec la colonne auto_increment et laissez simplement faire son travail. Ce que je veux dire, c'est que vous n'avez pas à vous en préoccuper. Avez-vous regardé à quel point la plus grande valeur de bigint est énorme? Je dirais que 90% de tous les utilisateurs de la base de données n'atteignent jamais la limite supérieure d'un entier 32 bits dans une colonne auto_increment. Et vous parlez d'une valeur de 64 bits. – fancyPants

+0

Votre système sera au coucher du soleil avant d'atteindre ce nombre. – Juan

Répondre

2

Supposons une structure de table comme:

CREATE TABLE `tbl` (
    `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT, 
    PRIMARY KEY (`id`) 
); 

et INSERT des requêtes telles que:

INSERT INTO tbl(id) VALUES (NULL); 

Dans le code réel, il y a aussi d'autres colonnes dans la table et ils sont également présents dans la requête INSERT mais nous pouvons les ignorer en toute sécurité car ils n'apportent aucune valeur à ce problème spécifique.

Lorsque la valeur de la colonne id atteint sa valeur maximale, plus de lignes peuvent être insérées dans la table en utilisant la requête ci-dessus. La prochaine INSERT échoue avec l'erreur:

SQL Error (167): Out of range value for column 'id'.

S'il y a des lacunes dans les valeurs de la colonne id alors vous pouvez toujours insérer des lignes qui utilisent les valeurs ne sont pas présentes dans le tableau, mais vous devez spécifier les valeurs pour id dans la requête INSERT.


Quoi qu'il en soit, si le type de votre colonne est AUTO_INCREMENTBIGINT vous ne devez pas vous inquiéter.

En supposant que le code insère un million d'enregistrements chaque seconde (ce qui est très surfait, pour ne pas dire impossible), il y a suffisamment de valeurs pour la colonne id pour la prochaine half of million years. Ou juste 292,277 ans si la colonne n'est pas UNSIGNED.


J'ai été témoin du comportement sur un serveur web, qui utilisait INT(11) (et non UNSIGNED) comme ed PK AUTO_INCREMENT pour une table qui enregistre des informations sur les visites du site Web. Il a échoué au milieu de la nuit, après plusieurs années de fonctionnement en douceur, lorsque le nombre de visites atteint 2^31 (2 milliards et quelque chose). Le changement du type de colonne de INT à BIGINT n'est pas une solution sur une table de 2 milliards d'enregistrements (cela prend des âges à compléter et quand le système est actif, il n'y a jamais assez de temps).La solution a été de créer une nouvelle table avec la même structure mais avec BIGINT pour la colonne de PK et une valeur initiale de la colonne AUTO_INCREMENT et ensuite commuter les tables:

CREATE TABLE `tbl_new` (
    `id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, 
    PRIMARY KEY (`id`) 
) AUTO_INCREMENT=2200000000; 

RENAME TABLE `tbl` TO `tbl_old`, `tbl_new` TO `tbl`; 
+0

merci pour cette excellente réponse! :) – Sharpy35

1
tinyint: 1 byte, -128 to +127/0 to 255 (unsigned) 
smallint: 2 bytes, -32,768 to +32,767/0 to 65,535 (unsigned) 
mediumint: 3 bytes, -8,388,608 to 8,388,607/0 to 16,777,215 (unsigned) 
int/integer: 4 bytes, -2,147,483,648 to +2,147,483,647/0 to 4,294,967,295 (unsigned) 
bigint: 8 bytes, -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807/0 to 18,446,744,073,709,551,615 (unsigned) 

Pensez-vous que ce numéro est un petit nombre? peut-être vous serez mort avant d'atteindre ce nombre