web-dev-qa-db-fra.com

Comment utiliser 2 colonnes d'incrémentation automatique dans MySQL phpmyadmin

Est-il possible d'utiliser 2 valeurs d'incrémentation automatique?

  • Un à partir de 0
  • Un autre à partir de 4000400

Aidez-moi, s'il vous plaît

6
user2106221

Non, tu ne peux pas. Pas hors de la boîte. Solutions de contournement possibles:

  1. Déclencheurs (an AFTER INSERT déclencheur).

    Désavantages:

    • Horreur pure et simple. Livré avec tous les autres inconvénients des déclencheurs, comme les cauchemars de maintenance et de débogage.

    Avantages:

    • Vous pouvez avoir FOREIGN KEY contraintes qui référencent cette colonne.
    • Vous pouvez mettre à jour la première et la deuxième colonnes id individuellement.
  2. Vues. Si vous avez seulement une valeur qui est toujours +4000400 de la première valeur incrémentée automatiquement, vous pouvez utiliser une vue, donc ne stockez pas du tout cette valeur, calculez-la simplement quand vous en avez besoin:

        CREATE VIEW 
            tablex_with_2nd_AI AS
        SELECT 
            tablex_id,
            colA,                                 -- other columns
            --                                    -- you need
            tablex_ix + 4000400  AS second_id
        FROM 
            tablex ;
    

    Désavantages:

    • Vous ne pouvez pas avoir un FOREIGN KEY contrainte qui fait référence à cette colonne (virtuelle).

    Avantages:

    • Économise de l'espace. Inserts légèrement plus rapides.
  3. Ne faites pas ça, n'ont pas du tout de deuxième colonne incrémentée automatiquement. Avez-vous vraiment besoin d'une deuxième valeur incrémentée automatiquement? Pourquoi? Une description du problème réel que vous essayez de résoudre aiderait les autres à mieux vous aider. Je pense que vous venez de dire ici comment vous avez essayé de résoudre un problème et non quel est le problème réel.

6
ypercubeᵀᴹ

J'ai de bonnes et de mauvaises nouvelles

BONNES NOUVELLES

Vous pouvez plusieurs valeurs auto_increment

MAUVAISES NOUVELLES

Deux choses:

  1. Il est uniquement disponible pour le moteur de stockage MyISAM
  2. Une seule valeur numérique auto_increment est autorisée. Chaque auto_increment doit avoir une colonne associée pour définir l'unicité des autres valeurs auto_increment dans la même table.

J'en ai déjà discuté

Voici un exemple de tableau

USE test
DROP TABLE IF EXISTS stores;
CREATE TABLE stores
(
    store_type int not null,
    id int not null auto_increment,
    store_name varchar(128) not null,
    PRIMARY KEY (store_type,id)
) ENGINE=MyISAM;

Voici des exemples de données

INSERT INTO stores (store_type,store_name) VALUES
(1,'Red Lobster'),(1,'Olive Garden'),
(2,'ShopRite'),(2,'PathMark'),(2,'Wegman''s'),
(3,'McDonald''s'),(3,'Wendy''s'),(3,'Burger King'),
(1,'Ruby Tuesdays'),(1,'TGI Fridays'),
(4,'BJs'),(4,'Costco'),(1,'Bennigan''s');

Chargeons-le

mysql> USE test
Database changed
mysql> DROP TABLE IF EXISTS stores;
Query OK, 0 rows affected (0.00 sec)

mysql> CREATE TABLE stores
    -> (
    ->     store_type int not null,
    ->     id int not null auto_increment,
    ->     store_name varchar(128) not null,
    ->     PRIMARY KEY (store_type,id)
    -> ) ENGINE=MyISAM;
Query OK, 0 rows affected (0.08 sec)

mysql> INSERT INTO stores (store_type,store_name) VALUES
    -> (1,'Red Lobster'),(1,'Olive Garden'),
    -> (2,'ShopRite'),(2,'PathMark'),(2,'Wegman''s'),
    -> (3,'McDonald''s'),(3,'Wendy''s'),(3,'Burger King'),
    -> (1,'Ruby Tuesdays'),(1,'TGI Fridays'),
    -> (4,'BJs'),(4,'Costco'),(1,'Bennigan''s');
Query OK, 13 rows affected (0.00 sec)
Records: 13  Duplicates: 0  Warnings: 0

mysql>

Maintenant, regardez les données:

mysql> SELECT * FROM stores;
+------------+----+---------------+
| store_type | id | store_name    |
+------------+----+---------------+
|          1 |  1 | Red Lobster   |
|          1 |  2 | Olive Garden  |
|          2 |  1 | ShopRite      |
|          2 |  2 | PathMark      |
|          2 |  3 | Wegman's      |
|          3 |  1 | McDonald's    |
|          3 |  2 | Wendy's       |
|          3 |  3 | Burger King   |
|          1 |  3 | Ruby Tuesdays |
|          1 |  4 | TGI Fridays   |
|          4 |  1 | BJs           |
|          4 |  2 | Costco        |
|          1 |  5 | Bennigan's    |
+------------+----+---------------+
13 rows in set (0.00 sec)

mysql>

Maintenant, regardez les données ordonnées par les colonnes PRIMARY KEY

