I am trying to write a tag system which I want allow users to insert multiple tag in a text input. And then I want insert each tag in tag_table and need their id for keep in tag_post_table.
I know that in multiple insert last_insert_id return the first record id. Co can I add count of tags to last_insert_id for getting the real last id and use every id between them? Is this reliable?
I read this article, but I don't understand it completely
http://dev.mysql.com/doc/refman/5.1/en/innodb-auto-increment-handling.html
As I understand this article:
With innodb_autoinc_lock_mode set to 0 (“traditional”) or 1 (“consecutive”), the auto-increment values generated by any given statement will be consecutive, without gaps, because the table-level AUTO-INC lock is held until the end of the statement, and only one such statement can execute at a time.
Setting innodb_autoinc_lock_mode to 0 or 1 guarantees that the auto incemented ids are consecutive.
So the ID you get from LAST_INSERT_ID is the first of the new IDs and LAST_INSERT_ID + "the number of affected rows" is the last of the new IDs.
Also LAST_INSTERT_ID is not affected by other connections
The ID that was generated is maintained in the server on a per-connection basis. This means that the value returned by the function to a given client is the first AUTO_INCREMENT value generated for most recent statement affecting an AUTO_INCREMENT column by that client. This value cannot be affected by other clients, even if they generate AUTO_INCREMENT values of their own. This behavior ensures that each client can retrieve its own ID without concern for the activity of other clients, and without the need for locks or transactions.
But notice, that there may be wrong results, if you use INSERT ... ON DUPLICATE KEY UPDATE or INSERT IGNORE .... But I have not tested this.
Related
According to the PHP documentation, mysql_insert_id takes the last inserted id from the mysql table.
My question is, if I have a website that inserts more than 2 rows per second to the DB, can I use the mysql_insert_id and get the correct ID I am referring to in the INSERT query a line before?
From the MySQL manual:
The ID that was generated is maintained in the server on a per-connection basis. This means that the value returned by the function to a given client is the first AUTO_INCREMENT value generated for most recent statement affecting an AUTO_INCREMENT column by that client. This value cannot be affected by other clients, even if they generate AUTO_INCREMENT values of their own. This behavior ensures that each client can retrieve its own ID without concern for the activity of other clients, and without the need for locks or transactions.
Short version: it is safe to use.
mysql_insert_id gives you the insert id of the most recent INSERT statement on the connection you give it.
If you call this immediatly after your insert, on the same mysql connection, you get the inserted id matching that insert statement, independantly of any other inserts going on in the mean time.
I'm using mysql_insert_id() to fetch the last inserted id. I have a confusion about which id it gives when inserting values concurrently by multiple users at the same instance. Does it gives the one that I have inserted or does it compare the last query within same instance?
The short answer to your question is: the last one you inserted.
Here's why.
The php functions that retrieve the last inserted ids are wrappers around the mysql library function mysql_insert_id(). The server tracks the most recently generated AUTO_INCREMENT value on a per connection basis, and is not affected by another connection generating an AUTO_INCREMENT value.
20.6.14.3 How to Get the Unique ID for the Last Inserted Row
For LAST_INSERT_ID(), the most recently generated ID is maintained in
the server on a per-connection basis. It is not changed by another
client. It is not even changed if you update another AUTO_INCREMENT
column with a nonmagic value (that is, a value that is not NULL and
not 0). Using LAST_INSERT_ID() and AUTO_INCREMENT columns
simultaneously from multiple clients is perfectly valid. Each client
will receive the last inserted ID for the last statement that client
executed.
I need to return the value from my auto incremented column of the update that's just happened.
Basically I am updating a user with XYZ values:
$stmt->execute();
I need to get the new records value from ID column in the database which is auto incremented.
PDO lastInsertId(); just returns the latest record and could be potentially dangerous on a high traffic site?
I hope you are using MySql??
From mysql site:
The ID that was generated is maintained in the server on a per-connection basis. This means that the value returned by the function to a given client is the first AUTO_INCREMENT value generated for most recent statement affecting an AUTO_INCREMENT column by that client. This value cannot be affected by other clients, even if they generate AUTO_INCREMENT values of their own. This behavior ensures that each client can retrieve its own ID without concern for the activity of other clients, and without the need for locks or transactions.
Further:
If you insert multiple rows using a single INSERT statement, LAST_INSERT_ID() returns the value generated for the first inserted row only.
So it's save to use because it works on connection basis. And if you insert multiple rows you can combine it with PDO's rowCount method to get all inserted id's.
In my application, I have a lot of foreign key dependencies, and often insert large numbers of rows. What I have done up until now is run a single insert at a time, and record the insert ID. This tends to take a long time when inserting a large number of rows, even when apache and mysql are run on the same server.
My question is, if I were to alter my application to add a number of rows with a single INSERT, would I be able to assume the ids of each row based strictly upon the last insert id returned by the mysql connection? The issue is that there is the occasional situation where more than one person will be putting large amounts of information into the database at a time.
From what I have been able to determine, it seems safe to assume that when you insert 500 rows, your insert ids will range from (lastInsertID) to (lastInsertID+499), regardless of whether a query from another connection has begun or ended in the time it took to complete, but I want to be sure this is accepted as safe practice.
I am primarily running InnoDB, but there is the occasional MyISAM in there as well.
Thanks All!
-Jer
The mysql_insert_id and the now recommended alternative mysqli_insert_id returns the first entry id from the affected table's AUTO_INCREMENT column of the last query you've ran.
Mysql grouped INSERT statements are inserted iteratively from the first entry AUTO_INCREMENT index. So yes it is safe to assume that the entries inserted from a single INSERT statement are contiguous.
Comment from the Mysql reference "The ID that was generated is maintained in the server on a per-connection basis. This means that the value returned by the function to a given client is the first AUTO_INCREMENT value generated for most recent statement affecting an AUTO_INCREMENT column by that client. This value cannot be affected by other clients, even if they generate AUTO_INCREMENT values of their own. This behavior ensures that each client can retrieve its own ID without concern for the activity of other clients, and without the need for locks or transactions.
I am using adodb for PHP library.
For fetching the id at which the record is inserted I use this function "$db->Insert_ID()"
I want to know if there are multiple and simultaneous inserts into the database table, will this method return me the correct inserted id for each record inserted ?
The reason I am asking this is because I use this last insert id for further processing of other records and making subsequent entries in the related tables.
Is this approach safe enough or am I missing something.
Please help me formulate a proper working plan for this so that I can use the last insert id for further inserts into the other table safely without having to mess up with the existing data.
Thanks
Yes, it's safe for concurent use. That's because LAST_INSERT_ID() is per-connection, as explained here:
The ID that was generated is
maintained in the server on a
per-connection basis. This means that
the value returned by the function to
a given client is the first
AUTO_INCREMENT value generated for
most recent statement affecting an
AUTO_INCREMENT column by that client.
This value cannot be affected by other
clients, even if they generate
AUTO_INCREMENT values of their own.
This behavior ensures that each client
can retrieve its own ID without
concern for the activity of other
clients, and without the need for
locks or transactions.
The $db->Insert_ID() will return you last insert id only so if you are inserting many records and want to get id of each last inserted row, then this will work successfully.
I want to know if there are multiple and simultaneous inserts into the database table, will this method return me the correct inserted id for each record inserted ?
It will return only the most recently inserted id.
In order to get ids for multiple inserts, you will have to call INSERT_ID() after each statement is executed. IE:
INSERT INTO TABLE ....
INSERT_ID()
INSERT INTO TABLE ....
INSERT_ID()
...to get the id value for each insert. If you ran:
INSERT INTO TABLE ....
INSERT INTO TABLE ....
INSERT_ID()
...will only return the id for the last insert statement.
Is this approach safe enough or am I missing something.
It's safer than using SELECT MAX(id) FROM TABLE, which risks returning a value inserted by someone else among other things relating to isolation levels.