1. 首页 > 国产数据库教程 > Kingbase教程 > 正文

kingbase教程FG157-金仓数据库范围列表哈希分区

本文档风哥主要介绍金仓数据库范围列表哈希分区相关知识,包括分区的概念、类型、优势、环境要求、分区规划、实现方法、实战案例等内容,风哥教程参考金仓官方文档性能调优相关内容编写,适合DBA人员在学习和测试中使用,如果要应用于生产环境则需要自行确认。

Part01-基础概念与理论知识

1.1 金仓数据库分区概念

金仓数据库分区是将一个大表分割成多个小表的技术,每个小表称为一个分区。分区可以提高查询性能,简化数据管理,减少维护成本。

金仓数据库分区的特点:

  • 将大表分割成多个小表
  • 每个分区独立存储
  • 可以单独管理每个分区,学习交流加群风哥微信: itpux-com
  • 提高查询性能
  • 简化数据管理

1.2 金仓数据库分区类型

金仓数据库支持的分区类型:


# 范围分区
– 基于列值的范围进行分区
– 例如:按日期范围、数值范围等
– 适用于数据有明显范围特征的场景
# 列表分区
– 基于列值的列表进行分区
– 例如:按地区、状态等
– 适用于数据有离散值的场景
# 哈希分区
– 基于列值的哈希值进行分区
– 数据均匀分布到各个分区
– 适用于数据分布均匀的场景
# 复合分区
– 结合多种分区类型
– 例如:范围-哈希分区、列表-哈希分区等
– 适用于复杂的数据分布场景

1.3 金仓数据库分区优势

金仓数据库分区的优势:

  • 提高查询性能:只扫描相关分区,减少数据扫描量
  • 简化数据管理:可以单独管理每个分区,如备份、恢复、删除等
  • 减少维护成本:可以对每个分区单独进行维护操作,学习交流加群风哥QQ113257174
  • 提高可用性:一个分区的故障不影响其他分区
  • 支持大数据量:可以处理更大的数据量
风哥提示:分区是数据库性能优化的重要手段,合理的分区策略可以显著提高数据库的性能和可管理性。在设计分区时,应该根据数据的特点和查询模式选择合适的分区类型。

Part02-生产环境规划与建议

2.1 分区环境要求

金仓数据库分区的环境要求:


# 硬件要求
– CPU:足够的CPU资源,处理分区操作
– 内存:足够的内存,支持分区管理
– 磁盘:足够的磁盘空间,存储分区数据
# 软件要求
– 金仓数据库版本:KingbaseES V8.0及以上
– 操作系统:Oracle Linux 9.3 / RHEL 9.3 / 8.x / 7.x、麒麟操作系统 Kylin v10 SP3
# 数据库参数要求
– work_mem:适当增大,提高分区操作性能
– maintenance_work_mem:适当增大,提高分区维护性能
– shared_buffers:适当增大,提高数据缓存能力

2.2 分区规划

金仓数据库分区的规划:


# 范围分区规划
– 分区键选择:选择查询频繁的列,如日期、时间等
– 分区数量:根据数据量和查询模式确定,一般建议每个分区大小在10-50GB之间
– 分区策略:按时间范围(如年、月、日)或数值范围
# 列表分区规划
– 分区键选择:选择有离散值的列,如地区、状态等
– 分区数量:根据离散值的数量确定
– 分区策略:按离散值列表进行分区
# 哈希分区规划
– 分区键选择:选择分布均匀的列,如ID、UUID等
– 分区数量:根据数据量和服务器资源确定,一般建议分区数量为2的幂次方
– 分区策略:按哈希值均匀分布
# 复合分区规划
– 结合多种分区类型,如范围-哈希分区、列表-哈希分区等
– 适用于复杂的数据分布场景

2.3 分区性能考量

