ORACLE SEQUENCE和MYSQL 自增字段对比

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: ORACLE 序列:不同于MYSQL的自增字段ORACLE序列是单独的一个object,单独进行维护,可以查看 SQL> select * from dba_sequences a where a.
ORACLE 序列:不同于MYSQL的自增字段ORACLE序列是单独的一个object,单独进行维护,可以查看
SQL> select * from dba_sequences a where a.sequence_name='TEST_SEQ'; 
SEQUENCE_OWNER                 SEQUENCE_NAME                   MIN_VALUE  MAX_VALUE INCREMENT_BY CYCLE_FLAG ORDER_FLAG CACHE_SIZE LAST_NUMBER
------------------------------ ------------------------------ ---------- ---------- ------------ ---------- ---------- ---------- -----------
SYS                            TEST_SEQ                                1       1E28            1 N          N                  10          11




这里的TEST_SEQ使用了CACHE 10的选项,意思为缓存10个数字在缓存中,索引LAST_NUMBER是11,如果重启后或者导入到其他数据库那么值是从11开始,丢失内存中的
计数,同时和MYSQL 的INNODB auto_increment一样如果事物回滚都可能出现断裂带
SQL> insert into testseq values(test_seq.nextval,'gaopeng');
1 row inserted




SQL> commit;
Commit complete




SQL> insert into testseq values(test_seq.nextval,'gaopeng');
1 row inserted




SQL> rollback;
Rollback complete




SQL> insert into testseq values(test_seq.nextval,'gaopeng');
1 row inserted




SQL> select * from testseq;
        ID NAME
---------- --------------------
         1 gaopeng
         3 gaopeng




但是任何TRUNCATE,DELETE是不会影响到寻列本生的。
SQL> truncate table testseq;
Table truncated




SQL> insert into testseq values(test_seq.nextval,'gaopeng');
1 row inserted




SQL> select* from testseq;
        ID NAME
---------- --------------------
       121 gaopeng




删除顶端的值,重启后怎么样呢?
SQL> select LAST_NUMBER from dba_sequences a where a.sequence_name='TEST_SEQ';
LAST_NUMBER
-----------
        130




SQL> select* from testseq;
        ID NAME
---------- --------------------
       121 gaopeng
       122 gaopeng
       123 gaopeng
       124 gaopeng
       125 gaopeng
       126 gaopeng
删除顶端部分值
SQL> delete from testseq where id>124;
2 rows deleted




SQL> commit;
Commit complete
这里实际的值下次应该是 




SQL> select test_seq.nextval from dual;
   NEXTVAL
----------
       127 
然后重启
SQL> insert into testseq values(test_seq.nextval,'gaopeng');
Warning: connection was lost and re-established
1 row inserted




SQL> select* from testseq;
        ID NAME
---------- --------------------
       121 gaopeng
       122 gaopeng
       123 gaopeng
       124 gaopeng
       130 gaopeng
可以看到这里的ID=130实际上是LAST_NUMBER的值
















但是MYSQL INNODB有一些不同
mysql> create table testseq
    -> (id int(10) auto_increment,
    ->  name varchar(20),
    ->  primary key (id));
Query OK, 0 rows affected (0.42 sec)




mysql> alter table testseq auto_increment=1000;




1、TRUNCATE后自增字段将从最小值1开始,而ORACLE不会,因为ORACLE SEQUENCE是单独的OBJECT,不受表本生影响
mysql> select * from testseq;
+------+---------+
| id   | name    |
+------+---------+
| 1000 | gaopeng |
| 1002 | gaopeng |
+------+---------+
2 rows in set (0.00 sec)




mysql> truncate table testseq;
Query OK, 0 rows affected (0.17 sec)




mysql> insert into testseq(name) values('gaopeng');
Query OK, 1 row affected (0.04 sec)




mysql> insert into testseq(name) values('gaopeng');
Query OK, 1 row affected (0.00 sec)




mysql> insert into testseq(name) values('gaopeng');
Query OK, 1 row affected (0.00 sec)




mysql> select * from testseq;
+----+---------+
| id | name    |
+----+---------+
|  1 | gaopeng |
|  2 | gaopeng |
|  3 | gaopeng |
+----+---------+
3 rows in set (0.00 sec)








2、INNODB 在缓存中维护着计数器,如果重启后,任何删除顶端的数据重启后会重用这些数据,而ORACLE不会,因为ORACLE会从LAST_NUMBER开始
mysql> select * from testseq;
+----+---------+
| id | name    |
+----+---------+
|  1 | gaopeng |
|  3 | gaopeng |
|  5 | gaopeng |
|  6 | gaopeng |
|  7 | gaopeng |
|  8 | gaopeng |
+----+---------+
6 rows in set (0.00 sec)




mysql> delete from testseq where id>6;
Query OK, 1 row affected (0.01 sec)




mysql> select * from testseq;
+----+---------+
| id | name    |
+----+---------+
|  1 | gaopeng |
|  3 | gaopeng |
|  5 | gaopeng |
|  6 | gaopeng |
+----+---------+
4 rows in set (0.00 sec)




