1 背景描述
oceanbase 数据库中分为 mysql 租户与 oracle 租户,本文针对 oceanbase 中 oracle 租户怎样创建自增列,以及如何更简单方便的处理自增列的问题展开介绍。oceanbase 的 oracle 租户以下简称:oboracle。
发现问题场景
业务需要将数据库转换为 oceanbase 数据库,但源端涉及到 oracle 及 mysql 两种不同数据库,需要合并为 oceanbase 中单一的 oracle 模式,其中源端 mysql 数据库需要改造为 oboracle 并做异构数据迁移。
在数据迁移中发现,mysql 中的自增列(auto_increment)在 oboracle 中是不支持的,在 oboracle 对应 mysql 自增列的功能是通过序列实现的。通过测试以及阅读相关文章,共测试完成了以下四种 oboracle 创建并使用序列的方法。
2 四种 oboracle 创建序列方法
1方法一:sequence + dml
在 oceanbase 中 oracle 数据库,我们可以通过以下语法创建序列:
create sequence sequence_name [ minvalue value -- 序列最小值 maxvalue value -- 序列最大值 start with value -- 序列起始值 increment by value -- 序列增长值 cache cache -- 序列缓存个数 cycle | nocycle -- 序列循环或不循环 ]
语法解释:
sequence_name 是要创建的序列名称
start with 指定使用该序列时要返回的第一个值,默认为 1
increment by 指定序列每次递增的值,默认为 1
minvalue 和 maxvalue 定义序列值的最小值和最大值
如果序列已经递增到最大值或最小值,则会根据你的设置进行循环或停止自增长。cache设置序列预读缓存数量。
cycle 表示循环序列
nocycle 则表示不循环序列
通过 ob 官方文档操作,创建序列,实现表的列自增,示例如下:
obclient [oboracle]> create table test ( -> id number not null primary key, -> name varchar2(480), -> age number(10,0) -> );query ok, 0 rows affected (0.116 sec)obclient [oboracle]> create sequence seq_test start with 100 increment by 1;query ok, 0 rows affected (0.026 sec)obclient [oboracle]> insert into test(id,name,age) values(seq_test.nextval, 'a',18);query ok, 1 row affected (0.035 sec)obclient [oboracle]> insert into test(id,name,age) values(seq_test.nextval, 'b',19);query ok, 1 row affected (0.001 sec)obclient [oboracle]> insert into test(id,name,age) values(seq_test.nextval, 'c',20);query ok, 1 row affected (0.001 sec)obclient [oboracle]> select * from test;+-----+------+------+| id | name | age |+-----+------+------+| 100 | a | 18 || 101 | b | 19 || 102 | c | 20 |+-----+------+------+3 rows in set (0.006 sec)
2方法二:sequence + ddl
1、首先创建一个需要自增列的表。
obclient [oboracle]> create table atable ( -> id number(10,0), -> name varchar2(480), -> age number(10,0), -> primary key (id) -> );query ok, 0 rows affected (0.105 sec)obclient [oboracle]> desc atable;+-------+---------------+------+-----+---------+-------+| field | type | null | key | default | extra |+-------+---------------+------+-----+---------+-------+| id | number(10) | no | pri | null | null || name | varchar2(480) | yes | null | null | null || age | number(10) | yes | null | null | null |+-------+---------------+------+-----+---------+-------+3 rows in set (0.037 sec)
2、创建一个序列并更改表中 id 列的 default 属性为 sequence_name.nextval。
obclient [oboracle]> create sequence a_seq -> minvalue 1 -> maxvalue 999999 -> start with 10 -> increment by 1;query ok, 0 rows affected (0.022 sec)obclient [oboracle]> alter table atable modify id default a_seq.nextval;query ok, 0 rows affected (0.065 sec)obclient [oboracle]> desc atable;+-------+---------------+------+-----+-------------------+-------+| field | type | null | key | default | extra |+-------+---------------+------+-----+-------------------+-------+| id | number(10) | no | pri | a_seq.nextval | null || name | varchar2(480) | yes | null | null | null || age | number(10) | yes | null | null | null |+-------+---------------+------+-----+-------------------+-------+3 rows in set (0.013 sec)
此处为修改表 tablename 中的 id 值为序列 sequence_name 的下一个值。具体而言,sequence_name.nextval 表示调用 sequence_name 序列的 nextval 函数,该函数返回序列的下一个值。因此,执行述语句后,当 tablename 表中插入一行数据时,会自动为 id 列赋值为 sequence_name 序列的下一个值。
3、验证该方法是否达到自增列的效果。
obclient [oboracle]> insert into atable(name,age) values('zhangsan', 18);query ok, 1 row affected (0.047 sec)obclient [oboracle]> insert into atable(name,age) values('lisi', 19);query ok, 1 row affected (0.002 sec)obclient [oboracle]> select * from atable;+----+----------+------+| id | ame | age |+----+----------+------+| 10 | zhangsan | 18 || 11 | lisi | 19 |+----+----------+------+2 rows in set (0.013 sec)
3 方法三:sequence + 触发器
ob 延用 oracle 中创建触发器的方法达到自增列的效果,具体步骤如下:
1、首先创建一个序列。
obclient [oboracle]> create sequence b_seq -> minvalue 1 -> maxvalue 999999 -> start with 1 -> increment by 1;query ok, 0 rows affected (0.023 sec)
2、创建一个表。
obclient [oboracle]> create table btable ( -> id number, -> name varchar2(480), -> age number(10,0) -> );query ok, 0 rows affected (0.129 sec)
3、创建一个触发器,在每次向表中插入行时,触发器将自动将新行的 id 列设置为序列的下一个值。
obclient [oboracle]> create or replace trigger set_id_on_btable -> before insert on btable -> for each row -> begin -> select b_seq.nextval into :new.id from dual; -> end; -> /query ok, 0 rows affected (0.114 sec)
该触发器在每次向 btable 表中插入行之前触发,通过 select b_seq.nextval into :new.id from dual; 将 id 列设置为 b_seq 序列的下一个值。:new.id 表示新插入行的 id 列,dual 是一个虚拟的表,用于生成一行数据用以存储序列的下一个值。
4、验证该方法是否达到自增列的效果。
obclient [oboracle]> insert into btable(name,age) values('zhangsan', 18);query ok, 1 row affected (0.111 sec)obclient [oboracle]> insert into btable(name,age) values('lisi', 19);query ok, 1 row affected (0.002 sec)obclient [oboracle]> select * from btable;+------+----------+------+| id | name | age |+------+----------+------+| 1 | zhangsan | 18 || 2 | lisi | 19 |+------+----------+------+2 rows in set (0.008 sec)
4方法四:generated by default as identity 语法
1、在创建表时使用 generated by default as identity 语法来创建自增长的列。
obclient [oboracle]> create table ctable ( -> id number generated by default as identity minvalue 1 maxvalue 999999 increment by 1 start with 1 primary key, -> name varchar2(480), -> age number(10,0) -> );query ok, 0 rows affected (0.121 sec)obclient [oboracle]> desc ctable;+-------+---------------+------+-----+------------------+-------+| field | type | null | key | default | extra |+-------+---------------+------+-----+------------------+-------+| id | number | no | pri | sequence.nextval | null || name | varchar2(480) | yes | null | null | null || age | number(10) | yes | null | null | null |+-------+---------------+------+-----+------------------+-------+3 rows in set (0.011 sec)
2、验证该方法是否达到自增列的效果。
obclient [oboracle]> insert into ctable(name,age) values('zhangsan', 18);query ok, 1 row affected (0.015 sec)obclient [oboracle]> insert into ctable(name,age) values('lisi', 19);query ok, 1 row affected (0.001 sec)obclient [oboracle]> select * from ctable;+----+----------+------+| id | name | age |+----+----------+------+| 1 | zhangsan | 18 || 2 | lisi | 19 |+----+----------+------+2 rows in set (0.008 sec)
3、通过验证,使用 generated by default as identity 可以非常简单地创建自增长列,无需使用其他手段,例如触发器。此方法不需要手动创建序列,会自动创建一个序列,在内部使用它来生成自增长列的值。
obclient [sys]> select * from dba_objects where object_type='sequence';+-------+-----------------+----------------+------------------+----------------+-------------+-----------+---------------+------------------------------+--------+-----------+-----------+-----------+-----------+--------------+| owner | object_name | subobject_name | object_id | data_object_id | object_type | created | last_ddl_time | timestamp | status | temporary | generated | secondary | namespace | edition_name |+-------+-----------------+----------------+------------------+----------------+-------------+-----------+---------------+------------------------------+--------+-----------+-----------+-----------+-----------+--------------+| mysql | a_seq | null | 1100611139403783 | null | sequence | 31-may-23 | 31-may-23 | 31-may-23 02.21.42.603005 pm | valid | n | n | n | 0 | null || mysql | b_seq | null | 1100611139403784 | null | sequence | 31-may-23 | 31-may-23 | 31-may-23 03.28.39.222090 pm | valid | n | n | n | 0 | null || mysql | iseq$$_50012_16 | null | 1100611139403785 | null | sequence | 31-may-23 | 31-may-23 | 31-may-23 04.01.23.577766 pm | valid | n | n | n | 0 | null || mysql | seq_test | null | 1100611139403786 | null | sequence | 31-may-23 | 31-may-23 | 31-may-23 05.09.33.981039 pm | valid | n | n | n | 0 | null |+-------+-----------------+----------------+------------------+----------------+-------------+-----------+---------------+------------------------------+--------+-----------+-----------+-----------+-----------+--------------+6 rows in set (0.042 sec)
查看数据库对象视图 dba_objects,发现该方法通过创建对象内部命名方式为 iseq$$_5000x_16。
测试发现,关于序列对象的名称在ob中不论是通过 generated by default as identity 自动创建,还是手动创建,都会占用 iseq$$_5000x_16 中 x 的位置,若删除序列或删除表,该对象名称也不会复用,只会单调递增。
tips:
在 oracle 12c 及以上版本中,可以使用 generated by default as identity 关键字来创建自增长的列;
在 postgresql 数据库中 generated by default as identity 也是适用的。
3 总结
方法一(sequence + dml):也就是 ob 的官方文档中创建序列的操作,在每次做 insert 操作时需要指定自增列并加入 sequence_name ,对业务不太友好,不推荐。
方法二(sequence + ddl):相较于第一种该方法只需要指定 ddl 改写 default 属性省去了 dml 的操作,但仍需再指定自己创建的序列名 sequence_name,每个表的序列名都不一致,管理不方便,不推荐。
方法三(sequence + 触发器):延用 oracle 的序列加触发器的方法,触发器会占用更多的计算资源和内存,对性能会有影响,因此也不推荐。
方法四(generated by default as identity 语法):既方便运维人员管理,对业务也很友好,还不影响性能。强烈推荐!!!
以上就是对 oboracle 中如何创建自增列的几种方法的总结。
Linux的文件系统特点
华为mate9、p10手机被媒评价为“时下最好用手机”,不得了啊!
嫦娥4号登陆月球背面,人类的首次!
三星One UI 3用户界面开始推送
AI核心动力之深度学习神经网络的现状及发展趋势
从MySQL到OBOracle:如何处理自增列?
如何根据PLC点亮指示灯最基本的问题理解PLC标准化编程
鸿海携手旗下夏普,全力建构8K生态系
使用SPCE061A对步进电机进行控制的详细资料概述
便携充电宝哪个牌子好?便携充电宝品牌排行榜
利用计算机视觉和机器学习技术实现莴苣种植的精准化作业
铅酸电池可以随时充电吗 铅酸电池怎么充电才耐用 铅酸电池的最佳充电方法
SKYLAB适用于网络摄像机的WiFi模块有哪些?
电池组保护电路测试系统解决方案
音响电源220V150W电子火牛直流变压器,150w power supply for audio system
我国4G移动芯片技术及产业关键问题分析
变压器具有隔直流的特性
新唐科技W588C400主板介绍
蔡司工业CT METROTOM1工作原理
美国明尼苏达大学推出了磁场测量传感器可以避免车辆发生碰撞