金仓数据库分区的性能考量:

  • 分区键选择:选择查询频繁的列,避免选择更新频繁的列
  • 分区数量:分区数量过多会增加管理成本,过少则无法充分发挥分区的优势
  • 分区大小:每个分区的大小应该合理,一般建议在10-50GB之间,更多视频教程www.fgedu.net.cn
  • 数据分布:数据应该均匀分布到各个分区,避免数据倾斜
  • 索引设计:为每个分区创建适当的索引,提高查询性能
  • 维护操作:定期进行分区维护,如清理、重建等
生产环境建议:在设计分区时,应该根据数据的特点和查询模式选择合适的分区类型和分区策略。同时,应该定期监控分区的使用情况,及时调整分区策略。

Part03-生产环境项目实施方案

3.1 金仓数据库范围分区

3.1.1 创建范围分区表


# 连接数据库
$ ksql -U fgedu -d fgedudb
# 创建范围分区表
CREATE TABLE fgedu_order_range (
order_id INTEGER PRIMARY KEY,
order_date DATE,
customer_id INTEGER,
amount NUMERIC(10,2)
)
PARTITION BY RANGE (order_date);
# 创建分区
CREATE TABLE fgedu_order_range_202601 PARTITION OF fgedu_order_range
FOR VALUES FROM (‘2026-01-01’) TO (‘2026-02-01’);
CREATE TABLE fgedu_order_range_202602 PARTITION OF fgedu_order_range
FOR VALUES FROM (‘2026-02-01’) TO (‘2026-03-01’);
CREATE TABLE fgedu_order_range_202603 PARTITION OF fgedu_order_range
FOR VALUES FROM (‘2026-03-01’) TO (‘2026-04-01’);
CREATE TABLE fgedu_order_range_202604 PARTITION OF fgedu_order_range
FOR VALUES FROM (‘2026-04-01’) TO (‘2026-05-01’);
# 插入测试数据
INSERT INTO fgedu_order_range VALUES (1, ‘2026-01-15’, 101, 100.00);
INSERT INTO fgedu_order_range VALUES (2, ‘2026-02-15’, 102, 200.00);
INSERT INTO fgedu_order_range VALUES (3, ‘2026-03-15’, 103, 300.00);
INSERT INTO fgedu_order_range VALUES (4, ‘2026-04-15’, 104, 400.00);
# 查询分区数据
SELECT * FROM fgedu_order_range;
order_id | order_date | customer_id | amount
———-+————+————-+——–
1 | 2026-01-15 | 101 | 100.00
2 | 2026-02-15 | 102 | 200.00
3 | 2026-03-15 | 103 | 300.00
4 | 2026-04-15 | 104 | 400.00
# 查询特定分区
SELECT * FROM fgedu_order_range_202601;
order_id | order_date | customer_id | amount
———-+————+————-+——–
1 | 2026-01-15 | 101 | 100.00

3.1.2 管理范围分区


# 连接数据库
$ ksql -U fgedu -d fgedudb
# 添加新分区
CREATE TABLE fgedu_order_range_202605 PARTITION OF fgedu_order_range
FOR VALUES FROM (‘2026-05-01’) TO (‘2026-06-01’);
# 删除旧分区
DROP TABLE fgedu_order_range_202601;
# 查看分区信息
SELECT
inhparent::regclass AS parent_table,
inhrelid::regclass AS partition_table
FROM pg_inherits
WHERE inhparent = ‘fgedu_order_range’::regclass;
parent_table | partition_table
—————+——————-
fgedu_order_range | fgedu_order_range_202602
fgedu_order_range | fgedu_order_range_202603
fgedu_order_range | fgedu_order_range_202604
fgedu_order_range | fgedu_order_range_202605

3.2 金仓数据库列表分区

3.2.1 创建列表分区表


