web-dev-qa-db-fra.com

Que se passe-t-il lorsque auto_increment sur une colonne entière atteint la valeur max_value dans les bases de données?

J'implémente une application de base de données et j'utiliserai JavaDB et MySQL comme base de données. J'ai une colonne ID dans mes tables qui a un entier comme type et j'utilise la fonction auto_increment-bases de données pour la valeur.

Mais que se passe-t-il lorsque j'obtiens plus de 2 (ou 4) milliards de messages et que l'entier ne suffit pas? L'entier a-t-il débordé et continue-t-il ou une exception est-elle levée que je peux gérer?

Oui, je pourrais changer aussi longtemps que le type de données, mais comment puis-je vérifier quand cela est nécessaire? Et je pense qu'il y a un problème à obtenir les fonctions last_inserred_id () - si j'utilise un type de données long pour la colonne ID.

63
Jonas

Commentaire de Jim Martin de §3.6.9. "Using AUTO_INCREMENT" de la documentation MySQL:

Juste au cas où il y aurait une question, le champ AUTO_INCREMENT/NE REMPLACE PAS /. Une fois que vous avez atteint la limite de la taille du champ, les INSERT génèrent une erreur. (Selon Jeremy Cole)

Un test rapide avec MySQL 5.1.45 entraîne une erreur de:

ERREUR 1467 (HY000): impossible de lire la valeur d'incrémentation automatique du moteur de stockage

Vous pouvez tester cette erreur lors de l'insertion et prendre les mesures appropriées.

45
outis

Juste pour calmer les nerfs, considérez ceci:

Supposons que vous ayez une base de données qui insère une nouvelle valeur pour chaque fois qu'un utilisateur exécute une sorte de transaction sur votre site Web.

Avec un entier 64 bits comme ID, c'est la condition du débordement: avec une population mondiale de 6 milliards, si chaque être humain exécute une transaction une fois par seconde chaque jour et chaque année (sans repos), cela prendrait plus de 80 ans pour que votre carte d'identité se termine.

C'est-à-dire que seul Google a besoin de considérer vaguement ce problème de temps en temps pendant une pause-café.

48
Justin

Vous saurez quand il va déborder en regardant le plus grand ID. Vous devez le changer bien avant qu'une exception ne soit sur le point d'être levée.

En fait, vous devez commencer par concevoir avec un type de données suffisamment grand. Les performances de votre base de données ne seront pas affectées même si vous utilisez un ID 64 bits depuis le début.

9
Matti Virkkunen

Les réponses ici indiquent ce qui se passe, mais une seule réponse indique comment détecter le problème (et seulement après que l'erreur s'est produite). Généralement, il est utile de pouvoir détecter ces choses avant qu'elles ne deviennent un problème de production, j'ai donc écrit une requête pour détecter quand un débordement est sur le point de se produire:

SELECT
  c.TABLE_CATALOG,
  c.TABLE_SCHEMA,
  c.TABLE_NAME,
  c.COLUMN_NAME
FROM information_schema.COLUMNS AS c
JOIN information_schema.TABLES AS t USING (TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME)
WHERE c.EXTRA LIKE '%auto_increment%'
  AND t.AUTO_INCREMENT / CASE c.DATA_TYPE
      WHEN 'TINYINT' THEN IF(c.COLUMN_TYPE LIKE '% UNSIGNED', 255, 127)
      WHEN 'SMALLINT' THEN IF(c.COLUMN_TYPE LIKE '% UNSIGNED', 65535, 32767)
      WHEN 'MEDIUMINT' THEN IF(c.COLUMN_TYPE LIKE '% UNSIGNED', 16777215, 8388607)
      WHEN 'INT' THEN IF(c.COLUMN_TYPE LIKE '% UNSIGNED', 4294967295, 2147483647)
      WHEN 'BIGINT' THEN IF(c.COLUMN_TYPE LIKE '% UNSIGNED', '18446744073709551615', 9223372036854775807) # need to quote because column type defaults to unsigned.
      ELSE 0
    END > .9; # 10% buffer

J'espère que cela aide quelqu'un quelque part.

6
CSTobey

Pour MySQL 5.6, .6.9 en utilisant AUTO_INCREMENT in dit:

Utilisez le plus petit type de données entier pour la colonne AUTO_INCREMENT qui est suffisamment grand pour contenir la valeur de séquence maximale dont vous aurez besoin. Lorsque la colonne atteint la limite supérieure du type de données, la prochaine tentative de génération d'un numéro de séquence échoue.

0
Jingguo Yao