mysql> SELECT * FROM stores ORDER BY store_type,id;
+------------+----+---------------+
| store_type | id | store_name    |
+------------+----+---------------+
|          1 |  1 | Red Lobster   |
|          1 |  2 | Olive Garden  |
|          1 |  3 | Ruby Tuesdays |
|          1 |  4 | TGI Fridays   |
|          1 |  5 | Bennigan's    |
|          2 |  1 | ShopRite      |
|          2 |  2 | PathMark      |
|          2 |  3 | Wegman's      |
|          3 |  1 | McDonald's    |
|          3 |  2 | Wendy's       |
|          3 |  3 | Burger King   |
|          4 |  1 | BJs           |
|          4 |  2 | Costco        |
+------------+----+---------------+
13 rows in set (0.00 sec)

mysql>

Essaie !!!

MISE À JOUR 2013-02-26 12:00 EST

Augmentons les SuperMarkets (store_type 2) en ajoutant 4000400 aux valeurs id

mysql> UPDATE stores SET id = id + 4000400 WHERE store_type = 2;
Query OK, 3 rows affected (0.02 sec)
Rows matched: 3  Changed: 3  Warnings: 0

mysql> SELECT * FROM stores ORDER BY store_type,id;
+------------+---------+---------------+
| store_type | id      | store_name    |
+------------+---------+---------------+
|          1 |       1 | Red Lobster   |
|          1 |       2 | Olive Garden  |
|          1 |       3 | Ruby Tuesdays |
|          1 |       4 | TGI Fridays   |
|          1 |       5 | Bennigan's    |
|          2 | 4000401 | ShopRite      |
|          2 | 4000402 | PathMark      |
|          2 | 4000403 | Wegman's      |
|          3 |       1 | McDonald's    |
|          3 |       2 | Wendy's       |
|          3 |       3 | Burger King   |
|          4 |       1 | BJs           |
|          4 |       2 | Costco        |
+------------+---------+---------------+
13 rows in set (0.00 sec)

mysql>

Ajoutons A & P comme un autre SuperMarket

mysql> INSERT INTO stores (store_type,store_name) VALUES (2,'A & P');
Query OK, 1 row affected (0.00 sec)

mysql> SELECT * FROM stores ORDER BY store_type,id;
+------------+---------+---------------+
| store_type | id      | store_name    |
+------------+---------+---------------+
|          1 |       1 | Red Lobster   |
|          1 |       2 | Olive Garden  |
|          1 |       3 | Ruby Tuesdays |
|          1 |       4 | TGI Fridays   |
|          1 |       5 | Bennigan's    |
|          2 | 4000401 | ShopRite      |
|          2 | 4000402 | PathMark      |
|          2 | 4000403 | Wegman's      |
|          2 | 4000404 | A & P         |
|          3 |       1 | McDonald's    |
|          3 |       2 | Wendy's       |
|          3 |       3 | Burger King   |
|          4 |       1 | BJs           |
|          4 |       2 | Costco        |
+------------+---------+---------------+
14 rows in set (0.00 sec)

mysql>

On dirait que cela peut fonctionner pour vous !!!

3
RolandoMySQLDBA

Je viens de rencontrer ce problème et j'aimerais contribuer aux réponses. J'ai utilisé la réponse d'Ypercube pour le résoudre, mais d'une manière légèrement différente. Mais d'abord,

Pourquoi avez-vous besoin de la deuxième colonne d'incrémentation automatique en plus de l'ID?

Il y a quelques objets, dont la quantité peut être des informations d'entreprise assez sensibles. Par exemple, je ne veux peut-être pas user_id 37 pour suggérer que je n'ai que 37 utilisateurs sur mon site Web. Nombre de réclamations, nombre d'achats, nombre de choses bonnes ou mauvaises que vous ne voulez pas que les utilisateurs, les concurrents ou les régulateurs connaissent.

Pourtant, il est utile, au moins dans mon cas, d'attribuer un numéro unique accessible au public à ces objets afin que je puisse les gérer plus facilement avec la saisie de l'utilisateur. Par exemple, cette question sur SE a un numéro 35449 et je peux l'obtenir en tapant ce numéro dans le navigateur: https://dba.stackexchange.com/questions/35449

Et enfin, je ne veux pas créer de surcharge complexe en essayant d'obscurcir les identifiants. L'incrémentation automatique d'un nombre supérieur à ID fera l'affaire.

Voilà donc le problème. La réponse d'Ypercube a une solution assez cool, ajoutez simplement une constante à l'id. Seulement je l'ai fait en PHP dans mon cas avec une requête supplémentaire et je l'ai mis dans une fonction séparée afin que je puisse facilement en garder la trace et qu'il ne soit pas étroitement couplé avec le reste de SQL C'est plus lent mais plus facile à gérer quant à moi.

Notez que si vous essayez de réduire la quantité apparente de quelque chose de négatif, comme complaint_id ou refund_id, ne soustrayez pas car vous pouvez entrer en négatif, ajoutez simplement un énorme nombre aléatoire, en milliards + sans zéros consécutifs (par exemple id + 159035466234) qui montrera clairement que cela n'a rien à voir avec la quantité de ces objets.

0
Arthur Tarasov

Jetez un œil à l'onglet déclencheurs - vous devriez pouvoir créer un déclencheur pour mettre à jour une deuxième colonne d'incrémentation automatique basée sur une insertion.

    CREATE TABLE IF NOT EXISTS test2 (
    id          int(11) NOT NULL AUTO_INCREMENT,
    another_id      int(11) ,
    blah        varchar(250),
    PRIMARY KEY (`id`)  
)   ENGINE=MyISAM  DEFAULT CHARSET=latin1 ; 

Le déclencheur doit incrémenter la colonne 'another_id' (que vous définissez sur 40004000) lorsqu'une ligne est insérée dans le tableau

0
acutesoftware