ORACLE SEQUENCE和MYSQL 自增字段对比

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 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

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
打赏
0
0
0
0
91
分享
相关文章
MySQL 和 Oracle 的区别?
本文对比了Oracle和MySQL数据库的多个方面。Oracle适用于大型数据库,支持高并发和大访问量,市场占有率为40%,安装占用空间较大,约3G;而MySQL适合中小型应用,是开源免费的,安装仅需152M。两者在主键生成、字符串处理、SQL语句、事务处理等方面存在差异。Oracle功能更为强大,尤其在企业级应用中表现突出,而MySQL则以简单易用见长。
MySQL 和 Oracle 的区别?
Mysql、Oracle审计日志的开启
通过上述步骤,可以在 MySQL 和 Oracle 数据库中启用和配置审计日志。这些日志对于监控数据库操作、提高安全性和满足合规性要求非常重要。确保正确配置审计参数和策略,定期查看和分析审计日志,有助于及时发现并处理潜在的安全问题。
81 11
MySQL主键谁与争锋:MySQL为何钟爱自增主键ID+UUID?
本文深入探讨了在MySQL中使用自增类型主键的优势与局限性。自增主键通过保证数据的有序性和减少索引维护成本,提升了查询和插入性能,简化了数据库管理和维护,并提高了数据一致性。然而,在某些业务场景下,如跨表唯一性需求或分布式系统中,自增主键可能无法满足要求,且存在主键值易预测的安全风险。因此,选择主键类型时需综合考虑业务需求和应用场景。
118 2
MySQL的group by与count(), *字段使用问题
正确使用 `GROUP BY`和 `COUNT()`函数是进行数据聚合查询的基础。通过理解它们的用法和常见问题,可以有效避免查询错误和性能问题。无论是在单列分组、多列分组还是结合其他聚合函数的场景中,掌握这些技巧和注意事项都能大大提升数据查询和分析的效率。
419 0
MySQL 8.0特性-自增变量的持久化
【11月更文挑战第8天】在 MySQL 8.0 之前,自增变量(`AUTO_INCREMENT`)的行为在服务器重启后可能会发生变化,导致意外结果。MySQL 8.0 引入了自增变量的持久化特性,将其信息存储在数据字典中,确保重启后的一致性。这提高了开发和管理的稳定性,减少了主键冲突和数据不一致的风险。默认情况下,MySQL 8.0 启用了这一特性,但在升级时需注意行为变化。
113 1
MySQL自增ID耗尽应对策略:技术解决方案全解析
在数据库管理中,MySQL的自增ID(AUTO_INCREMENT)属性为表中的每一行提供了一个唯一的标识符。然而,当自增ID达到其最大值时,如何处理这一情况成为了数据库管理员和开发者必须面对的问题。本文将探讨MySQL自增ID耗尽的原因、影响以及有效的应对策略。
279 3
MySQL自增ID耗尽解决方案:应对策略与实践技巧
在MySQL数据库中,自增ID(AUTO_INCREMENT)是一种特殊的属性,用于自动为新插入的行生成唯一的标识符。然而,当自增ID达到其最大值时,会发生什么?又该如何解决?本文将探讨MySQL自增ID耗尽的问题,并提供一些实用的解决方案。
150 1
SpringBoot项目中mysql字段映射使用JSONObject和JSONArray类型
SpringBoot项目中mysql字段映射使用JSONObject和JSONArray类型 图像处理 光通信 分布式计算 算法语言 信息技术 计算机应用
82 8
oracle 数据库 迁移 mysql数据库
将 Oracle 数据库迁移到 MySQL 是一项复杂的任务,因为这两种数据库管理系统具有不同的架构、语法和功能。
136 0
oracle迁移mysql数据库注意(转)
oracle转mysql修改:1. substr() substr( string , 0, 10) 这里测试 必须从 第一位获取 既是 substr(string , 1 , 10)2. to_char() 只能用做oracle的函数,兼容oracle和mysql故 改为concat( … , ''); 这里 使用了两个, 一个 是将类似 int 转为 string 3.
1784 0

推荐镜像

更多
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等