# 连接数据库
$ ksql -U fgedu -d fgedudb
# 创建列表分区表
CREATE TABLE fgedu_customer_list (
customer_id INTEGER PRIMARY KEY,
name VARCHAR(50),
region VARCHAR(50),
status VARCHAR(20)
)
PARTITION BY LIST (region);
# 创建分区
CREATE TABLE fgedu_customer_list_north PARTITION OF fgedu_customer_list
FOR VALUES IN (‘North’);
CREATE TABLE fgedu_customer_list_south PARTITION OF fgedu_customer_list
FOR VALUES IN (‘South’);
CREATE TABLE fgedu_customer_list_east PARTITION OF fgedu_customer_list
FOR VALUES IN (‘East’);
CREATE TABLE fgedu_customer_list_west PARTITION OF fgedu_customer_list
FOR VALUES IN (‘West’);
# 插入测试数据
INSERT INTO fgedu_customer_list VALUES (1, ‘John’, ‘North’, ‘Active’);
INSERT INTO fgedu_customer_list VALUES (2, ‘Jane’, ‘South’, ‘Active’);
INSERT INTO fgedu_customer_list VALUES (3, ‘Robert’, ‘East’, ‘Inactive’);
INSERT INTO fgedu_customer_list VALUES (4, ‘Alice’, ‘West’, ‘Active’);
# 查询分区数据
SELECT * FROM fgedu_customer_list;
customer_id | name | region | status
————-+——–+——–+——–
1 | John | North | Active
2 | Jane | South | Active
3 | Robert | East | Inactive
4 | Alice | West | Active
# 查询特定分区
SELECT * FROM fgedu_customer_list_north;
customer_id | name | region | status
————-+——+——–+——–
1 | John | North | Active

3.2.2 管理列表分区


# 连接数据库
$ ksql -U fgedu -d fgedudb
# 添加新分区
CREATE TABLE fgedu_customer_list_central PARTITION OF fgedu_customer_list
FOR VALUES IN (‘Central’);
# 删除旧分区
DROP TABLE fgedu_customer_list_west;
# 查看分区信息
SELECT
inhparent::regclass AS parent_table,
inhrelid::regclass AS partition_table
FROM pg_inherits
WHERE inhparent = ‘fgedu_customer_list’::regclass;
parent_table | partition_table
—————-+————————
fgedu_customer_list | fgedu_customer_list_north
fgedu_customer_list | fgedu_customer_list_south
fgedu_customer_list | fgedu_customer_list_east
fgedu_customer_list | fgedu_customer_list_central

3.3 金仓数据库哈希分区

3.3.1 创建哈希分区表


# 连接数据库
$ ksql -U fgedu -d fgedudb
# 创建哈希分区表
CREATE TABLE fgedu_product_hash (
product_id INTEGER PRIMARY KEY,
name VARCHAR(50),
price NUMERIC(10,2),
category VARCHAR(50)
)
PARTITION BY HASH (product_id);
# 创建分区
CREATE TABLE fgedu_product_hash_1 PARTITION OF fgedu_product_hash
FOR VALUES WITH (MODULUS 4, REMAINDER 0);
CREATE TABLE fgedu_product_hash_2 PARTITION OF fgedu_product_hash
FOR VALUES WITH (MODULUS 4, REMAINDER 1);
CREATE TABLE fgedu_product_hash_3 PARTITION OF fgedu_product_hash
FOR VALUES WITH (MODULUS 4, REMAINDER 2);
CREATE TABLE fgedu_product_hash_4 PARTITION OF fgedu_product_hash
FOR VALUES WITH (MODULUS 4, REMAINDER 3);
# 插入测试数据
INSERT INTO fgedu_product_hash VALUES (1, ‘Product A’, 100.00, ‘Category 1’);
INSERT INTO fgedu_product_hash VALUES (2, ‘Product B’, 200.00, ‘Category 2’);
INSERT INTO fgedu_product_hash VALUES (3, ‘Product C’, 300.00, ‘Category 1’);
INSERT INTO fgedu_product_hash VALUES (4, ‘Product D’, 400.00, ‘Category 2’);
INSERT INTO fgedu_product_hash VALUES (5, ‘Product E’, 500.00, ‘Category 1’);
INSERT INTO fgedu_product_hash VALUES (6, ‘Product F’, 600.00, ‘Category 2’);
INSERT INTO fgedu_product_hash VALUES (7, ‘Product G’, 700.00, ‘Category 1’);
INSERT INTO fgedu_product_hash VALUES (8, ‘Product H’, 800.00, ‘Category 2’);
# 查询分区数据
SELECT * FROM fgedu_product_hash;
product_id | name | price | category
————+———–+——–+———-
1 | Product A | 100.00 | Category 1
2 | Product B | 200.00 | Category 2
3 | Product C | 300.00 | Category 1
4 | Product D | 400.00 | Category 2
5 | Product E | 500.00 | Category 1
6 | Product F | 600.00 | Category 2
7 | Product G | 700.00 | Category 1
8 | Product H | 800.00 | Category 2
# 查询特定分区
SELECT * FROM fgedu_product_hash_1;
product_id | name | price | category
————+———–+——–+———-
4 | Product D | 400.00 | Category 2
8 | Product H | 800.00 | Category 2

