OceaBase 分区表创建技巧

最近遇在干个核心的金融项目,规模很大,客户主要是用oracle数据库,现在需要适配ob,原来在oracle就是分区表的迁来ob以后需要进行改造。

oracle默认使用是堆表(ht),而ob使用的是索引组织表(iot),表原理不一样所以分区表会稍微有点区别。


1、表无主键,创建范围分区表

复制代码
CREATE TABLE sales_orders (        
        order_id INT,
        customer_id INT,
        order_date DATE,
        total_amount DECIMAL(10, 2)
        )
PARTITION BY RANGE(order_date) 
            (  PARTITION M202001 VALUES LESS THAN(TO_DATE('2020/02/01','YYYY/MM/DD'))
            , PARTITION M202002 VALUES LESS THAN(TO_DATE('2020/03/01','YYYY/MM/DD'))
            , PARTITION M202003 VALUES LESS THAN(TO_DATE('2020/04/01','YYYY/MM/DD'))
            , PARTITION M202004 VALUES LESS THAN(TO_DATE('2020/05/01','YYYY/MM/DD'))
            , PARTITION MMAX VALUES LESS THAN (MAXVALUE));

表在无主键情况下创建分区表,只需要提前确认好分区列,分区列的类型,分区规则就行。

由于历史原因,以前很多用堆表的业务都是没有使用主键的,业务涉及没有严格使用三范式,如果此类无主键的表迁移到ob数据库的话,ob也会建议创建上必要的主键索引。

如果业务无法找到合适的列创建主键索引,上面sql 也可以兼容oracle,在ob_oracle 租户可以直接创建成功。


2**、表有主键,创建范围分区表**

但是表有主键的情况下,情况会稍微复杂点,oracle由于是堆表可以按照以下方式创建分区表,主键和分区键之间可以没有关联

复制代码
CREATE TABLE sales_orders (        
        order_id INT,            -- 订单号
        customer_id INT,
        order_date DATE,         -- 订单日期
        total_amount DECIMAL(10, 2),
        PRIMARY KEY(order_id)
        )
        PARTITION BY RANGE(order_date)   -- 使用订单日期进行分区
            (  PARTITION M202001 VALUES LESS THAN(TO_DATE('2020/02/01','YYYY/MM/DD'))
            , PARTITION M202002 VALUES LESS THAN(TO_DATE('2020/03/01','YYYY/MM/DD'))
            , PARTITION M202003 VALUES LESS THAN(TO_DATE('2020/04/01','YYYY/MM/DD'))
            , PARTITION M202004 VALUES LESS THAN(TO_DATE('2020/05/01','YYYY/MM/DD'))
            , PARTITION MMAX VALUES LESS THAN (MAXVALUE)
            );

但是在ob里面,如果需要创建带有主键的分区表,分区列必须是主键列的一部分。

参考官方文档:https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000000820771

如果 ob_oracle 创建分区表使用单独的列会报错:ORA-00600: internal error code, arguments: -5261, A PRIMARY KEY must include all columns in the table's partitioning function

ob_oracle 正确创建分区表方式:

复制代码
CREATE TABLE sales_orders (        
        order_id INT,        -- 订单号
        customer_id INT,
        order_date DATE,    -- 订单日期
        total_amount DECIMAL(10, 2),
        PRIMARY KEY(order_id,order_date)   -- 联合主键
        )
        PARTITION BY RANGE(order_date)      -- order_date 是主键一部分,使用订单日期进行分区
            (  PARTITION M202001 VALUES LESS THAN(TO_DATE('2020/02/01','YYYY/MM/DD'))
            , PARTITION M202002 VALUES LESS THAN(TO_DATE('2020/03/01','YYYY/MM/DD'))
            , PARTITION M202003 VALUES LESS THAN(TO_DATE('2020/04/01','YYYY/MM/DD'))
            , PARTITION M202004 VALUES LESS THAN(TO_DATE('2020/05/01','YYYY/MM/DD'))
            , PARTITION MMAX VALUES LESS THAN (MAXVALUE)
            );

但是这样会有一个问题,就是原来oracle上order_id 是主键,现在在ob以后是order_id,order_date成为组合索引。

如果业务代码层面没有做数据校验的逻辑,会在order_id上产生重复数据,这样不合符原有的业务逻辑

其实很简单,只需要对order_id加个唯一索引即可实现在oracle上一样的逻辑。

复制代码
CREATE unique index idx_uniq_order_id on sales_orders(order_id);

这样一来,order_id就不会出现重复数据了,而且ob分区表的逻辑也能和oracle 对得上。

相关推荐
OceanBase数据库官方博客21 小时前
OceanBase场景解码系列三|OB Cloud 如何稳定支撑中企出海实现数 10 倍的高速增长?
数据库·oceanbase·分布式数据库
码海踏浪1 天前
从简单到专业在OceanBase中查看SQL是否走索引
数据库·sql·oceanbase
OceanBase数据库官方博客3 天前
DeepK 自动程序修复框架论文——OceanBase 校企联合研究
数据库·oceanbase·分布式数据库
OceanBase数据库官方博客3 天前
高德刘振飞:从自研 OceanBase,回望数据库技术范式变迁
数据库·oceanbase·分布式数据库·高德
MMMMMMMMMMemory4 天前
社区版oceanbase报警XA事务悬挂
数据库·oceanbase
OceanBase数据库官方博客4 天前
APQO自适应参数化查询优化框架——OceanBase 校企联合研究成果
数据库·oceanbase·分布式数据库
OceanBase数据库官方博客4 天前
中国联通软研院基于OceanBase引领运营商数智化转型新范式
数据库·oceanbase·分布式数据库
OceanBase数据库官方博客5 天前
滔搏基于OceanBase实现 15TB到0.9TB“无痛切换”与“系统瘦身”
数据库·oceanbase·分布式数据库
OceanBase数据库官方博客5 天前
爱奇艺基于OceanBase实现百亿级卡券业务的“单库双擎”架构升级
数据库·架构·oceanbase·分布式数据库
OceanBase数据库官方博客7 天前
主流关系型数据库系统缺陷实证研究——OceanBase 校企联合研究
数据库·oceanbase·分布式数据库