加入收藏 | 设为首页 | 会员中心 | 我要投稿 PHP编程网 - 黄冈站长网 (http://www.0713zz.com/)- 数据应用、建站、人体识别、智能机器人、语音技术!
当前位置: 首页 > 站长学院 > MySql教程 > 正文

mysql的auto_increment细说

发布时间:2022-04-03 00:33:37 所属栏目:MySql教程 来源:互联网
导读:MySQL的中AUTO_INCREMENT类型的属性用于为一个表中记录自动生成ID功能,可在一定程度上代替Oracle,PostgreSQL等数据库中的sequence。 在数据库应用,我们经常要用到唯一编号,以标识记录。在MySQL中可通过数据列的AUTO_INCREMENT属性来自动生成。 当插入
        MySQL的中AUTO_INCREMENT类型的属性用于为一个表中记录自动生成ID功能,可在一定程度上代替Oracle,PostgreSQL等数据库中的sequence。          在数据库应用,我们经常要用到唯一编号,以标识记录。在MySQL中可通过数据列的AUTO_INCREMENT属性来自动生成。          当插入记录时,如果为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就会失效。    在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()   一、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”:因为不能确定插入的数量,因此使用和以前的模式相同的表级锁定。   三、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。   最后说一句今天遇到这个问题,在LOCK_MODE为AUTO_INC,而且事物回滚非常的慢,不得已停止数据库重新启动 mysql> select * from innodb_locks; +-------------+-------------+-----------+-----------+---------------+------------+------------+-----------+----------+-----------+ | lock_id     | lock_trx_id | lock_mode | lock_type | lock_table    | lock_index | lock_space | lock_page | lock_rec | lock_data | +-------------+-------------+-----------+-----------+---------------+------------+------------+-----------+----------+-----------+ | 2954466:518 | 2954466     | AUTO_INC  | TABLE     | `test`.`kkkm` | NULL       |       NULL |      NULL |     NULL | NULL      | | 2954465:518 | 2954465     | AUTO_INC  | TABLE     | `test`.`kkkm` | NULL       |       NULL |      NULL |     NULL | NULL      | +-------------+-------------+-----------+-----------+---------------+------------+------------+-----------+----------+-----------+

(编辑:PHP编程网 - 黄冈站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读