3.3.2 管理哈希分区


# 连接数据库
$ ksql -U fgedu -d fgedudb
# 查看分区信息
SELECT
inhparent::regclass AS parent_table,
inhrelid::regclass AS partition_table
FROM pg_inherits
WHERE inhparent = ‘fgedu_product_hash’::regclass;
parent_table | partition_table
—————–+———————-
fgedu_product_hash | fgedu_product_hash_1
fgedu_product_hash | fgedu_product_hash_2
fgedu_product_hash | fgedu_product_hash_3
fgedu_product_hash | fgedu_product_hash_4
# 查看分区数据分布
SELECT
partition_table,
COUNT(*) AS row_count
FROM (
SELECT
inhrelid::regclass AS partition_table,
product_id
FROM pg_inherits
JOIN fgedu_product_hash ON inhrelid = tableoid
WHERE inhparent = ‘fgedu_product_hash’::regclass
) AS t
GROUP BY partition_table;
partition_table | row_count
——————–+———–
fgedu_product_hash_1 | 2
fgedu_product_hash_2 | 2
fgedu_product_hash_3 | 2
fgedu_product_hash_4 | 2

风哥提示:在选择分区类型时,应该根据数据的特点和查询模式进行选择。范围分区适用于时间序列数据,列表分区适用于离散值数据,哈希分区适用于均匀分布的数据。

Part04-生产案例与实战讲解

4.1 金仓数据库分区实战案例

4.1.1 案例背景

某电信企业的用户通话记录系统需要存储大量的通话记录数据,数据量达到TB级别。企业希望通过使用分区技术来提高查询性能,简化数据管理,降低维护成本。

4.1.2 实施方案


