`

mysql的auto_increment详解

 
阅读更多
  • auto_increment的基本特性

 

MySQL的中AUTO_INCREMENT类型的属性用于为一个表中记录自动生成ID功能,可在一定程度上代替Oracle,PostgreSQL等数据库中的sequence。

在数据库应用,我们经常要用到唯一编号,以标识记录。在MySQL中可通过数据列的AUTO_INCREMENT属性来自动生成。

可在建表时可用“AUTO_INCREMENT=n”选项来指定一个自增的初始值。
可用alter table table_name AUTO_INCREMENT=n命令来重设自增的起始值。

当插入记录时,如果为AUTO_INCREMENT数据列明确指定了一个数值,则会出现两种情况,
情况一,如果插入的值与已有的编号重复,则会出现出错信息,因为AUTO_INCREMENT数据列的值必须是唯一的;
情况二,如果插入的值大于已编号的值,则会把该插入到数据列中,并使在下一个编号将从这个新值开始递增。也就是说,可以跳过一些编号。
如果自增序列的最大值被删除了,则在插入新记录时,该值被重用。
如果用UPDATE命令更新自增列,如果列值与已有的值重复,则会出错。如果大于已有值,则下一个编号从该值开始递增。

在使用AUTO_INCREMENT时,应注意以下几点:
AUTO_INCREMENT是数据列的一种属性,只适用于整数类型数据列。
设置AUTO_INCREMENT属性的数据列应该是一个正数序列,所以应该把该数据列声明为UNSIGNED,这样序列的编号个可增加一倍。
AUTO_INCREMENT数据列必须有唯一索引,以避免序号重复(即是主键或者主键的一部分)。
AUTO_INCREMENT数据列必须具备NOT NULL属性。
AUTO_INCREMENT数据列序号的最大值受该列的数据类型约束,如TINYINT数据列的最大编号是127,如加上UNSIGNED,则最大为255。一旦达到上限,AUTO_INCREMENT就会失效。
当进行全表删除时,MySQL AUTO_INCREMENT会从1重新开始编号。全表删除的意思是发出以下两条语句时:

 

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

这是因为进行全表操作时,MySQL(和PHP搭配之最佳组合)实际是做了这样的优化操作:先把数据表里的所有数据和索引删除,然后重建数据表。
如果想删除所有的数据行又想保留序列编号信息,可这样用一个带where的delete命令以抑制MySQL(和PHP搭配之最佳组合)的优化:

 

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


可用last_insert_id()获取刚刚自增过的值。

 

  • 关于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的区别在于,不会预分配多个,这种方式并发性最高。
但是在replication中当binlog_format为statement-based时(简称SBR statement-based replication)存在问题,因为是来一个分配一个,这样当并发执行时,“Bulk inserts”在分配的时会同时向其他的INSERT分配,会出现主从不一致(从库执行结果和主库执行结果不一样),因为binlog只会记录开始的insert id。
测试SBR,执行begin;insert values(),();insert values(),();commit;会在binlog中每条insert values(),();前增加SET INSERT_ID=18/*!*/;。
但是row-based replication RBR时不会存在问题。
另外RBR的主要缺点是日志数量在包括语句中包含大量的update delete(update多条语句,delete多条语句)时,日志会比SBR大很多;假如实际语句中这样语句不是很多的时候(现实中存在很多这样的情况),推荐使用RBR配合innodb_autoinc_lock_mode,不过话说回来,现实生产中“Bulk inserts”本来就很少,因此innodb_autoinc_lock_mode = 1应该是够用了。

分享到:
评论

相关推荐

    MySQL AUTO_INCREMENT 主键

    ### MySQL AUTO_INCREMENT 主键详解 在数据库设计与应用中,主键是确保数据表每一行记录唯一性的关键机制之一。而`AUTO_INCREMENT`属性则是在MySQL数据库系统中为某些整数类型的主键自动分配唯一值的功能。下面我们...

    MySQL 序列 AUTO_INCREMENT详解及实例代码

    MySQL 序列 AUTO_INCREMENT详解及实例代码 MySQL序列是一组整数:1, 2, 3, …,由于一张数据表只能有一个字段自增主键, 如果你想实现其他字段也实现自动增加,就可以使用MySQL序列来实现。 本章我们将介绍如何使用...

    MYSQL_C_API详解.pdf

    - 字段属性包括`NOT_NULL_FLAG`、`PRI_KEY_FLAG`、`UNIQUE_KEY_FLAG`、`MULTIPLE_KEY_FLAG`、`UNSIGNED_FLAG`、`ZEROFILL_FLAG`、`BINARY_FLAG`、`AUTO_INCREMENT_FLAG`、`ENUM_FLAG`和`BLOB_FLAG`等,用于标识字段...

    identity:用于MySql数据库

    #### MySQL `auto_increment`详解 当创建一个新表时,如果希望某列作为主键并能够自动递增,可以在定义该列时指定`auto_increment`属性。例如: ```sql CREATE TABLE users ( id INT AUTO_INCREMENT PRIMARY KEY,...

    如何用php连接mysql实例详解_.docx

    ### 如何用PHP连接MySQL实例详解 #### 一、创建数据库和数据表 在开始学习如何使用PHP连接MySQL之前,我们需要先确保有一个可用的数据库和数据表。根据文档中的描述,我们将创建一个名为`txl`的数据库,并在这个...

    mysql 5.6 参数详解.docx

    1. `auto_increment_increment`: 这个变量定义了 AUTO_INCREMENT 列在每次自增时的增值,范围1到65535,默认值是1。例如,设置为2意味着每次生成的新序列值会增加2。 2. `auto_increment_offset`: 它设定了 AUTO_...

    mysql全局变量详解[收集].pdf

    当配置主主复制时,为了避免冲突,两台服务器的`auto_increment_offset`应分别设置为1和2,而`auto_increment_increment`应设置为2。 2. **auto_increment_increment**:它定义了自增长字段每次递增的量,默认是1,...

    mysql主主复制

    ### MySQL主主复制知识点详解 #### 一、MySQL主主复制概述 MySQL主主复制是一种高级复制模式,它允许两个MySQL服务器互相作为对方的主服务器和从服务器,实现双向的数据同步。这种架构不仅可以提高系统的可用性和...

    mysql 数据库双机热备

    ### MySQL 数据库双机热备实现详解 #### 一、双机热备概念与意义 在现代企业级应用中,数据库作为数据存储的核心组件,其稳定性和可用性至关重要。一旦数据库发生故障,可能会导致业务中断甚至数据丢失。为了提高...

    MySQL 字段约束 mysql学习笔记

    MySQL 字段约束详解 MySQL 字段约束是指在 MySQL 中对字段的定义时添加的约束或修饰符,它们可以用来增加对输入数据的约束。今天我们来看一下 MySQL 的字段约束:NULL 和 NOT NULL 修饰符、DEFAULT 修饰符、AUTO_...

    mysql 自增长 时间字段

    MySQL 自增长时间字段详解 MySQL 是一种广泛应用的关系型数据库管理系统,具有强大的数据存储和管理能力。在实际应用中,我们经常需要对数据进行自增长和时间戳记录,本文将详细介绍 MySQL 中的自增长和时间字段的...

    mysql执行过程

    MySQL 执行过程详解 MySQL 是一个流行的关系型数据库管理系统,本文将对 MySQL 执行过程进行详细的解释,并结合具体的实例来讲解 MySQL 存储过程。 什么是 MySQL 存储过程? MySQL 存储过程是一个预编译的 SQL ...

    CentOs7下mysql5.7的下载安装以及主从同步、双主多从配置详情

    CentOs7 下 Mysql 5.7 的下载安装和主从同步、双主多从配置详解 CentOs 7 是一个流行的 Linux 操作系统,而 Mysql 5.7 是一个广泛使用的关系型数据库管理系统。本文将详细介绍如何在 CentOs 7 下下载安装 Mysql 5.7...

    win2003下MySQL数据同步

    ### Win2003下MySQL数据同步配置详解 #### 一、引言 在数据库管理领域,数据同步是一项重要的技术,特别是在多服务器架构中。本文档详细介绍了如何在Windows Server 2003环境下实现MySQL数据库的数据同步。通过...

    heartbeat +mysql master +ldirectord构建高可用的MYSQL主主复制

    #### MySQL AA复制详解 MySQL AA(Active-Active)复制模式是指在一个复制组内,两个或多个MySQL实例都可以同时处理写操作。这种模式可以提供更好的性能和可用性,并能在一定程度上提高系统的扩展能力。下面详细...

    MySQL数据库双活同步复制方案详解.pdf

    为了防止"脑裂"和自增ID冲突,通常会设置不同的`auto_increment_increment`和`auto_increment_offset`。此外,可以利用MySQL 5.7+的多线程复制功能减少延迟,或者使用半同步复制(semi-sync)实现接近零延迟,但可能...

    MySQL数据库双活同步复制方案详解.docx

    为了防止数据冲突,自增ID的配置至关重要,通常会设置`auto_increment_increment`和`auto_increment_offset`以避免ID冲突。此外,半同步复制(semi-sync)可以降低复制延迟,但可能牺牲事务并发性能。对于延迟非常...

    mysql创建表(详解mysql的建表方法).docx

    id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(50), age INT ); ``` 这个语句创建了一个名为`Students`的表,包含三个字段:`id`(自动递增的整数主键)、`name`(最多50个字符的字符串)和`age`(整数类型...

Global site tag (gtag.js) - Google Analytics