2009-08-16 15 views
23

Quando si inseriscono dati in una tabella con un PK con incremento automatico, è necessario ottenere tale chiave per utilizzarla in un'altra istruzione. Come molte domande mostrano su SO questo può essere fatto in PHP usando mysql_insert_id().Recupero degli ultimi ID inseriti per più righe

Tuttavia, ho raggruppato insieme i miei inserti in modo da inserire più di una riga alla volta. Ho fatto questo perché immaginavo che ci sarebbe stato probabilmente qualche problema di prestazioni, ti prego di avvisare se ho torto. Ad ogni modo, per quanto ne so, lo mysql_insert_id() restituisce solo l'ultimo ID, quando ho bisogno degli ID per tutte le righe inserite.

Credo che in questo caso ho potuto:

  1. fare un po 'di matematica semplice per calcolare tutti gli ID utilizzando mysql_insert_id() e il numero di righe che ho inseriti. Ma è garantito che sia sempre corretto?

  2. utilizzare istruzioni inserire più, uno per ogni riga

  3. generare i miei ID prima e inutile incremento automatico.

Sono sicuro che questo deve essere un problema classico, quindi mi sto chiedendo quali sono gli approcci più comuni e consigliabili.

risposta

2

ci sono un paio di approcci che userei, se mi fossi:

primo luogo, c'è il campo CreateDate il valore predefinito è CURRENT_TIMESTAMP metodo. In pratica, si seleziona CURRENT_TIMESTAMP per ottenere la data, eseguire l'inserto e quindi select id from table where CreateDate > $mytimestamp.

In secondo luogo, è possibile creare un trigger sulla tabella per registrare after insert e inserire i nuovi ID in una piccola tabella di controllo. Tronca la tabella prima di controllare quegli ID, però. Vorrei utilizzare questo metodo se la tua tabella è milioni su milioni di righe.

+0

L'approccio 'CURRENT_TIMESTAMP' sembra un po 'pericoloso per me. Cosa succede se tu e qualcun altro scrivete allo stesso tavolo contemporaneamente (stesso timestamp)? – tonix

32

La chiamata last_insert_id() fornisce l'ID della prima riga inserita nell'ultimo batch. Tutti gli altri inseriti, sono garantiti per essere sequenziali.

A meno che non si stia facendo qualcosa di molto strano, questo consente di calulare l'ID di ogni riga abbastanza facilmente.

In realtà il comportamento varia in 5.1 a seconda dell'impostazione del parametro della modalità di incremento automatico di innodb; questo non dovrebbe importare. Finché non lo cambi da predefinito, vedrai il comportamento previsto.

Ci sono casi occasionali in cui ciò non fa ciò che ci si aspetta e non è utile, ad esempio se si esegue un AGGIORNAMENTO DELLA CHIAVE DUPLICATO o INSERISCI IGNORA. In questi casi, dovrai fare qualcos'altro per elaborare gli ID di ogni riga.

Ma per un semplice batch INSERIMENTO vaniglia, senza valori specificati per la colonna di autoincremento, è facile.

Una descrizione completa di come auto-increments are handled in innodb is here

+1

Ho pensato a InnoDB, perché la maggior parte delle applicazioni dovrebbe usare InnoDB, è il miglior motore per uso generale. – MarkR

+0

Per i motori con blocco a livello di tabella (memoria, myisam ecc.), L'auto-inc è banale, poiché non vi è alcuna concorrenza di cui preoccuparsi. – MarkR

+0

Questo è quello che ho pensato "fai un po 'di matematica". Il caos è sbagliato dicendo che non è garantito che sia sequenziale? o forse mi ha frainteso – zenna

Problemi correlati