您当前的位置:首页 > 电脑百科 > 数据库 > MYSQL

从MySQL到OBOracle:如何处理自增列?

时间:2023-06-09 14:20:29  来源:  作者:OSC开源社区

作者:杨敬博

爱可生 DBA 团队成员,一位会摄影、会铲屎、会打球、会骑车、生活可以自理的 DBA。

* 爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。

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 数据库,我们可以通过以下语法创建序列:

CREATESEQUENCEsequence_name

[

MINVALUEvalue-- 序列最小值

MAXVALUE value-- 序列最大值

STARTWITHvalue-- 序列起始值

INCREMENTBYvalue-- 序列增长值

CACHEcache-- 序列缓存个数

CYCLE| NOCYCLE-- 序列循环或不循环

]

语法解释:

  • sequence_name 是要创建的序列名称

  • START WITH 指定使用该序列时要返回的第一个值,默认为 1

  • INCREMENT BY 指定序列每次递增的值,默认为 1

  • MINVALUE 和 MAXVALUE 定义序列值的最小值和最大值

    • 如果序列已经递增到最大值或最小值,则会根据你的设置进行循环或停止自增长。 CACHE 设置序列预读缓存数量。

  • CYCLE 表示循环序列

  • NOCYCLE 则表示不循环序列

通过 OB 官方文档操作,创建序列,实现表的列自增,示例如下:

obclient [oboracle]> CREATETABLEtest(

-> IDNUMBERNOTNULLPRIMARY KEY,

-> NAMEVARCHAR2( 480),

-> AGE NUMBER( 10, 0)

-> );

Query OK, 0 rows affected (0.116 sec)

obclient [oboracle]> CREATESEQUENCEseq_test STARTWITH100INCREMENTBY1;

Query OK, 0 rows affected (0.026 sec)

obclient [oboracle]> INSERTINTOtest( ID, NAME,AGE) VALUES(seq_test.nextval, 'A', 18);

Query OK, 1 row affected (0.035 sec)

obclient [oboracle]> INSERTINTOtest( ID, NAME,AGE) VALUES(seq_test.nextval, 'B', 19);

Query OK, 1 row affected (0.001 sec)

obclient [oboracle]> INSERTINTOtest( ID, NAME,AGE) VALUES(seq_test.nextval, 'C', 20);

Query OK, 1 row affected (0.001 sec)

obclient [oboracle]> select* fromtest;

+ -----+------+------+

| ID | NAME | AGE |

+ -----+------+------+

| 100 | A | 18 |

| 101 | B | 19 |

| 102 | C | 20 |

+ -----+------+------+

3 rows in set( 0.006sec)

2方法二:SEQUENCE + DDL

1、首先创建一个需要自增列的表。

obclient [oboracle]> CREATETABLEAtable (

-> IDNUMBER( 10, 0),

-> NAMEVARCHAR2( 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.037sec)

2、创建一个序列并更改表中 ID 列的 DEFAULT 属性为 sequence_name.nextval 。

obclient [oboracle]> CREATESEQUENCEA_seq

-> MINVALUE1

-> MAXVALUE 999999

-> STARTWITH10

-> INCREMENTBY1;

Query OK, 0 rows affected (0.022 sec)

obclient [oboracle]> ALTERTABLEAtable MODIFYidDEFAULTA_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.013sec)

此处为修改表 tablename 中的 ID 值为序列 sequence_name 的下一个值。具体而言, sequence_name.nextval 表示调用 sequence_name 序列的 nextval 函数,该函数返回序列的下一个值。因此,执行述语句后,当 tablename 表中插入一行数据时,会自动为 ID 列赋值为 sequence_name 序列的下一个值。

3、验证该方法是否达到自增列的效果。

obclient [oboracle]> INSERTINTOAtable( NAME,AGE) VALUES( 'zhangsan', 18);

Query OK, 1 row affected (0.047 sec)

obclient [oboracle]> INSERTINTOAtable( NAME,AGE) VALUES( 'lisi', 19);

