Mysql
 sql >> Database >  >> RDS >> Mysql

autoincremento ciclico per ogni valore chiave

MyISAM supporta questo comportamento. Crea una chiave primaria a due colonne e crea la seconda auto-incremento della colonna. Ricomincerà da capo per ogni valore distinto nella prima colonna.

CREATE TABLE t (i INT, j INT AUTO_INCREMENT, PRIMARY KEY (i,j)) ENGINE=MyISAM;
INSERT INTO t (i) VALUES (1), (1), (2), (2), (1), (3);
SELECT * FROM t; 

+---+---+
| i | j |
+---+---+
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
| 2 | 1 |
| 2 | 2 |
| 3 | 1 |
+---+---+

Ma se ci pensi, questo è thread-safe solo in un motore di archiviazione che esegue il blocco a livello di tabella per le istruzioni INSERT. Perché INSERT deve cercare altre righe nella tabella per trovare il massimo j valore per lo stesso i valore. Se altre persone eseguono INSERT contemporaneamente, si crea una race condition.

Quindi, la dipendenza da MyISAM, che esegue il blocco a livello di tabella su INSERT.

Vedere questo riferimento nel manuale:http:// dev.mysql.com/doc/refman/5.6/en/example-auto-increment.html nella sezione MyISAM Notes .

Ci sono molte buone ragioni per non usare MyISAM. Il fattore decisivo per me è la tendenza di MyISAM a corrompere i dati.

Re il tuo commento:

InnoDB non supporta il comportamento di incremento per gruppo descritto sopra. Puoi creare una chiave primaria a più colonne, ma l'errore che hai ottenuto è perché InnoDB richiede che la colonna di incremento automatico sia la prima colonna in una chiave della tabella (non deve essere strettamente la chiave primaria)

Indipendentemente dalla posizione della colonna di incremento automatico nella chiave a più colonne, viene incrementata solo quando la si utilizza con InnoDB; non numera le voci per valore distinto in un'altra colonna.

Per fare ciò con una tabella InnoDB, dovresti bloccare la tabella in modo esplicito per la durata di INSERT, per evitare condizioni di gara. Faresti la tua query SELECT per il valore massimo nel gruppo in cui stai inserendo. Quindi inserisci quel valore + 1.

Fondamentalmente, devi ignorare la funzione di incremento automatico e specificare i valori invece di averli generati automaticamente.