基于湖库一体架构,统一管理结构化、半结构化与非结构化等多模态数据,一个系统承载事务处理、实时分析与 AI 工作负载。
数据分布
更新时间:2026-08-14 11:48:11
OceanBase Database AI 通过创建分区表将数据分布在不同的分区,不同分区数据可以分布到不同的机器,查询时利用分区裁剪能够减少数据的扫描量,且能利用多机的资源提升查询性能。默认情况下,不同表之间的数据是随机分布的,没有直接关系,通过负载均衡可以将一个表的数据比较均匀的分布在整个集群。
OceanBase Database AI 中分区的作用
在 OceanBase Database AI 中,分区是水平分片的基本单位,是数据分布、负载均衡和并行操作的最小物理单元。一张大表被逻辑地分割成多个更小、更易管理的独立块,每个分区(甚至分区的不同副本)都可以分散存储在集群中不同的 OBServer 节点上。
这种设计为分析型业务带来的优势在于,当单个节点的存储或计算能力达到瓶颈时,只需通过增加节点并重新分布分区,即可实现近乎线性的水平扩展,以应对 PB 级数据规模。
OceanBase Database AI 的基础分区方式
目前 OceanBase Database AI 中支持三大类基础的分区方式,包括 Hash/Key、Range/Range Columns 和 List/List Columns。三种分区方式各自的使用场景有所不同。
HASH/KEY 分区
一般适用于分区列 NDV(不同值的种类)较大,且难以划分出明确范围的情况。优点是容易让没有特定规则的数据也能够在不同的分区内均匀分布,缺点是在范围查询时难以进行分区裁剪。
适用场景举例:
- 无明显查询模式,需均匀分布数据到多个节点(如用户 ID、交易 ID)。
设计要点:
分区键选择:
- NDV(唯一值数量)远大于分区数(如用户 ID 的 NDV 应远大于分区数)。
- 优先选择无倾斜(或只有少量倾斜)的整型 / 时间列(如
user_id,order_time,或者自增列)。 - 高频查询条件字段(如
user_id作为 Join 关键字)。
分区数推荐:
- 确保分区数匹配集群的机器数量,避免资源分配不均衡
示例场景:
-- Hash 分区,按 user_id 均匀分布
CREATE TABLE customer (
user_id BIGINT NOT NULL,
login_time TIMESTAMP NOT NULL,
customer_name VARCHAR(100) NOT NULL,
phone_num BIGINT NOT NULL,
city_name VARCHAR(50) NOT NULL,
sex INT NOT NULL,
id_number VARCHAR(18) NOT NULL,
home_address VARCHAR(255) NOT NULL,
office_address VARCHAR(255) NOT NULL,
age INT NOT NULL
)
PARTITION BY HASH(user_id) PARTITIONS 128;
Range/Range Columns 分区
一般适用于分区键容易划分出明确的范围的情况,例如可以把记录流水信息的大表,根据表示信息时间的列做 RANGE 分区。
适用场景举例:
- 数据按时间 / 数值范围增长(如
order_time,price)。 - 需快速裁剪历史数据(如仅查询最近一个月数据)。
设计要点:
分区键选择:
- 时间字段(如
order_time)或连续数值字段。 - 分区边界需与业务查询条件对齐(如按天 / 月划分)。
- 时间字段(如
分区数推荐:
- 根据数据增长设置分区,例如按照月份分区。
示例场景:
-- 创建系统日志表,按日志时间进行月度 RANGE 分区,支持快速查询与数据归档
CREATE TABLE system_logs (
log_id BIGINT,
log_date TIMESTAMP NOT NULL,
log_level VARCHAR(10),
source_system VARCHAR(50),
user_id BIGINT,
log_message TEXT,
client_ip VARCHAR(15)
)
-- 主分区:按月 RANGE 分区,使用日期直接表达分区边界
PARTITION BY RANGE COLUMNS(log_date) (
PARTITION p_202001 VALUES LESS THAN ('2020-02-01'),
PARTITION p_202002 VALUES LESS THAN ('2020-03-01'),
PARTITION p_202003 VALUES LESS THAN ('2020-04-01'),
PARTITION p_202004 VALUES LESS THAN ('2020-05-01'),
PARTITION p_202005 VALUES LESS THAN ('2020-06-01'),
PARTITION p_202006 VALUES LESS THAN ('2020-07-01'),
PARTITION p_202007 VALUES LESS THAN ('2020-08-01'),
PARTITION p_202008 VALUES LESS THAN ('2020-09-01'),
PARTITION p_202009 VALUES LESS THAN ('2020-10-01'),
PARTITION p_202010 VALUES LESS THAN ('2020-11-01'),
PARTITION p_202011 VALUES LESS THAN ('2020-12-01'),
PARTITION p_202012 VALUES LESS THAN ('2021-01-01'),
-- 默认分区处理未来数据或时间格式异常的记录
PARTITION p_future VALUES LESS THAN (MAXVALUE)
);
List/List Columns 分区
一般适用于需要显式控制各行数据如何映射到具体的某一个分区时,优点是可以对无序或无关的数据集进行精准分区,缺点是在范围查询时难以进行分区裁剪。
适用场景举例:
- 离散型字段(如地区、渠道类型)。
- 需按固定类别快速裁剪数据(如查询华东地区用户)。
设计要点:
分区键选择:
- 离散值且数量有限(如
region字段仅有['east','west','south','north'])。 - 分区值需覆盖所有可能取值,避免遗漏。
- 离散值且数量有限(如
分区数限制:
- 根据业务逻辑进行配置分区数。
示例场景:
CREATE TABLE orders_by_region (
order_id BIGINT COMMENT '订单唯一标识',
region_code INT NOT NULL PRIMARY KEY COMMENT '区域代码(1=north/china, 2=east/china, 3=south/china, 4=west/china)',
customer_id BIGINT COMMENT '客户 ID',
order_time DATETIME COMMENT '订单创建时间',
product_category VARCHAR(50) COMMENT '商品类别',
order_amount DECIMAL(18,2) COMMENT '订单金额',
payment_status VARCHAR(20) COMMENT '支付状态(如:PAID, UNPAID)'
)
PARTITION BY LIST(region_code) -- 改为整数类型分区键
(
PARTITION p_north VALUES IN (1), -- 区域代码 1 对应 north/china
PARTITION p_east VALUES IN (2),
PARTITION p_south VALUES IN (3),
PARTITION p_west VALUES IN (4),
PARTITION p_other VALUES IN (DEFAULT) -- 默认分区处理未知区域
);
混合数据维护和数据分布管理
我们也可以以二级分区的方式,同时支持数据维护和数据分布的需求。通常使用比较多的场景为:一级分区用于数据维护的需求,二级分区用于数据分布的需求,每种需求可以使用对应需求所支持的方式进行组合。
典型的手动分区管理方式
- 一级分区:
- 类型选择:使用 Range 或者 List 分区,匹配高频查询条件(如时间范围、地区)
- 分区数建议:根据查询条件时间分布、数据维护的需求设置合理范围(如按月分区保留 12 个月,或按地区分为 4 个 List 分区)
- 二级分区:
- 类型选择:使用 Hash 分区,保证数据打散
- 分区数推荐:
- 如果只有一个一级分区写入,那么一级分区的二级分区数需要满足写入打散的资源诉求
- 如果有多个一级分区能够写入,那么能写入的一级分区数 × 二级分区数满足写入打散的资源诉求即可
Range + Hash
一级选择 Range 分区,指定 order_date 后,可以快速过滤掉不需要扫描数据的分区,也能够通过分区管理操作快速进行数据维护;二级选择 Hash 分区,可以将当月的写入或者读取打散到 8 个分区中,避免热点。
CREATE TABLE orders (
user_id BIGINT NOT NULL COMMENT '用户 ID(二级分区键)',
order_date DATE NOT NULL COMMENT '下单日期(一级分区键)',
amount DECIMAL(10,2) NOT NULL COMMENT '订单金额',
status TINYINT NOT NULL COMMENT '状态: 0-取消 1-待支付 2-已支付 3-已发货 4-已完成',
region_code CHAR(6) NOT NULL COMMENT '地区编码(前 2 位省码)',
product_id INT NOT NULL COMMENT '商品 ID',
payment_method VARCHAR(20) COMMENT '支付方式',
created_at TIMESTAMP(6) DEFAULT CURRENT_TIMESTAMP(6) COMMENT '记录创建时间')
PARTITION BY RANGE COLUMNS(order_date)
SUBPARTITION BY HASH(user_id) SUBPARTITIONS 8
(
PARTITION p202501 VALUES LESS THAN ('2025-02-01'),
PARTITION p202502 VALUES LESS THAN ('2025-03-01'),
...
PARTITION p202601 VALUES LESS THAN ('2026-02-01')
);
List + Hash
一级选择 List 分区,指定省份能够裁剪到相应的分区,也可以按照省维度进行数据维护;二级选择 Hash / Key 分区,可以将省的读写流量打散到多个分区中,实现负载均衡。
-- 一级分区:LIST 按省划分(31 个省级行政区)
CREATE TABLE social_insurance_records (
record_id BIGINT,
province_code INT NOT NULL, -- 省级编码(如 11 北京,31 上海)
payment_date DATE NOT NULL,
user_id VARCHAR(32) NOT NULL,
amount DECIMAL(10,2)
) PARTITION BY LIST (province_code) -- 一级 LIST 分区
SUBPARTITION BY KEY(user_id) SUBPARTITIONS 16 -- 二级 HASH 分区
(
PARTITION p_beijing VALUES IN (11),
PARTITION p_shanghai VALUES IN (31),
PARTITION p_tianjin VALUES IN (12),
...
PARTITION p_xizang VALUES IN (54)
);