Query OK, 1 row affected (0.002 sec)

obclient [oboracle]> select* fromAtable;

+ ----+----------+------+

| ID | AME | AGE |

+ ----+----------+------+

| 10 | zhangsan | 18 |

| 11 | lisi | 19 |

+ ----+----------+------+

2 rows in set( 0.013sec)

3方法三:SEQUENCE + 触发器

OB 延用 Oracle 中创建触发器的方法达到自增列的效果,具体步骤如下:

1、首先创建一个序列。

obclient [oboracle]> CREATESEQUENCEB_seq

-> MINVALUE1

-> MAXVALUE 999999

-> STARTWITH1

-> INCREMENTBY1;

Query OK, 0 rows affected (0.023 sec)

2、创建一个表。

obclient [oboracle]> CREATETABLEBtable (

-> IDNUMBER,

-> NAMEVARCHAR2( 480),

-> AGE NUMBER( 10, 0)

-> );

Query OK, 0 rows affected (0.129 sec)

3、创建一个触发器,在每次向表中插入行时,触发器将自动将新行的 ID 列设置为序列的下一个值。

obclient [oboracle]> CREATEORREPLACETRIGGERset_id_on_Btable

-> BEFOREINSERTONBtable

-> FOREACHROW

-> BEGIN

-> SELECTB_seq.NEXTVAL INTO:new.id FROMdual;

-> 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]> INSERTINTOBtable( NAME,AGE) VALUES( 'zhangsan', 18);

Query OK, 1 row affected (0.111 sec)

obclient [oboracle]> INSERTINTOBtable( NAME,AGE) VALUES( 'lisi', 19);

Query OK, 1 row affected (0.002 sec)

obclient [oboracle]> select* fromBtable;

+ ------+----------+------+

| ID | NAME | AGE |

+ ------+----------+------+

| 1 | zhangsan | 18 |

| 2 | lisi | 19 |

+ ------+----------+------+

2 rows in set( 0.008sec)

4方法四:GENERATED BY DEFAULT AS IDENTITY 语法

1、在创建表时使用 GENERATED BY DEFAULT AS IDENTITY 语法来创建自增长的列。

obclient [oboracle]> CREATETABLECtable (

-> IDNUMBERGENERATEDBYDEFAULTASIDENTITYMINVALUE1MAXVALUE 999999INCREMENTBY1STARTWITH1primary key,

-> NAMEVARCHAR2( 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.011sec)

2、验证该方法是否达到自增列的效果。

obclient [oboracle]> INSERTINTOCtable( NAME,AGE) VALUES( 'zhangsan', 18);

Query OK, 1 row affected (0.015 sec)

obclient [oboracle]> INSERTINTOCtable( NAME,AGE) VALUES( 'lisi', 19);

Query OK, 1 row affected (0.001 sec)

obclient [oboracle]> select* fromCtable;

+ ----+----------+------+

| ID | NAME | AGE |

+ ----+----------+------+

| 1 | zhangsan | 18 |

| 2 | lisi | 19 |

+ ----+----------+------+

2 rows in set( 0.008sec)

3、通过验证,使用 GENERATED BY DEFAULT AS IDENTITY 可以非常简单地创建自增长列,无需使用其他手段,例如触发器。此方法不需要手动创建序列,会自动创建一个序列,在内部使用它来生成自增长列的值。

obclient [SYS]> select* fromdba_objects whereOBJECT_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.042sec)

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 中如何创建自增列的几种方法的总结。有需要的小伙伴可以试试(●'◡'●)。

END



