mysql自增怎么用 mysql如何实现自增

mysql 自增插入列mysql自增怎么用的自增属性mysql自增怎么用,一般用来设置整数列根据一定步长逐步增长的值,类似于其他数据库的序列 。不过这里的“序列”是基于特定一张表的 。关于自增属性的相关特性如下mysql自增怎么用:
1. 控制自增属性性能的变量:innodb_autoinc_lock_mode
innodb_autoinc_lock_mode=0
代表传统模式 , 也就是说,在对有自增属性的字段插入记录时,会持续持有一个表级别的自增锁,直到语句执行结束为止 。比如说下面两条语句,SQL 1 在执行期间 , 一直持有对表 f1 的表级自增锁,接下来 SQL 2 执行时锁超时 。
innodb_autoinc_lock_mode=1
代表连续模式,和传统模式差不多,不同的点在于对于简单的插入语句,比如 SQL 2,只在分配新的 ID 过程中持有一个轻量级的互斥锁(线程级别,而不是事务级别),而不是直到语句结束才释放的表锁 。
代表交错模式 。这个模式下放弃了自增表锁 , 产生的值会不连续 。不过这是性能最高的模式,多条插入语句可以并发执行 。MySQL 8.0 默认就是交错模式 。
那针对复制安全来说,以上三种模式 , 0 和 1 对语句级别安全,也就是产生的二进制日志复制到任何其他机器都数据都一致mysql自增怎么用;2 对于语句级别不安全mysql自增怎么用;三种模式对二进制日志格式为行的都安全 。
2. 控制自增属性的步长以及偏移量
一般用在主主复制架构或者多源复制架构里,主动规避主键冲突 。
auto_increment_increment 控制步长
auto_increment_offset 控制偏移量
3. 对于要立刻获取插入值的需求
就是说要获取一张表任何时候的最大值,应该时刻执行以下 SQL 3,而不是 SQL 2 。SQL 2 里的函数 last_insert_id() 只获取上一条语句最开始的 ID,只适合简单的 INSERT 。
4. 自增列溢出现象
自增属性的列如果到了此列数据类型的最大值,会发生值溢出 。比如变更表 f1 的自增属性列为 tinyint 。
SQL 2 显式插入最大值 127,SQL 3 就报错了 。所以这点上建议提前规划好自增列的字段类型,提前了解上限值 。
5. 自增列也可以显式插入有符号的值
那针对这样的,建议在请求到达数据库前规避掉 。
Mysql数据库自增长如何设置?在MySQL中可通过字段mysql自增怎么用的AUTO_INCREMENT属性来自动生成 。
mysql数据库表主键自增长mysql自增怎么用的sql语句
1、不控制主键mysql自增怎么用的起点
create table emb_t_dictBusType
(
emb_c_busTypeIDint not null auto_increment,
emb_c_busTypeEnNamevarchar(255) not null,
emb_c_busTypeZhNamevarchar(255) not null,
primary key(emb_c_busTypeID)
)engine=INNODBdefault charset=gbk;
2、控制主键的起点
create table emb_t_dictBusType
(
emb_c_busTypeIDint not null auto_increment,
emb_c_busTypeEnNamevarchar(255) not null,
emb_c_busTypeZhNamevarchar(255) not null,
primary key(emb_c_busTypeID)
)engine=INNODB auto_increment=1001 default charset=gbk;
mysql如何设置ID自增 设置自增列
MYSQL的自增列一定要是有索引的列 , 设置种子值要在表的后面设置
--mysql
-- 设置自增ID从N开始
CREATE TABLE empautoinc(
ID INT PRIMARY KEY AUTO_INCREMENT
) AUTO_INCREMENT = 100 ; --(设置自增ID从100开始)
insert into empautoinc(id) values(null);
Query OK, 1 row affected (0.00 sec)
mysql select * from empautoinc;
-----
| ID |
-----
| 100 |
-----
1 row in set (0.00 sec)
show table status like 'empautoinc'G;
*************************** 1. row ***************************
Name: empautoinc
Engine: InnoDB
Version: 10
Row_format: Compact
Rows: 1
Avg_row_length: 16384
Data_length: 16384
Max_data_length: 0
Index_length: 0
Data_free: 0
Auto_increment: 101
Create_time: 2016-10-27 01:50:32
Update_time: NULL
Check_time: NULL
Collation: utf8_general_ci
Checksum: NULL
Create_options:
Comment:
1 row in set (0.00 sec)
设置自增列的步长,可以分为全局级别和会话级别
如果是会话级别,那么当用户新建一个会话的时候,那么步长又回到了全局级别,所以mysql的步长跟sqlserver的步长有很大的不同
mysql不能设置为表级别的步长
私信666领取资料
技术分享 | 关于 MySQL 自增 ID 的事儿当mysql自增怎么用我们使用 MySQL 进行数据存储时mysql自增怎么用,一般会为一张表设置一个自增主键,当有数据行插入时,该主键字段则会根据步长与偏移量增长(默认每次 1) 。
下文以 Innodb 引擎为主进行介绍,使用自增主键mysql自增怎么用的好处有很多,如mysql自增怎么用:索引空间占比小、范围查询与排序都友好、避免像 UUID 这样随机字符串带来mysql自增怎么用的页分裂问题等...
当我们对该表设置了自增主键之后,则会在该表上产生一个计数器,用于为自增列分配 ID。
自增的值并不是保存在表结构信息内的 , 对于不同的版本它们有如下的区别:
计数器的值存储在内存中的 , 重启后丢弃,下一次将读取最大的一个自增ID往后继续发号 。
计数器的值将会持久化到磁盘 。在每次发号时都将写入 Redolog,并在每个 Checkpoint 都进行保存,重启时候使用 Redolog 恢复重启之前的值 。
可以预先确定插入行数的语句(像简单 insert 的语句包含多个 value 这种情况也是属于简单插入 , 因为在进行插入时就已经可以确定行数了)
预先不知道要插入的行数的语句(包括 INSERT ... SELECT, REPLACE ... SELECT 和 LOAD DATA 语句,但不包括 plain INSERT )
如果一个事务正在向表中插入值 , 则会产生表级的共享锁,以便当前事务插入的行接收连续的主键值 。
当处于[ 传统模式 ]与[ 连续模式 ]时,每次访问计数器时都会加上一个名为 AUTO-INC 的表级锁
传统模式:锁只持有到该语句执行结束 , 注意是语句结束,不是事务结束
连续模式:批量插入时锁持有到该语句执行结束,简单插入时锁持有到申请完自增ID后即释放,不直到语句完成
通过调整 innodb_autoinc_lock_mode 配置项 , 可以定义 AUTO-INC 锁的模式,不同的模式对应的策略与锁的粒度也将不同 。
当使用基于 Binlog 的复制场景时,对于 statement(SBR)同步模式下只有[ 传统模式 ]与[ 连续模式 ]能保证语句的正确性 。
基于 row(RBR)行复制的情况下任何配置模式都可以 。
执行语句时加 AUTO-INC 表级锁,执行完毕后释放
针对 Bulk Inserts 时才会采用 AUTO-INC 锁,而针对 Simple Inserts 时,则采用了一种新的轻量级的互斥锁来分配 auto_increment 列的值 。
该模式下可以保证同一条 insert 语句中新插入的自增 ID 都是连续的,但如果前一个事务 rollback 丢弃了一部分 ID 的话也会存在后续 ID 出现间隔的情况 。
来一个分配一个,不会产生 AUTO-INC 表级锁 , 仅仅会锁住分配 ID 的过程 。
由于锁的粒度减少,多条语句在插入时进行锁竞争,自增长的值可能不是连续的 。
且当 Binlog 模式为 statement(SBR)时自增 ID 不能保证数据的正确性
不一定,业务也不应该过分依赖 MySQL 自增 ID 的连续性,在以下三种情况下,并不能保证自增 ID 的连续性:
假设已存在数据{1,张三},且张三所属的字段设置了唯一主键
此时再次插入{null,张三}时候,主键冲突插入失败 , 但表的计数器已由2变成了3
当下次插入{null,李四}的时候最终入库的会变成{3,李四}
在一个事务里进行数据的插入,但最后并没提交,而是执行了 Rollback。那么计数器已递增的 ID 是不会返还的,而是被直接丢弃 。
发生大量插入时可能会出现自增 ID 并不是连续的情况
当我们为表设置了自增主键后 , 自增 ID 的范围则与主键的数据类型长度相关 。
如果没有一张表里没有设置任何主键,则会自动生成一个隐性的6字节的 row_id 作为主键,它的取值范围为 0 到 2^48-1 。
row_id 是由一个全局的 dict_sys.row_id 参数进行维护的,所有没有主键的表都会用上它(并不是每一个表单独占一份 row_id list )
那么针对这两种主键,则会有以下两种情况发生:
当自增 ID 到达上限后,受到主键数据类型的影响,计数器发放的下一个 ID 也是当前这个 Max ID ,当执行语句时则会提示主键冲突 。
建议根据业务合理规划 , 在进行表设计时就选择适合的数据类型 。
当然也可以直接选择 Bigint 类型,它的取值范围是无符号情况下:0到 2^64–1(18446744073709551615)
这里并不是指 bigint 类型一定不会用完,毕竟一个有范围的持续增长的值一定会有溢出的时候,只是说一般场景下它都是足够使用的 。
当 row_id 使用完后则又会从 0 开始发放,此时新插入的数据将覆盖回 row_id=0 的数据行 。
由于它并不产生错误,还会造成数据的覆盖写 。所以我们平时还是尽量给表都设置一个合理的主键才是 。
在实际业务场景中,ID 常常需要返回给客户端用来进行相关业务操作 。
假如我们有个 userinfo?uid=? 的 API 接口,而用户 ID 是自增的,这时会发生什么?
该接口通过简单的尝试就可以暴露出真实的业务用户总数,可以很方便的使用爬虫从1开始递增获取数据信息 。
那么有的同学说,我既想使用自增 ID 带来的好处,也不想承受这种比较常见的问题,那该怎么办呢?
在输出或者获取前对指定字段进行可逆的转义操作
优点:实现起来比较简单 , 无论单体业务或者分布式应用都无需考虑对数据源的解析,只需在客户端实现自己的转义与解析方法即可;
缺点:业务入侵较大,且需要前后端各个合作方确认统一的标准;如果转义方法有调整,变更影响面也会很大;字符串长度会随ID长度而变化,使用空位填充也会特别明显;
优点:由于采用了时间戳进行 ID 生成,该 ID 是有序的,对范围查询与排序都比较友好;
缺点:需要保证发号节点的高可用性;另外由于生成时依赖时间戳,需要考虑时钟回拨与时钟同步的问题;
维护一份 ID 与 hash 的映射字典,它可以存在于客户端本身 , 也可以依赖其他如 Redis 、ETCD 之类的组件
优点:hash 长度不会随着 ID 长度或值的变化而变化;可以根据已有的 hash code 来造布隆过滤器;
缺点:业务入侵较大,查询时同样需要先根据 hash key 找到对应的 ID 值;需要考虑选择合适的 hash 算法以及解决 hash 冲突或扩容的问题 。
如何在MYSQL插数据ID自增如何在MYSQL插数据ID自增的方法 。
如下参考:
1.在添加字段之前,第一个应该首先检查当前tb1表的结构,如下图所示 。
2.实例字段列添加到表,如下所示 。
3.再次看表结构和比较之前和之后的情况添加字段 , 如下图所示 。
4.最后,插入新的数据行看到的样子,最后添加自动增长的字段,如下所示 。
注意事项:
MySQL使用的SQL语言是访问数据库最常用的标准语言 。MySQL软件采用双重许可政策,分为社区版,商业版,由于其体积小、速度快、总体拥有成本低,尤其是开放源码这一特性,一般中小网站开发选择MySQL作为数据库 。
一文让你彻底弄懂MySQL自增列MYSQL的自增列在实际生产中应用的非常广泛,相信各位所在的公司or团队,MYSQL开发规范中一定会有要求尽量使用自增列去充当表的主键,为什么DBA会有这样的要求,各位在使用MYSQL自增列时遇到过哪些问题?这些问题是由什么原因造成的呢?本文由浅入深,带领大家彻底弄懂MYSQL的自增机制 。
1.通过auto_increment关键字来指定自增的列,并指定自增列的初始值为1 。
[root@localhost][test1]Create table t(id int auto_increment ,namevarchar(10),primary key(id))auto_increment=1;
QueryOK, 0 rows affected (0.63 sec)
2.自增列上必须有索引 , 将t表的主键索引删除掉 , 会报错
[root@localhost][test1]alter table t drop primary key;
ERROR1075 (42000): Incorrect table definition; there can be only one auto column andit must be defined as a key
3.设定auto_increment_increment参数 , 可以调整自增步长,该参数有session级跟global级,在分库分表以及双主or多主的模式下比较有用 。
4.一个表上只能有一个自增列
5.Mysql5.7及以下版本,innodb表的自增值保存在内存中,重启后表的自增值会设为max(id) 1,而myisam引擎的自增值是保存在文件中 , 重启不会丢失 。Mysql8.0开始 , innodb的自增id能持久化了,重启mysql,自增ID不会丢 。
首先:表中自增列的上限是根据自增列的字段类型来定的 。
若设定了自增id充当主键,当达到了自增id的上限值时,会发生什么样的事情呢?还是以上面创建的 t表为例,先回顾它的表结构:
CREATETABLE `t` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(10) COLLATE utf8mb4_binDEFAULT NULL,
PRIMARY KEY (`id`)
)ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
无符号的int类型,上限是2147483647 。这里我们将表的自增值设为2147483647 , 再插入两行数据:
[root@localhost][test1]alter table t auto_increment=2147483647;
QueryOK, 0 rows affected (0.01 sec)
Records:0Duplicates: 0Warnings: 0
[root@localhost][test1]insert into t(name) values ('test');
QueryOK, 1 row affected (0.01 sec)
[root@localhost][test1]insert into t(name) values ('test');
ERROR 1062 (23000): Duplicate entry '2147483647' for key 'PRIMARY'
可以看到,第一个插入没问题,因为自增列的值为2147483647,这是达到了上限,还没有超过 , 第二行数据插入时,则报出主键重复,在达到上限后,无法再分配新的更大的自增值,也没有从1开始从头分配,在这里表的auto_increment值会一直是2147483647 。
对于写入量大 , 且经常删除数据的表,自增id设为int类型还是偏小的,所以我们为了避免出现自增id涨满的情况,这边统一建议自增id的类型设为unsigned bingint,这样基本可以保障表的自增id是永远够用的 。
这里内容比较多,innodb是索引组织表,所以涉及到索引的知识,但这不是本文的重点,我们快速回顾索引知识:
1.Innodb索引分为主键跟辅助索引,主键即全表,辅助索引叶子节点保存主键的值,而主键的叶子节点保存数据行 , 中间节点存着叶子节点的路由值 。
2.Innodb存储数据(索引)的单位是页,这里默认是16K,这也意味着,数据本身越小,一个页中能存数据的量越多,而检索效率不仅仅由索引的层数来决定,更是由一次能够缓存的数据量来定,也就是说数据本身越?。?则一次IO能够提取到缓冲区的数据越多(OS每次IO的量是固定的4K),查询的效率越好 。
其实能够理解索引的结构及索引写入插入、更新的原理,则自然就明白为何建议使用自增id 。这里我直接列出使用自增id 当主键的好处吧:
1.顺序写入,避免了叶的分裂,数据写入效率好
2.缩小了表的体积,特别是相比于UUID当主键,甚至组合字段当主键时,效果更明显
3.查询效率好,原因就是我上面说到索引知识的第二点 。
4.某些情况下 , 我们可以利用自增id来统计大表的大致行数 。
5.在数据归档or垃圾数据清理时 , 也可方便的利用这个id去操作 , 效率高 。
容易出现不连续的id
有的同志会发现,自己的表中id值存在空洞,如类似于1、2、3、8、9、10这样,有的适合有想依赖于自增id的连续性来实现业务逻辑 , 所以会想方设法去修改id让其变的连续 , 其实 , 这是没有必要的 , 这一块的业务逻辑交由MySQL实现是很不理智的 , 表的记录小还好,要是表的数据量很大,修改起来就糟糕了 。那么,为什么自增id会容易出现空洞呢?
自增id的修改机制如下:
在MySQL里面,如果字段id被定义为AUTO_INCREMENT,在插入一行数据的时候,自增值的行为如下:
1. 如果插入数据时id字段指定为0、null 或未指定值,那么就把这个表当前的
AUTO_INCREMENT值填到自增字段;
2. 如果插入数据时id字段指定了具体的值,就直接使用语句里指定的值 。
根据要插入的值和当前自增值的大小关系 , 自增值的变更结果也会有所不同 。假设 , 某次要插入的值是X , 当前的自增值是Y 。
1. 如果XY , 那么这个表的自增值不变;
2. 如果X≥Y , 就需要把当前自增值修改为 新的自增值。
新的自增值生成算法是:从auto_increment_offset开始 , 以auto_increment_increment为步长 , 持续叠加,直到找到第一个大于X的值,作为新的自增值 。
Insert、update、delete操作会让id不连续 。
Delete、update:删除中间数据 , 会造成空动 , 而修改自增id值,也会造成空洞(这个很少) 。
Insert:插入报错(唯一键冲突与事务回滚),会造成空洞,因为这时候自增id已经分配出去了,新的自增值已经生成,如下面例子:
[root@localhost][test1] select * fromt;
---- ------
| id | name |
---- ------
|1| aaa|
|2| aaa|
|3| aaa|
|4| aaa|
---- ------
4 rows in set (0.00 sec)
[root@localhost][test1] selectAuto_increment from information_schema.tables where table_name='t';
----------------
| Auto_increment |
----------------
|5 |
----------------
1 row in set (0.00 sec)
[root@localhost][test1] begin;
Query OK, 0 rows affected (0.00 sec)
[root@localhost][test1] insert intot(name) values('aaa');
Query OK, 1 row affected (0.00 sec)
[root@localhost][test1] select * fromt;
---- ------
| id | name |
---- ------
|1| aaa|
|2| aaa|
|3| aaa|
|4| aaa|
|5| aaa|
---- ------
5 rows in set (0.00 sec)
[root@localhost][test1] selectAuto_increment from information_schema.tables where table_name='t';
----------------
| Auto_increment |
----------------
|6 |
----------------
1 row in set (0.00 sec)
[root@localhost][test1] rollback;
Query OK, 0 rows affected (0.00 sec)
[root@localhost][test1] selectAuto_increment from information_schema.tables where table_name='t';
----------------
| Auto_increment |
----------------
|6 |
----------------
1 row in set (0.01 sec)
[root@localhost][test1] select * fromt;
---- ------
| id | name |
---- ------
【mysql自增怎么用 mysql如何实现自增】 |1| aaa|
|2| aaa|
|3| aaa|
|4| aaa|
---- ------
4 rows in set (0.00 sec)
可以看到 , 虽然事务回滚了,但自增id已经回不到从前啦,唯一键冲突也是这样的,这里就不做测试了 。
在批量插入时(insert select等),也存在空洞的问题 。看下面实验:
[root@localhost][test1] select * fromt;
---- ------
| id | name |
---- ------
|1| aaa|
|2| aaa|
|3| aaa|
|4| aaa|
---- ------
4 rows in set (0.00 sec)
[root@localhost][test1] selectAuto_increment from information_schema.tables where table_name='t';
----------------
| Auto_increment |
----------------
|5 |
----------------
1 row in set (0.00 sec)
[root@localhost][test1] insert intot(name) select name from t;
Query OK, 4 rows affected (0.04 sec)
Records: 4 Duplicates: 0Warnings: 0
[root@localhost][test1] select * fromt;
---- ------
| id | name |
---- ------
|1| aaa|
|2| aaa|
|3| aaa|
|4| aaa|
|5| aaa|
|6| aaa|
|7| aaa|
|8| aaa|
---- ------
8 rows in set (0.00 sec)
[root@localhost][test1] selectAuto_increment from information_schema.tables where table_name='t';
----------------
| Auto_increment |
----------------
|12 |
----------------
1 row in set (0.00 sec)
可以看到,批量插入,导致下一个id值不为9了,再插入数据,即产生了空洞,这里是由mysql申请自增值的机制所造成的,MySQL在批量插入时,若一个值申请一个id,效率太慢,影响了批量插入的速度 , 故mysql采用下面的策略批量申请id 。
1.语句执行过程中 , 第一次申请自增id,会分配1个;
2.1个用完以后,这个语句第二次申请自增id,会分配2个;
3.2个用完以后 , 还是这个语句,第三次申请自增id,会分配4个;
4.依此类推,同一个语句去申请自增id,每次申请到的自增id个数都是上一次的两倍 。
在对自增列进行操作时,存在着自增锁,mysql的innodb_autoinc_lock_mode参数控制着自增锁的上锁机制 。该参数有0、1、2三种模式:
0:语句执行结束后释放自增锁,MySQL5.0时采用这种模式,并发度较低 。
1:mysql的默认设置 。普通的insert语句申请后立马释放,insert select、replace insert、load data等批量插入语句要等语句执行结束后才释放,并发读得到提升
2:所有的语句都是申请后立马释放,并发度大大提升!但是在binlog为statement格式时,主从数据会发生不一致 。这一块网上有很多介绍,我不做介绍了 。
在彻底了解了MYSQL的自增机制以后,在实际生产中就能灵活避坑 , 这里建议不要用自增id值去当表的行数,当需要对大表准确统计行数时,可以去count(*)从库,如果业务很依赖大表的准确行数,直接弄个中间表来统计 , 或者考虑要不要用mysql的innodb来存储数据,这个是需要自己去权衡 。另外对于要求很高的写入性能,但写入量又比较大的业务,自增id的使用依然存在热点写入的问题,存在性能瓶颈,这时候可通过分库分表来解决 。
关于mysql自增怎么用和mysql如何实现自增的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站 。

    推荐阅读