这个时候正常的情况下应该是下次是9,如果我们重启后




mysql> insert into testseq(name) values('gaopeng');
Query OK, 1 row affected (0.01 sec)




mysql> select * from testseq;
+----+---------+
| id | name    |
+----+---------+
|  1 | gaopeng |
|  3 | gaopeng |
|  5 | gaopeng |
|  6 | gaopeng |
|  7 | gaopeng |
+----+---------+
5 rows in set (0.02 sec)
可以看到ID=7的行被重用
















3、相同点都可能出现断裂如下:




mysql> insert into testseq(name) values('gaopeng');
Query OK, 1 row affected (0.03 sec)




mysql> select * from testseq;
+------+---------+
| id   | name    |
+------+---------+
| 1000 | gaopeng |
+------+---------+
1 row in set (0.00 sec)




mysql> begin;
Query OK, 0 rows affected (0.00 sec)




mysql> insert into testseq(name) values('gaopeng');
Query OK, 1 row affected (0.03 sec)




mysql> rollback;
Query OK, 0 rows affected (0.06 sec)




mysql> insert into testseq(name) values('gaopeng');
Query OK, 1 row affected (0.01 sec)




mysql> select * from testseq;
+------+---------+
| id   | name    |
+------+---------+
| 1000 | gaopeng |
| 1002 | gaopeng |
+------+---------+
2 rows in set (0.00 sec)








最后总结一下
1、TRUNCATE后自增字段将从最小值1开始,而ORACLE不会,因为ORACLE SEQUENCE是单独的OBJECT,不受表本生影响
2、INNODB和ORACLE 都在缓存中维护着计数器,但是MYSQL任何删除顶端的数据重启后会重用这些数据,而ORACLE重启会丢失全部的CACHE中的值直接从LAST_NUMBER开始
3、MYSQL和ORACLE都会出现回滚断裂问题
4、ORACLE是单独的对象而MYSQL是和表在一起的
5、如果在MYSQL中使用unsignde可以得到更大的自增值如下,因为tinyint的取值范围问题有如下报错:


mysql> create table testseq1 (id tinyint(3)  unsigned auto_increment,  name varchar(20),  primary key (id));
Query OK, 0 rows affected (0.01 sec)


mysql> create table testseq2 (id tinyint(3)   auto_increment,  name varchar(20),  primary key (id));
Query OK, 0 rows affected (0.02 sec)


mysql> alter table testseq1 auto_increment=200;
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0


mysql> alter table testseq2 auto_increment=200;
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0


mysql> insert into testseq1(name) values('gaopeng');
Query OK, 1 row affected (0.00 sec)
mysql> insert into testseq2(name) values('gaopeng');
ERROR 1467 (HY000): Failed to read auto-increment value from storage engine

相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
27天前
|
关系型数据库 MySQL
mysql增加修改删除字段
mysql增加修改删除字段
14 0
|
2月前
|
SQL Oracle 关系型数据库
Oracle 将表中的数据查出更改某一字段的值后再插入该表
Oracle 将表中的数据查出更改某一字段的值后再插入该表
32 2
|
2月前
|
关系型数据库 MySQL 数据库
MySQL时间字段设置自动更新
MySQL时间字段设置自动更新
27 0
|
2月前
|
存储 关系型数据库 MySQL
如何在MySQL现有表中添加自增ID?
如何在MySQL现有表中添加自增ID?
131 5
如何在MySQL现有表中添加自增ID?
|
2月前
|
SQL 关系型数据库 MySQL
MySQL 用gourp by分组后取某一字段最大值
MySQL 用gourp by分组后取某一字段最大值
|
22天前
|
存储 关系型数据库 MySQL
MySQL数据库性能大揭秘:表设计优化的高效策略(优化数据类型、增加冗余字段、拆分表以及使用非空约束)
MySQL数据库性能大揭秘:表设计优化的高效策略(优化数据类型、增加冗余字段、拆分表以及使用非空约束)
|
3月前
|
SQL Oracle 关系型数据库
整合Mybatis-Plus高级,Oracle 主键Sequence,Sql 注入器实现自定义全局操作
整合Mybatis-Plus高级,Oracle 主键Sequence,Sql 注入器实现自定义全局操作
89 0
|
2天前
|
存储 数据可视化 关系型数据库
MySQL字段的时间类型该如何选择?千万数据下性能提升10%~30%🚀
本文探讨MySQL中时间类型的选择,阐述datetime、timestamp、整形时间戳等类型特点以及它们在千万级数据量下的查询性能
MySQL字段的时间类型该如何选择?千万数据下性能提升10%~30%🚀
|
6天前
|
SQL 关系型数据库 MySQL
mysql 数据库查询 查询字段用逗号隔开 关联另一个表并显示
mysql 数据库查询 查询字段用逗号隔开 关联另一个表并显示
17 2
|
10天前
|
关系型数据库 MySQL
MySQL全局库表查询准确定位字段
information_schema.COLUMNS 详细信息查询
201 4

推荐镜像

更多