Tags:MySQL   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
MySQL 核心模块揭秘
server 层会创建一个 SAVEPOINT 对象,用于存放 savepoint 信息。binlog 会把 binlog offset 写入 server 层为它分配的一块 8 字节的内存里。 InnoDB 会维护自己的 savepoint...【详细内容】
2024-04-03  Search: MySQL  点击:(6)  评论:(0)  加入收藏
MySQL 核心模块揭秘,你看明白了吗?
为了提升分配 undo 段的效率,事务提交过程中,InnoDB 会缓存一些 undo 段。只要同时满足两个条件,insert undo 段或 update undo 段就能被缓存。1. 关于缓存 undo 段为了提升分...【详细内容】
2024-03-27  Search: MySQL  点击:(11)  评论:(0)  加入收藏
MySQL:BUG导致DDL语句无谓的索引重建
对于5.7.23之前的版本在评估类似DDL操作的时候需要谨慎,可能评估为瞬间操作,但是实际上线的时候跑了很久,这个就容易导致超过维护窗口,甚至更大的故障。一、问题模拟使用5.7.22...【详细内容】
2024-03-26  Search: MySQL  点击:(10)  评论:(0)  加入收藏
从 MySQL 到 ByteHouse,抖音精准推荐存储架构重构解读
ByteHouse是一款OLAP引擎,具备查询效率高的特点,在硬件需求上相对较低,且具有良好的水平扩展性,如果数据量进一步增长,可以通过增加服务器数量来提升处理能力。本文将从兴趣圈层...【详细内容】
2024-03-22  Search: MySQL  点击:(24)  评论:(0)  加入收藏
MySQL自增主键一定是连续的吗?
测试环境:MySQL版本:8.0数据库表:T (主键id,唯一索引c,普通字段d)如果你的业务设计依赖于自增主键的连续性,这个设计假设自增主键是连续的。但实际上,这样的假设是错的,因为自增主键不...【详细内容】
2024-03-10  Search: MySQL  点击:(6)  评论:(0)  加入收藏
准线上事故之MySQL优化器索引选错
1 背景最近组里来了许多新的小伙伴,大家在一起聊聊技术,有小兄弟提到了MySQL的优化器的内部策略,想起了之前在公司出现的一个线上问题,今天借着这个机会,在这里分享下过程和结论...【详细内容】
2024-03-07  Search: MySQL  点击:(28)  评论:(0)  加入收藏
MySQL数据恢复,你会吗?
今天分享一下binlog2sql,它是一款比较常用的数据恢复工具,可以通过它从MySQL binlog解析出你要的SQL,并根据不同选项,可以得到原始SQL、回滚SQL、去除主键的INSERT SQL等。主要...【详细内容】
2024-02-22  Search: MySQL  点击:(45)  评论:(0)  加入收藏
如何在MySQL中实现数据的版本管理和回滚操作?
实现数据的版本管理和回滚操作在MySQL中可以通过以下几种方式实现,包括使用事务、备份恢复、日志和版本控制工具等。下面将详细介绍这些方法。1.使用事务:MySQL支持事务操作,可...【详细内容】
2024-02-20  Search: MySQL  点击:(53)  评论:(0)  加入收藏
为什么高性能场景选用Postgres SQL 而不是 MySQL
一、 数据库简介 TLDR;1.1 MySQL MySQL声称自己是最流行的开源数据库,它属于最流行的RDBMS (Relational Database Management System,关系数据库管理系统)应用软件之一。LAMP...【详细内容】
2024-02-19  Search: MySQL  点击:(38)  评论:(0)  加入收藏
MySQL数据库如何生成分组排序的序号
经常进行数据分析的小伙伴经常会需要生成序号或进行数据分组排序并生成序号。在MySQL8.0中可以使用窗口函数来实现,可以参考历史文章有了这些函数,统计分析事半功倍进行了解。...【详细内容】
2024-01-30  Search: MySQL  点击:(54)  评论:(0)  加入收藏
▌简易百科推荐
MySQL 核心模块揭秘
server 层会创建一个 SAVEPOINT 对象,用于存放 savepoint 信息。binlog 会把 binlog offset 写入 server 层为它分配的一块 8 字节的内存里。 InnoDB 会维护自己的 savepoint...【详细内容】
2024-04-03  爱可生开源社区    Tags:MySQL   点击:(6)  评论:(0)  加入收藏
MySQL 核心模块揭秘,你看明白了吗?
为了提升分配 undo 段的效率,事务提交过程中,InnoDB 会缓存一些 undo 段。只要同时满足两个条件,insert undo 段或 update undo 段就能被缓存。1. 关于缓存 undo 段为了提升分...【详细内容】
2024-03-27  爱可生开源社区  微信公众号  Tags:MySQL   点击:(11)  评论:(0)  加入收藏
MySQL:BUG导致DDL语句无谓的索引重建
对于5.7.23之前的版本在评估类似DDL操作的时候需要谨慎,可能评估为瞬间操作,但是实际上线的时候跑了很久,这个就容易导致超过维护窗口,甚至更大的故障。一、问题模拟使用5.7.22...【详细内容】
2024-03-26  MySQL学习  微信公众号  Tags:MySQL   点击:(10)  评论:(0)  加入收藏
从 MySQL 到 ByteHouse,抖音精准推荐存储架构重构解读
ByteHouse是一款OLAP引擎,具备查询效率高的特点,在硬件需求上相对较低,且具有良好的水平扩展性,如果数据量进一步增长,可以通过增加服务器数量来提升处理能力。本文将从兴趣圈层...【详细内容】
2024-03-22  字节跳动技术团队    Tags:ByteHouse   点击:(24)  评论:(0)  加入收藏
MySQL自增主键一定是连续的吗?
测试环境:MySQL版本:8.0数据库表:T (主键id,唯一索引c,普通字段d)如果你的业务设计依赖于自增主键的连续性,这个设计假设自增主键是连续的。但实际上,这样的假设是错的,因为自增主键不...【详细内容】
2024-03-10    dbaplus社群  Tags:MySQL   点击:(6)  评论:(0)  加入收藏
准线上事故之MySQL优化器索引选错
1 背景最近组里来了许多新的小伙伴,大家在一起聊聊技术,有小兄弟提到了MySQL的优化器的内部策略,想起了之前在公司出现的一个线上问题,今天借着这个机会,在这里分享下过程和结论...【详细内容】
2024-03-07  转转技术  微信公众号  Tags:MySQL   点击:(28)  评论:(0)  加入收藏
MySQL数据恢复,你会吗?
今天分享一下binlog2sql,它是一款比较常用的数据恢复工具,可以通过它从MySQL binlog解析出你要的SQL,并根据不同选项,可以得到原始SQL、回滚SQL、去除主键的INSERT SQL等。主要...【详细内容】
2024-02-22  数据库干货铺  微信公众号  Tags:MySQL   点击:(45)  评论:(0)  加入收藏
如何在MySQL中实现数据的版本管理和回滚操作?
实现数据的版本管理和回滚操作在MySQL中可以通过以下几种方式实现,包括使用事务、备份恢复、日志和版本控制工具等。下面将详细介绍这些方法。1.使用事务:MySQL支持事务操作,可...【详细内容】
2024-02-20  编程技术汇    Tags:MySQL   点击:(53)  评论:(0)  加入收藏
MySQL数据库如何生成分组排序的序号
经常进行数据分析的小伙伴经常会需要生成序号或进行数据分组排序并生成序号。在MySQL8.0中可以使用窗口函数来实现,可以参考历史文章有了这些函数,统计分析事半功倍进行了解。...【详细内容】
2024-01-30  数据库干货铺  微信公众号  Tags:MySQL   点击:(54)  评论:(0)  加入收藏
mysql索引失效的场景
MySQL中索引失效是指数据库查询时无法有效利用索引,这可能导致查询性能显著下降。以下是一些常见的MySQL索引失效的场景:1.使用非前导列进行查询: 假设有一个复合索引 (A, B)。...【详细内容】
2024-01-15  小王爱编程  今日头条  Tags:mysql索引   点击:(85)  评论:(0)  加入收藏
站内最新
站内热门
站内头条