# 1. 分析需求
# 存储用户通话记录,按时间范围查询,数据量较大
# 2. 设计分区策略
# 使用范围分区,按月份分区,每个分区存储一个月的数据
# 3. 创建分区表
CREATE TABLE fgedu_call_record (
call_id INTEGER PRIMARY KEY,
caller_id VARCHAR(20),
callee_id VARCHAR(20),
call_start_time TIMESTAMP,
call_duration INTEGER, — 通话时长(秒)
call_type VARCHAR(10) — 通话类型:语音、短信等
)
PARTITION BY RANGE (call_start_time);
# 4. 创建分区
— 创建2026年1月分区
CREATE TABLE fgedu_call_record_202601 PARTITION OF fgedu_call_record
FOR VALUES FROM (‘2026-01-01 00:00:00’) TO (‘2026-02-01 00:00:00’);
— 创建2026年2月分区
CREATE TABLE fgedu_call_record_202602 PARTITION OF fgedu_call_record
FOR VALUES FROM (‘2026-02-01 00:00:00’) TO (‘2026-03-01 00:00:00’);
— 创建2026年3月分区
CREATE TABLE fgedu_call_record_202603 PARTITION OF fgedu_call_record
FOR VALUES FROM (‘2026-03-01 00:00:00’) TO (‘2026-04-01 00:00:00’);
— 创建2026年4月分区
CREATE TABLE fgedu_call_record_202604 PARTITION OF fgedu_call_record
FOR VALUES FROM (‘2026-04-01 00:00:00’) TO (‘2026-05-01 00:00:00’);
# 5. 为分区创建索引
CREATE INDEX idx_fgedu_call_record_caller_id ON fgedu_call_record(caller_id);
CREATE INDEX idx_fgedu_call_record_callee_id ON fgedu_call_record(callee_id);
CREATE INDEX idx_fgedu_call_record_call_start_time ON fgedu_call_record(call_start_time);
# 6. 插入测试数据
INSERT INTO fgedu_call_record VALUES (1, ‘13800138001’, ‘13900139001’, ‘2026-01-15 10:00:00’, 120, ‘语音’);
INSERT INTO fgedu_call_record VALUES (2, ‘13800138002’, ‘13900139002’, ‘2026-02-15 11:00:00’, 180, ‘语音’);
INSERT INTO fgedu_call_record VALUES (3, ‘13800138003’, ‘13900139003’, ‘2026-03-15 12:00:00’, 90, ‘语音’);
INSERT INTO fgedu_call_record VALUES (4, ‘13800138004’, ‘13900139004’, ‘2026-04-15 13:00:00’, 60, ‘语音’);
# 7. 查询测试
— 查询特定时间段的数据
SELECT * FROM fgedu_call_record WHERE call_start_time BETWEEN ‘2026-02-01’ AND ‘2026-02-29’;
call_id | caller_id | callee_id | call_start_time | call_duration | call_type
———+————-+————-+————————-+—————+———–
2 | 13800138002 | 13900139002 | 2026-02-15 11:00:00+00 | 180 | 语音
— 查看执行计划
EXPLAIN ANALYZE SELECT * FROM fgedu_call_record WHERE call_start_time BETWEEN ‘2026-02-01’ AND ‘2026-02-29’;
— 执行计划显示只扫描了202602分区,提高了查询性能

4.1.3 实施效果

通过使用分区技术,企业成功实现了以下目标:

  • 查询性能显著提高,查询时间从原来的数分钟减少到数秒
  • 数据管理更加简化,可以单独管理每个月的数据,更多学习教程公众号风哥教程itpux_com
  • 维护成本降低,可以对每个分区单独进行备份和恢复
  • 系统可用性提高,一个分区的故障不影响其他分区
  • 支持更大的数据量,为未来业务增长做好准备

4.2 金仓数据库分区优化

4.2.1 分区键选择优化


# 1. 选择合适的分区键
# 对于时间序列数据,选择时间列作为分区键
CREATE TABLE fgedu_log_range (
log_id INTEGER PRIMARY KEY,
log_time TIMESTAMP,
log_level VARCHAR(10),
log_message TEXT
)
PARTITION BY RANGE (log_time);
# 对于离散值数据,选择离散值列作为分区键
CREATE TABLE fgedu_user_list (
user_id INTEGER PRIMARY KEY,
user_name VARCHAR(50),
user_type VARCHAR(20),
status VARCHAR(10)
)
PARTITION BY LIST (user_type);
# 对于均匀分布的数据,选择ID列作为分区键
CREATE TABLE fgedu_transaction_hash (
transaction_id INTEGER PRIMARY KEY,
user_id INTEGER,
amount NUMERIC(10,2),
transaction_time TIMESTAMP
)
PARTITION BY HASH (transaction_id);

4.2.2 分区数量优化


# 1. 根据数据量确定分区数量
# 每个分区大小建议在10-50GB之间
# 例如:1TB数据,每个分区50GB,需要20个分区
# 2. 根据服务器资源确定分区数量
# 考虑CPU核心数、内存大小等因素
# 例如:4核心CPU,建议分区数量不超过8个
# 3. 动态调整分区数量
# 根据数据增长情况,定期添加新分区
# 对于历史数据,考虑合并或归档旧分区

4.2.3 索引优化


# 1. 为分区表创建合适的索引
# 为分区键创建索引
CREATE INDEX idx_fgedu_order_range_order_date ON fgedu_order_range(order_date);
# 为常用查询列创建索引
CREATE INDEX idx_fgedu_order_range_customer_id ON fgedu_order_range(customer_id);
# 2. 考虑使用局部索引
# 只在特定分区上创建索引
CREATE INDEX idx_fgedu_order_range_202601_amount ON fgedu_order_range_202601(amount);

