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数据库官方博客3 天前
半连接转内连接 | OceanBase SQL 查询改写
sql·oceanbase·分布式数据库
OceanBase数据库官方博客3 天前
解析在OceanBase创建分区的常见问题|OceanBase 用户问题精粹
oceanbase·分布式数据库·分区
OceanBase数据库官方博客3 天前
半连接转内连接规则的原理与代码解析 |OceanBase查询优化
sql·oceanbase·分布式数据库
IT培训中心-竺老师6 天前
OceanBase 数据库分布式与集中式 能力
数据库·分布式·oceanbase
靖顺6 天前
【OceanBase 诊断调优】—— OceanBase 数据库网络速率配置方案
网络·数据库·oceanbase
尚雷558014 天前
OceanBase 社区版 4.0 离线方式升级bp1至bp2 指南(含避坑总结)
oceanbase
五月高高14 天前
Linux部署oceanbase
linux·oceanbase
靖顺17 天前
【OceanBase 诊断调优】—— 统计信息自动收集超时导致的估行不准 SQL 选择错索引
数据库·sql·oceanbase
it界的哈士奇18 天前
Oceanbase离线集群部署
oceanbase