Detailed explanation of mysql's auto_increment

  • Basic properties of auto_increment

 

The AUTO_INCREMENT type attribute in MySQL is used to automatically generate an ID function for records in a table, which can replace the sequence in Oracle, PostgreSQL and other databases to a certain extent.

In database applications, we often use unique numbers to identify records. In MySQL, it can be automatically generated by the AUTO_INCREMENT attribute of the data column.

You can use the "AUTO_INCREMENT=n" option to specify an auto-increment initial value when creating a table.
Use the alter table table_name AUTO_INCREMENT=n command to reset the auto-increment start value.

When inserting a record, if a value is explicitly specified for the AUTO_INCREMENT data column, two situations will occur. In the
first case, if the inserted value is duplicated with the existing number, an error message will appear, because the value of the AUTO_INCREMENT data column must be is unique;
in case two, if the inserted value is greater than the numbered value, it will be inserted into the data column, and the next number will be incremented from this new value. That is, some numbers can be skipped.
If the maximum value of the auto-incrementing sequence is removed, that value is reused when inserting new records.
If you use the UPDATE command to update an auto-incrementing column, an error will occur if the column value duplicates the existing value. If it is greater than the existing value, the next number is incremented from this value.

When using AUTO_INCREMENT, you should pay attention to the following points:
AUTO_INCREMENT is an attribute of a data column and is only applicable to integer type data columns.
The data column for which the AUTO_INCREMENT attribute is set should be a positive sequence, so the data column should be declared as UNSIGNED, so that the number of sequences can be doubled.
AUTO_INCREMENT data columns must have a unique index to avoid sequence number duplication (ie, primary key or part of the primary key).
AUTO_INCREMENT data columns must have the NOT NULL attribute.
The maximum value of the serial number of the AUTO_INCREMENT data column is constrained by the data type of the column. For example, the maximum number of the TINYINT data column is 127, and if UNSIGNED is added, the maximum is 255. Once the upper limit is reached, AUTO_INCREMENT will fail.
When performing a full table delete, MySQL AUTO_INCREMENT will start numbering again from 1. Full table delete means when the following two statements are issued:

 

[php]  view plain copy  
 
  1. delete from table_name;  
  2. or  
  3. truncate table table_name   

This is because when performing a full table operation, MySQL (the best combination with PHP) actually does such an optimization operation: first delete all data and indexes in the data table, and then rebuild the data table.
If you want to delete all data rows but want to keep the sequence number information, you can use a delete command with where to suppress the optimization of MySQL (the best combination with PHP):

 

[php]  view plain copy  
 
  1. delete from table_name where 1;   


Use last_insert_id() to get the value just incremented.

 

  • About the lock table operation brought by mysql auto_increment

在mysql5.1.22之前,mysql的“INSERT-like”语句(包INSERT, INSERT…SELECT, REPLACE,REPLACE…SELECT, and LOAD DATA)会在执行整个语句的过程中使用一个AUTO-INC锁将表锁住,直到整个语句结束(而不是事务结束)。
因此在使用INSERT…SELECT、INSERT…values(…),values(…)时,LOAD DATA等耗费时间较长的操作时,会将整个表锁住,而阻塞其他的“INSERT-like”、Update等语句,推荐使用程序将这些语句分成多条语句,一一插入,减少单一时间的锁表时间。
mysql5.1.22之后mysql进行了改进,引入了参数 innodb_autoinc_lock_mode,通过这个参数控制mysql的锁表逻辑。
在介绍这个之前先引入几个术语,方便说明 innodb_autoinc_lock_mode。
1.“INSERT-like”:
INSERT, INSERT … SELECT, REPLACE, REPLACE … SELECT, and LOAD DATA, INSERT … VALUES(),VALUES()
2.“Simple inserts”:
就是通过分析insert语句可以确定插入数量的insert语句, INSERT, INSERT … VALUES(),VALUES()
3.“Bulk inserts”:
就是通过分析insert语句不能确定插入数量的insert语句, INSERT … SELECT, REPLACE … SELECT, LOAD DATA
4.“Mixed-mode inserts”:
不确定是否需要分配auto_increment id,一般是下面两种情况
INSERT INTO t1 (c1,c2) VALUES (1,’a'), (NULL,’b'), (5,’c'), (NULL,’d');
INSERT … ON DUPLICATE KEY UPDATE

一、innodb_autoinc_lock_mode = 0 (“traditional” lock mod,传统模式)。
这种方式就和mysql5.1.22以前一样,为了向后兼容而保留了这种模式,如同前面介绍的一样,这种方式的特点就是“表级锁定”,并发性较差。
二、innodb_autoinc_lock_mode = 1 (“consecutive” lock mode,连续模式)。
这种方式是新版本中的默认方式,推荐使用,并发性相对较高,特点是“consecutive”,即保证同一条insert语句中新插入的auto_increment id都是连续的。
这种模式下:
“Simple inserts”:直接通过分析语句,获得要插入的数量,然后一次性分配足够的auto_increment id,只会将整个分配的过程锁住。
“Bulk inserts”:因为不能确定插入的数量,因此使用和以前的模式相同的表级锁定。
“Mixed-mode inserts”:直接分析语句,获得最坏情况下需要插入的数量,然后一次性分配足够的auto_increment id,只会将整个分配的过程锁住。
需要注意的是,这种方式下,会分配过多的id,而导致浪费
比如INSERT INTO t1 (c1,c2) VALUES (1,’a'), (NULL,’b'), (5,’c'), (NULL,’d');会一次性的分配5个id,而不管用户是否指定了部分id;
INSERT … ON DUPLICATE KEY UPDATE一次性分配,而不管将来插入过程中是否会因为duplicate key而仅仅执行update操作。
注意:当master mysql版本<5.1.22,slave mysql版本>=5.1.22时,slave需要将innodb_autoinc_lock_mode设置为0,因为默认的innodb_autoinc_lock_mode为1,对于INSERT … ON DUPLICATE KEY UPDATE和INSERT INTO t1 (c1,c2) VALUES (1,’a'), (NULL,’b'), (5,’c'), (NULL,’d');的执行结果不同,现实环境一般会使用INSERT … ON DUPLICATE KEY UPDATE。
三、innodb_autoinc_lock_mode = 2 (“interleaved” lock mode,交叉模式)。
这种模式是来一个分配一个,而不会锁表,只会锁住分配id的过程,和innodb_autoinc_lock_mode = 1的区别在于,不会预分配多个,这种方式并发性最高。
However, there is a problem in replication when binlog_format is statement-based (SBR statement-based replication for short), because one is allocated one, so when concurrent execution, "Bulk inserts" will be allocated to other INSERTs at the same time. , there will be master-slave inconsistency (the execution result of the slave library is different from the execution result of the master library), because binlog will only record the beginning of the insert id.
Test SBR, execute begin;insert values(),();insert values(),();commit; will add SET INSERT_ID=18/*!*/; before each insert values(),(); in binlog .
But there is no problem with row-based replication RBR.
In addition, the main disadvantage of RBR is that when the number of logs includes a large number of update deletes (multiple statements of update, multiple statements of delete), the log will be much larger than that of SBR; if there are not many such statements in the actual statement (in reality There are many such cases), it is recommended to use RBR with innodb_autoinc_lock_mode, but then again, there are very few "Bulk inserts" in real production, so innodb_autoinc_lock_mode = 1 should be enough.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326195647&siteId=291194637