4.3 金仓数据库分区故障处理

4.3.1 常见故障及解决方案


# 故障1:分区键选择不当
# 症状:查询性能没有提高,甚至下降
# 解决方案:
– 重新选择合适的分区键
– 重新设计分区策略
# 故障2:分区数量过多
# 症状:管理成本增加,性能下降
# 解决方案:
– 合并部分分区
– 重新设计分区策略
# 故障3:数据倾斜
# 症状:部分分区数据量过大,部分分区数据量过小
# 解决方案:
– 重新选择分区键
– 调整分区策略
# 故障4:分区维护操作失败
# 症状:添加、删除分区失败
# 解决方案:
– 检查权限
– 检查磁盘空间
– 检查数据完整性
# 故障5:分区索引失效
# 症状:查询性能下降
# 解决方案:
– 重建索引
– 检查索引设计

生产环境建议:在使用分区技术时,应该注意合理选择分区键,控制分区数量,避免数据倾斜,定期进行分区维护。同时,应该监控分区的使用情况,及时调整分区策略。

Part05-风哥经验总结与分享

5.1 金仓数据库分区最佳实践

金仓数据库分区的最佳实践:

  • 合理选择分区键:选择查询频繁的列,避免选择更新频繁的列
  • 控制分区数量:根据数据量和服务器资源确定分区数量,一般建议每个分区大小在10-50GB之间
  • 避免数据倾斜:确保数据均匀分布到各个分区,from DB视频:www.itpux.com
  • 创建合适的索引:为分区表创建合适的索引,提高查询性能
  • 定期维护分区:定期添加新分区,删除或归档旧分区
  • 监控分区使用情况:定期监控分区的使用情况,及时调整分区策略
  • 考虑复合分区:对于复杂的数据分布场景,考虑使用复合分区
  • 测试分区性能:在生产环境部署前,进行充分的性能测试

5.2 金仓数据库分区常见问题

金仓数据库分区的常见问题及解决方案:


# 常见问题1:分区键选择不当
– 原因:选择了查询不频繁的列,或更新频繁的列
– 解决方案:重新选择合适的分区键
# 常见问题2:分区数量过多
– 原因:分区数量超过了服务器资源的承载能力
– 解决方案:合并部分分区,重新设计分区策略
# 常见问题3:数据倾斜
– 原因:分区键选择不当,或数据分布不均匀
– 解决方案:重新选择分区键,调整分区策略
# 常见问题4:分区维护操作失败
– 原因:权限不足,磁盘空间不足,或数据完整性问题
– 解决方案:检查权限,检查磁盘空间,检查数据完整性
# 常见问题5:分区索引失效
– 原因:索引设计不当,或索引损坏
– 解决方案:重建索引,检查索引设计

5.3 金仓数据库分区应用场景

金仓数据库分区的应用场景:

  • 时间序列数据:如日志、监控数据、交易记录等,使用范围分区按时间划分
  • 离散值数据:如地区、状态、类型等,使用列表分区按离散值划分
  • 均匀分布数据:如用户ID、订单ID等,使用哈希分区均匀分布
  • 大数据量表:如数据仓库中的事实表,使用分区提高查询性能
  • 历史数据管理:如归档历史数据,使用分区简化管理
风哥提示:分区是数据库性能优化的重要手段,合理的分区策略可以显著提高数据库的性能和可管理性。在设计分区时,应该根据数据的特点和查询模式选择合适的分区类型和分区策略,并定期进行维护和监控。

持续改进:分区策略的设计和优化是一个持续的过程,需要根据业务需求的变化和数据量的增长,不断调整和优化分区策略,以保持良好的性能和可用性。

本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html

联系我们

在线咨询:点击这里给我发消息

微信号:itpux-com

工作日:9:30-18:30,节假日休息