PostgreSQL può essere configurato in questo modo con un CREATE SEQUENCE seq_name
e utilizzando nextval(seq_name)
su ogni inserto.
MySQL non ha il supporto nativo per questo, è possibile simulare il comportamento di un SEQUENCE di PostgreSQL creando una tabella con una sola colonna e uno AUTO_INCREMENT
su quella colonna.
Inserire sempre in quella tabella per prima cosa leggere lo LAST_INSERT_ID
di quella tabella per ottenere l'ID che è necessario inserire nella tabella. Sarebbe sicuro per le transazioni, quindi non sarebbero mai generati duplicati.
Un altro modo per ottenere ciò è creare una tabella con una colonna n. AUTO_INCREMENT
e una sola riga contenente il valore massimo corrente.
Ogni volta che è necessario incrementare si esegue UPDATE seq_table SET seq_column = seq_colum+1;
un aggiornamento incrementale è di per sé atomico ma è necessario leggere anche il valore successivo che rende due dichiarazioni e non sono atomici insieme a meno che non si imposti una transazione intorno a loro e un isolamento appropriato livello. Questo approccio consente di risparmiare spazio, ma genera anche query di blocco.
Più thread che provano a INSERT
dovranno attendere che altri aggiornino il seq_table
prima di poter aggiornare autonomamente e leggere il nuovo valore.
anche che avrebbe dovuto avvolgere la UPDATE
e il SELECT
su seq_table
in una transazione con un appropriato ISOLATION LEVEL
per evitare di leggere il valore che qualche altro thread incrementato dopo aver incrementato esso.
Ciò significa che INSERTS
diventa un problema di transazione ma normalmente non lo sono, quindi non consiglierei il secondo approccio.
fonte
2012-07-04 10:35:12
Se si desidera garantire l'univocità, è possibile utilizzare la funzione ['UUID_SHORT()'] (http://dev.mysql.com/doc/en/miscellaneous-functions.html#function_uuid-short) di MySQL. – eggyal
MySQL non ha sequenze (come la maggior parte degli altri DBMS). Devi rollare la tua soluzione. –
Non conosco un modo nativo. Ma forse potresti scrivere un trigger di inserimento che cerca tutte le tabelle per l'indice più alto e restituisce quel valore. Almeno in teoria, onestamente non sono sicuro che ciò sia possibile in MySQL. – acme