ORACLE SEQUENCE和MYSQL 自增字段对比-阿里云开发者社区

开发者社区> 数据库> 正文
登录阅读全文

ORACLE SEQUENCE和MYSQL 自增字段对比

简介: 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

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:
数据库
使用钉钉扫一扫加入圈子
+ 订阅

分享数据库前沿,解构实战干货,推动数据库技术变革

其他文章