DolphinDB分区策略:HASH分区与COMPO分区

目录

    • 摘要
    • 一、HASH分区概述
      • [1.1 什么是HASH分区](#1.1 什么是HASH分区)
      • [1.2 HASH分区特点](#1.2 HASH分区特点)
      • [1.3 适用场景](#1.3 适用场景)
    • 二、创建HASH分区
      • [2.1 基本语法](#2.1 基本语法)
      • [2.2 创建INT类型HASH分区](#2.2 创建INT类型HASH分区)
      • [2.3 创建STRING类型HASH分区](#2.3 创建STRING类型HASH分区)
      • [2.4 创建SYMBOL类型HASH分区](#2.4 创建SYMBOL类型HASH分区)
    • 三、HASH分区查询
      • [3.1 查询特点](#3.1 查询特点)
      • [3.2 查询优化](#3.2 查询优化)
    • 四、COMPO组合分区
      • [4.1 什么是COMPO分区](#4.1 什么是COMPO分区)
      • [4.2 COMPO分区优势](#4.2 COMPO分区优势)
      • [4.3 创建COMPO分区](#4.3 创建COMPO分区)
      • [4.4 RANGE + HASH组合](#4.4 RANGE + HASH组合)
      • [4.5 VALUE + RANGE组合](#4.5 VALUE + RANGE组合)
    • 五、COMPO分区查询优化
      • [5.1 多维度分区裁剪](#5.1 多维度分区裁剪)
      • [5.2 查询性能对比](#5.2 查询性能对比)
    • 六、分区策略选择
      • [6.1 选择决策树](#6.1 选择决策树)
      • [6.2 策略对比](#6.2 策略对比)
      • [6.3 最佳实践](#6.3 最佳实践)
    • 七、实战案例
      • [7.1 工业物联网数据分区](#7.1 工业物联网数据分区)
      • [7.2 多租户SaaS数据分区](#7.2 多租户SaaS数据分区)
    • 八、总结
    • 参考资料

摘要

本文深入讲解DolphinDB HASH分区和COMPO组合分区策略。从HASH分区的均匀分布原理到COMPO分区的多维度设计,从分区创建到查询优化,全面介绍这两种分区策略的应用场景和最佳实践。通过丰富的代码示例,帮助读者掌握复杂场景下的分区设计技能。


一、HASH分区概述

1.1 什么是HASH分区

HASH分区通过对分区列的值进行哈希运算,将数据均匀分布到指定数量的分区中:
HASH分区原理
原始数据
哈希运算
分区1
分区2
分区3
分区4
数据均匀分布

1.2 HASH分区特点

特点 说明
均匀分布 数据自动均匀分布
分区固定 分区数量预先确定
适合高基数 适合值域很大的列
查询需扫描 精确查询需扫描所有分区

1.3 适用场景

场景 说明
高基数列 设备ID、用户ID等
均匀分布 需要数据均匀分布
写入优化 并行写入优化
组合分区 作为组合分区的子分区

二、创建HASH分区

2.1 基本语法

python 复制代码
// HASH分区语法
db = database("dfs://db_name", HASH, [data_type, bucket_count])

// 参数说明:
// - data_type: 分区列的数据类型
// - bucket_count: 哈希桶数量(分区数)

2.2 创建INT类型HASH分区

python 复制代码
// 按设备ID哈希分区(10个分区)
db = database("dfs://hash_db", HASH, [INT, 10])

// 创建分区表
schema = table(1:0,
    `device_id`timestamp`temperature`humidity,
    [INT, TIMESTAMP, DOUBLE, DOUBLE])
db.createPartitionedTable(schema, `sensor_data, `device_id)

// 插入数据
t = table(
    take(1..1000, 100000) as device_id,
    take(now(), 100000) as timestamp,
    rand(20.0..30.0, 100000) as temperature,
    rand(40.0..60.0, 100000) as humidity
)
loadTable("dfs://hash_db", "sensor_data").append!(t)

// 查看各分区数据量
select count(*) from t group by device_id % 10 as partition

2.3 创建STRING类型HASH分区

python 复制代码
// 按用户ID哈希分区
db = database("dfs://user_hash_db", HASH, [STRING, 20])

// 创建分区表
schema = table(1:0,
    `user_id`timestamp`action`value,
    [STRING, TIMESTAMP, SYMBOL, DOUBLE])
db.createPartitionedTable(schema, `user_action, `user_id)

2.4 创建SYMBOL类型HASH分区

python 复制代码
// 按设备名称哈希分区
db = database("dfs://symbol_hash_db", HASH, [SYMBOL, 50])

// 创建分区表
schema = table(1:0,
    `device_name`timestamp`status`value,
    [SYMBOL, TIMESTAMP, SYMBOL, DOUBLE])
db.createPartitionedTable(schema, `device_status, `device_name)

三、HASH分区查询

3.1 查询特点

python 复制代码
// HASH分区查询需要扫描所有分区
t = loadTable("dfs://hash_db", "sensor_data")

// 精确查询(扫描所有分区)
select * from t where device_id = 100

// 范围查询(扫描所有分区)
select * from t where device_id between 1 and 100

// 聚合查询
select count(*) from t

3.2 查询优化

python 复制代码
// HASH分区适合全量扫描场景
// 不适合精确查询场景

// 优化方案:使用组合分区
// 时间RANGE + 设备HASH
db = database("dfs://combo_hash_db", COMPO,
    [RANGE, 2024.01.01..2024.12.31,
     HASH, [INT, 10]])

// 这样可以按时间裁剪分区
select * from loadTable("dfs://combo_hash_db", "sensor_data")
where date(timestamp) = 2024.01.15 and device_id = 100

四、COMPO组合分区

4.1 什么是COMPO分区

COMPO分区是多种分区策略的组合,支持多维度分区:
COMPO组合分区
原始数据
第一层: 时间RANGE
第二层: 设备VALUE
分区1: 2024.01.01 + 设备1-10
分区2: 2024.01.01 + 设备11-20
分区3: 2024.01.02 + 设备1-10
分区4: 2024.01.02 + 设备11-20

4.2 COMPO分区优势

优势 说明
多维度 支持多列分区
灵活查询 支持多维度裁剪
均衡分布 数据分布更均匀
精细管理 分区管理更精细

4.3 创建COMPO分区

python 复制代码
// 时间RANGE + 设备VALUE组合分区
db = database("dfs://compo_db", COMPO,
    [RANGE, 2024.01.01..2024.12.31,  // 第一层:时间范围
     VALUE, 1..100])                  // 第二层:设备值

// 创建分区表
schema = table(1:0,
    `device_id`timestamp`temperature`humidity,
    [INT, TIMESTAMP, DOUBLE, DOUBLE])
db.createPartitionedTable(schema, `sensor_data, `timestamp`device_id)

// 插入数据
t = table(
    take(1..100, 100000) as device_id,
    take(2024.01.01T00:00:00 + 0..99999 * 600, 100000) as timestamp,
    rand(20.0..30.0, 100000) as temperature,
    rand(40.0..60.0, 100000) as humidity
)
loadTable("dfs://compo_db", "sensor_data").append!(t)

4.4 RANGE + HASH组合

python 复制代码
// 时间RANGE + 设备HASH组合分区
db = database("dfs://compo_hash_db", COMPO,
    [RANGE, 2024.01.01..2024.12.31,  // 第一层:时间范围
     HASH, [INT, 10]])                // 第二层:设备哈希

// 创建分区表
schema = table(1:0,
    `device_id`timestamp`temperature`humidity,
    [INT, TIMESTAMP, DOUBLE, DOUBLE])
db.createPartitionedTable(schema, `sensor_data, `timestamp`device_id)

4.5 VALUE + RANGE组合

python 复制代码
// 设备VALUE + 时间RANGE组合分区
db = database("dfs://compo_vr_db", COMPO,
    [VALUE, 1..100,                   // 第一层:设备值
     RANGE, 2024.01.01..2024.12.31])  // 第二层:时间范围

// 创建分区表
schema = table(1:0,
    `device_id`timestamp`temperature`humidity,
    [INT, TIMESTAMP, DOUBLE, DOUBLE])
db.createPartitionedTable(schema, `sensor_data, `device_id`timestamp)

五、COMPO分区查询优化

5.1 多维度分区裁剪

python 复制代码
// COMPO分区支持多维度裁剪
t = loadTable("dfs://compo_db", "sensor_data")

// 按时间裁剪(第一层)
select count(*) from t where date(timestamp) = 2024.01.15

// 按设备裁剪(第二层)
select count(*) from t where device_id = 50

// 双维度裁剪(最优)
select count(*) from t 
where date(timestamp) = 2024.01.15 and device_id = 50

// 查看执行计划
explain select * from t 
where date(timestamp) = 2024.01.15 and device_id = 50

5.2 查询性能对比

python 复制代码
// 性能对比测试
def testQueryPerformance() {
    t = loadTable("dfs://compo_db", "sensor_data")
    
    // 测试1:全表扫描
    timer {
        select count(*) from t
    }
    
    // 测试2:时间过滤
    timer {
        select count(*) from t where date(timestamp) = 2024.01.15
    }
    
    // 测试3:设备过滤
    timer {
        select count(*) from t where device_id = 50
    }
    
    // 测试4:双维度过滤
    timer {
        select count(*) from t 
        where date(timestamp) = 2024.01.15 and device_id = 50
    }
}

testQueryPerformance()

六、分区策略选择

6.1 选择决策树

按时间范围
按枚举值
均匀分布
多维度


时间
设备
选择分区策略
查询模式
RANGE分区
VALUE分区
HASH分区
COMPO分区
数据量
时间+其他组合
纯时间分区
第一层
RANGE + HASH/VALUE
VALUE + RANGE

6.2 策略对比

策略 适用场景 查询优势 写入优势
VALUE 离散值、低基数 精确匹配快 按值分布
RANGE 连续值、时间 范围查询快 按时间写入
HASH 高基数、均匀 全量扫描 并行写入
COMPO 多维度 多维度裁剪 灵活分布

6.3 最佳实践

场景 推荐策略 说明
物联网数据 RANGE + HASH 时间+设备
日志数据 RANGE + VALUE 时间+类型
交易数据 RANGE + HASH 时间+用户
监控数据 VALUE + RANGE 设备+时间

七、实战案例

7.1 工业物联网数据分区

python 复制代码
// 工业物联网数据:时间RANGE + 设备HASH
db = database("dfs://iot_compo", COMPO,
    [RANGE, 2024.01.01..2024.12.31,  // 按日分区
     HASH, [INT, 100]])               // 设备哈希100个桶

// 创建设备数据表
schema = table(1:0,
    `device_id`timestamp`temperature`humidity`pressure`vibration`power,
    [INT, TIMESTAMP, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE])
db.createPartitionedTable(schema, `device_data, `timestamp`device_id)

// 创建告警表
schema = table(1:0,
    `alert_id`device_id`timestamp`alert_type`alert_level`message,
    [LONG, INT, TIMESTAMP, SYMBOL, INT, STRING])
db.createPartitionedTable(schema, `alert_data, `timestamp`device_id)

// 模拟数据
def simulateIoTData(days, devices) {
    for (d in 0..(days-1)) {
        date = 2024.01.01 + d
        data = table(
            take(1..devices, devices * 100) as device_id,
            take(dateT00:00:00 + 0..(devices*100-1) * 864, devices * 100) as timestamp,
            rand(20.0..30.0, devices * 100) as temperature,
            rand(40.0..60.0, devices * 100) as humidity,
            rand(1000.0..1020.0, devices * 100) as pressure,
            rand(0.0..5.0, devices * 100) as vibration,
            rand(100.0..500.0, devices * 100) as power
        )
        loadTable("dfs://iot_compo", "device_data").append!(data)
    }
}

simulateIoTData(30, 1000)  // 30天,1000设备

// 查询某日某设备数据
select * from loadTable("dfs://iot_compo", "device_data")
where date(timestamp) = 2024.01.15 and device_id = 500
limit 10

7.2 多租户SaaS数据分区

python 复制代码
// 多租户数据:租户VALUE + 时间RANGE
tenants = `tenant_001`tenant_002`tenant_003`tenant_004`tenant_005
db = database("dfs://saas_compo", COMPO,
    [VALUE, tenants,                  // 租户分区
     RANGE, 2024.01.01..2024.12.31])  // 时间分区

// 创建订单表
schema = table(1:0,
    `tenant_id`order_id`timestamp`user_id`amount`status,
    [SYMBOL, STRING, TIMESTAMP, STRING, DOUBLE, SYMBOL])
db.createPartitionedTable(schema, `orders, `tenant_id`timestamp)

// 查询某租户某日订单
select * from loadTable("dfs://saas_compo", "orders")
where tenant_id = `tenant_001`
and date(timestamp) = 2024.01.15

八、总结

本文详细介绍了DolphinDB HASH分区和COMPO组合分区:

  1. HASH分区:均匀分布、高基数、写入优化
  2. COMPO分区:多维度、灵活查询、精细管理
  3. 组合策略:RANGE+HASH、RANGE+VALUE、VALUE+RANGE
  4. 查询优化:多维度分区裁剪
  5. 策略选择:根据查询模式和业务场景选择

思考题

  1. HASH分区和VALUE分区有什么区别?
  2. 什么时候应该使用COMPO组合分区?
  3. 如何设计物联网数据的分区策略?

参考资料

相关推荐
沪漂阿龙2 小时前
程序员面试技术爆款文:2026大厂算法通关手册——从零基础到LeetCode刷穿,这一篇就够了
算法·leetcode·面试
rit84324993 小时前
基于博弈论的小区分簇算法MATLAB实现
开发语言·算法·matlab
华清远见成都中心3 小时前
C 语言内存管理深度解析:malloc/free 与嵌入式堆栈分配策略
java·c语言·算法
一行代码一行诗++3 小时前
关系操作符
算法
生成论实验室4 小时前
《源·觉·知·行·事·物:生成论视域下的统一认知语法》第五章 事:行在时空中的具体化
人工智能·算法·架构·知识图谱·创业创新
Liangwei Lin4 小时前
LeetCode 283. 移动零
算法
Lenyiin4 小时前
《LeetCode 顺序刷题》61 - 70
java·c++·python·算法·leetcode·lenyiin
岁岁的O泡奶4 小时前
NSSCTF_crypto_[LitCTF 2023]babyLCG
经验分享·python·算法·密码学·crypto·流密码
Hesionberger4 小时前
LeetCode 78:子集生成全攻略
java·开发语言·数据结构·python·算法·leetcode·职场和发展