DolphinDB数据模型:表、分区与分布式表

目录

    • 摘要
    • 一、数据类型体系
      • [1.1 基本数据类型](#1.1 基本数据类型)
      • [1.2 数据类型详解](#1.2 数据类型详解)
        • [1.2.1 整数类型](#1.2.1 整数类型)
        • [1.2.2 时间类型](#1.2.2 时间类型)
        • [1.2.3 字符串类型](#1.2.3 字符串类型)
      • [1.3 类型转换](#1.3 类型转换)
    • 二、表结构设计
      • [2.1 内存表](#2.1 内存表)
      • [2.2 表操作](#2.2 表操作)
        • [2.2.1 插入数据](#2.2.1 插入数据)
        • [2.2.2 更新数据](#2.2.2 更新数据)
        • [2.2.3 删除数据](#2.2.3 删除数据)
      • [2.3 表连接](#2.3 表连接)
    • 三、分区策略
      • [3.1 分区概述](#3.1 分区概述)
      • [3.2 分区类型](#3.2 分区类型)
        • [3.2.1 VALUE分区](#3.2.1 VALUE分区)
        • [3.2.2 RANGE分区](#3.2.2 RANGE分区)
        • [3.2.3 HASH分区](#3.2.3 HASH分区)
        • [3.2.4 COMPO组合分区](#3.2.4 COMPO组合分区)
      • [3.3 分区选择策略](#3.3 分区选择策略)
    • 四、分布式表
      • [4.1 分布式表概述](#4.1 分布式表概述)
      • [4.2 创建分布式表](#4.2 创建分布式表)
      • [4.3 数据写入](#4.3 数据写入)
      • [4.4 数据查询](#4.4 数据查询)
      • [4.5 分区管理](#4.5 分区管理)
    • 五、工业物联网场景实践
      • [5.1 设备监控数据模型](#5.1 设备监控数据模型)
      • [5.2 数据写入优化](#5.2 数据写入优化)
      • [5.3 查询优化](#5.3 查询优化)
    • 六、最佳实践
      • [6.1 分区设计原则](#6.1 分区设计原则)
      • [6.2 数据类型选择](#6.2 数据类型选择)
      • [6.3 性能优化建议](#6.3 性能优化建议)
    • 七、常见问题
      • [7.1 分区不均匀](#7.1 分区不均匀)
      • [7.2 查询慢](#7.2 查询慢)
      • [7.3 写入失败](#7.3 写入失败)
    • 八、总结
    • 参考资料

摘要

本文深入讲解DolphinDB的核心数据模型,包括基本数据类型、表结构设计、分区策略和分布式表管理。从内存表到分布式表的演进,从单分区到多分区的策略选择,逐步带领读者掌握DolphinDB数据建模的核心技能。同时提供工业物联网场景下的最佳实践,帮助读者设计高效的数据存储方案。本文适合需要设计和优化DolphinDB数据存储架构的开发者阅读。


一、数据类型体系

1.1 基本数据类型

DolphinDB支持丰富的数据类型,满足工业物联网场景的各种需求:
数据类型
整数类型
INT
LONG
SHORT
CHAR
浮点类型
FLOAT
DOUBLE
时间类型
DATE
DATETIME
TIMESTAMP
TIME
MONTH
字符串类型
STRING
SYMBOL
其他类型
BOOL
UUID
IPADDR

1.2 数据类型详解

1.2.1 整数类型
类型 字节数 范围 适用场景
CHAR 1 -128 ~ 127 状态码、标志位
SHORT 2 -32,768 ~ 32,767 小范围数值
INT 4 -2^31 ~ 2^31-1 设备ID、计数器
LONG 8 -2^63 ~ 2^63-1 大数值、时间戳
1.2.2 时间类型
类型 格式 示例 适用场景
DATE YYYY-MM-DD 2024.01.01 日期存储
DATETIME YYYY-MM-DD HH:mm:ss 2024.01.01 12:00:00 日期时间
TIMESTAMP 精确到毫秒 2024.01.01T12:00:00.123 高精度时间
TIME HH:mm:ss.SSS 12:00:00.123 时间点
MONTH YYYY-MM 2024.01M 月度统计
1.2.3 字符串类型
类型 特点 适用场景
STRING 可变长度,存储任意字符串 描述信息、备注
SYMBOL 枚举型,存储重复值 设备名称、状态标签

SYMBOL类型优势

python 复制代码
// 使用STRING类型
t1 = table(`device1`device2`device1`device3 as device_name)

// 使用SYMBOL类型(推荐)
t2 = table(symbol(`device1`device2`device1`device3) as device_name)

// SYMBOL类型优势:
// 1. 存储空间更小(存储索引而非字符串)
// 2. 比较速度更快(整数比较)
// 3. 分组聚合更高效

1.3 类型转换

python 复制代码
// 显式类型转换
a = 123.456
b = int(a)          // 浮点转整数: 123
c = string(a)       // 转字符串: "123.456"
d = long(a)         // 转长整数: 123

// 时间类型转换
ts = now()                          // 当前时间戳
dt = date(ts)                       // 提取日期
tm = temporalParse(formatDateTime(ts, "HH:mm:ss"), "HH:mm:ss")  // 提取时间

// 字符串转时间
dateStr = "2024-01-15"
dateVal = temporalParse(dateStr, "yyyy-MM-dd")

二、表结构设计

2.1 内存表

内存表是DolphinDB最基本的数据结构,数据完全存储在内存中:

python 复制代码
// 创建空表
t = table(1:0, `id`name`value, [INT, STRING, DOUBLE])

// 创建带数据的表
t = table(1..10 as id, `device` + string(1..10) as name, rand(100.0, 10) as value)

// 查看表结构
schema(t)

// 查看数据
t

内存表特点:

特点 说明
速度快 全内存操作,毫秒级响应
易丢失 服务重启数据丢失
容量有限 受内存大小限制
适合场景 临时计算、中间结果

2.2 表操作

2.2.1 插入数据
python 复制代码
// 创建表
t = table(1:0, `device_id`timestamp`temperature`humidity, 
          [INT, TIMESTAMP, DOUBLE, DOUBLE])

// 方式1:使用tableInsert
tableInsert(t, 1, now(), 25.5, 50.0)

// 方式2:使用append!
t.append!(table(2 as device_id, now() as timestamp, 26.0 as temperature, 48.0 as humidity))

// 方式3:批量插入
data = table(1..100 as device_id, 
             take(now(), 100) as timestamp,
             rand(20..30, 100) as temperature,
             rand(40..60, 100) as humidity)
t.append!(data)

// 查看记录数
count(t)
2.2.2 更新数据
python 复制代码
// 更新单条记录
update t set temperature = 30.0 where device_id = 1

// 批量更新
update t set temperature = temperature + 1 where device_id < 50

// 条件更新
update t set humidity = humidity * 1.1 where temperature > 25
2.2.3 删除数据
python 复制代码
// 删除指定记录
delete from t where device_id = 1

// 批量删除
delete from t where temperature < 20

// 清空表
delete from t

2.3 表连接

DolphinDB支持多种表连接方式:
INNER JOIN
LEFT JOIN
FULL JOIN
CROSS JOIN
表A
连接类型
内连接
左连接
全连接
交叉连接
结果表

python 复制代码
// 创建测试表
devices = table(1..5 as device_id, `device` + string(1..5) as device_name)
readings = table(1 1 2 2 3 3 as device_id, 
                 now() + 1..6 as timestamp,
                 rand(20..30, 6) as temperature)

// 内连接
select * from lj(readings, devices, `device_id)

// 左连接
select * from lj(readings, devices, `device_id)

// 全连接
select * from fj(readings, devices, `device_id)

// 交叉连接
select * from cj(devices, table(1..3 as sensor_id))

三、分区策略

3.1 分区概述

分区是DolphinDB分布式存储的核心概念。合理的分区策略可以显著提升查询性能:
分区优势
并行查询
多节点同时处理
数据裁剪
只扫描相关分区
负载均衡
数据均匀分布
运维便利
分区级备份恢复

3.2 分区类型

3.2.1 VALUE分区

VALUE分区适用于枚举值查询场景:

python 复制代码
// 创建VALUE分区数据库
db = database("dfs://value_demo", VALUE, `device1`device2`device3`device4`device5)

// 创建分区表
t = table(1:0, `device_id`timestamp`value, [SYMBOL, TIMESTAMP, DOUBLE])
db.createPartitionedTable(t, `sensor_data, `device_id)

// 插入数据
data = table(take(`device1`device2`device3`device4`device5, 1000) as device_id,
             now() + 1..1000 as timestamp,
             rand(100.0, 1000) as value)
loadTable("dfs://value_demo", "sensor_data").append!(data)

// 查询(只扫描device1分区)
select count(*) from loadTable("dfs://value_demo", "sensor_data") where device_id = `device1

适用场景

  • 设备ID、地区等枚举值
  • 查询条件多为等值查询
  • 分区值数量有限
3.2.2 RANGE分区

RANGE分区适用于范围查询场景:

python 复制代码
// 创建RANGE分区数据库(按日期)
db = database("dfs://range_demo", RANGE, 2024.01.01..2024.12.31)

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

// 插入数据
data = table(2024.01.01 + rand(365, 10000) as timestamp,
             rand(1..100, 10000) as device_id,
             rand(100.0, 10000) as value)
loadTable("dfs://range_demo", "sensor_data").append!(data)

// 查询(只扫描1月分区)
select count(*) from loadTable("dfs://range_demo", "sensor_data") 
where timestamp between 2024.01.01 and 2024.01.31

适用场景

  • 时间范围查询
  • 数值范围查询
  • 数据按时间顺序写入
3.2.3 HASH分区

HASH分区适用于均匀分布场景:

python 复制代码
// 创建HASH分区数据库
db = database("dfs://hash_demo", HASH, [INT, 10])  // 10个分区

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

// 数据均匀分布在10个分区

适用场景

  • 数据分布不均匀
  • 需要负载均衡
  • 分区键值域很大
3.2.4 COMPO组合分区

COMPO分区支持多维度分区:

python 复制代码
// 创建组合分区数据库(日期 + 设备ID)
db = database("dfs://compo_demo", COMPO, 
              [RANGE, 2024.01.01..2024.03.31, VALUE, `device1`device2`device3])

// 创建分区表
t = table(1:0, `timestamp`device_id`value, [TIMESTAMP, SYMBOL, DOUBLE])
db.createPartitionedTable(t, `sensor_data, `timestamp`device_id)

// 查询时可以同时利用两个分区维度进行裁剪
select count(*) from loadTable("dfs://compo_demo", "sensor_data")
where timestamp between 2024.01.01 and 2024.01.31 and device_id = `device1

3.3 分区选择策略

场景 推荐分区类型 分区键 说明
设备监控 VALUE device_id 按设备分区
时间序列 RANGE timestamp 按时间范围
用户行为 HASH user_id 均匀分布
多维查询 COMPO date + device 组合分区

四、分布式表

4.1 分布式表概述

分布式表是DolphinDB的核心存储形式,数据分布在多个节点上:
分布式表架构
客户端
Controller
分区路由
DataNode1

分区1,4
DataNode2

分区2,5
DataNode3

分区3,6

4.2 创建分布式表

python 复制代码
// 创建分布式数据库
db = database("dfs://iot_demo", RANGE, 2024.01.01..2024.12.31)

// 定义表结构
schema = table(1:0, 
    `device_id`timestamp`temperature`humidity`pressure`status,
    [INT, TIMESTAMP, DOUBLE, DOUBLE, DOUBLE, SYMBOL])

// 创建分布式表
db.createPartitionedTable(schema, `sensor_data, `timestamp)

// 查看表结构
schema(loadTable("dfs://iot_demo", "sensor_data"))

4.3 数据写入

python 复制代码
// 批量写入
data = table(
    rand(1..100, 10000) as device_id,
    2024.01.01 + rand(365, 10000) as timestamp,
    rand(20.0..30.0, 10000) as temperature,
    rand(40.0..60.0, 10000) as humidity,
    rand(1000.0..1020.0, 10000) as pressure,
    take(`normal`warning`error, 10000) as status
)

loadTable("dfs://iot_demo", "sensor_data").append!(data)

// 验证写入
select count(*) from loadTable("dfs://iot_demo", "sensor_data")

4.4 数据查询

python 复制代码
// 基本查询
select * from loadTable("dfs://iot_demo", "sensor_data") limit 10

// 条件查询
select * from loadTable("dfs://iot_demo", "sensor_data")
where timestamp between 2024.01.01 and 2024.01.31
and device_id = 1

// 聚合查询
select device_id,
       avg(temperature) as avg_temp,
       max(temperature) as max_temp,
       min(temperature) as min_temp,
       count(*) as record_count
from loadTable("dfs://iot_demo", "sensor_data")
group by device_id

// 时间窗口聚合
select device_id,
       bar(timestamp, 1h) as hour,
       avg(temperature) as avg_temp
from loadTable("dfs://iot_demo", "sensor_data")
group by device_id, bar(timestamp, 1h)

4.5 分区管理

python 复制代码
// 查看分区信息
getPartitionScheme("dfs://iot_demo")

// 查看分区分布
getClusterChunksStatus()

// 查看表分区
getTabletsMeta("dfs://iot_demo", "sensor_data")

// 数据重平衡
rebalanceChunksAmongNodes()

五、工业物联网场景实践

5.1 设备监控数据模型

python 复制代码
// 创建设备监控数据库
db = database("dfs://device_monitor", COMPO,
    [RANGE, 2024.01.01..2024.12.31, VALUE, 1..1000])

// 设备实时数据表
realtime_schema = table(1:0,
    `device_id`timestamp`temperature`humidity`pressure`vibration`power`status,
    [INT, TIMESTAMP, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, SYMBOL])
db.createPartitionedTable(realtime_schema, `realtime_data, `timestamp`device_id)

// 设备告警表
alert_schema = table(1:0,
    `alert_id`device_id`timestamp`alert_type`alert_level`message`handled,
    [LONG, INT, TIMESTAMP, SYMBOL, INT, STRING, BOOL])
db.createPartitionedTable(alert_schema, `alerts, `timestamp`device_id)

// 设备信息表(维度表)
device_info = table(1:0,
    `device_id`device_name`location`device_type`install_date`manufacturer,
    [INT, STRING, STRING, SYMBOL, DATE, STRING])
db.createTable(device_info, `device_info)

5.2 数据写入优化

python 复制代码
// 批量写入函数
def batchWriteDeviceData(dbPath, tableName, data){
    t = loadTable(dbPath, tableName)
    t.append!(data)
    return count(data)
}

// 模拟实时数据写入
def generateDeviceData(deviceIds, startTime, numRecords){
    return table(
        take(deviceIds, numRecords) as device_id,
        startTime + 1..numRecords as timestamp,
        rand(20.0..30.0, numRecords) as temperature,
        rand(40.0..60.0, numRecords) as humidity,
        rand(1000.0..1020.0, numRecords) as pressure,
        rand(0.0..5.0, numRecords) as vibration,
        rand(100.0..500.0, numRecords) as power,
        take(`normal`warning`error, numRecords) as status
    )
}

// 批量写入测试
data = generateDeviceData(1..100, now(), 100000)
batchWriteDeviceData("dfs://device_monitor", "realtime_data", data)

5.3 查询优化

python 复制代码
// 查询最近1小时数据(利用分区裁剪)
select * from loadTable("dfs://device_monitor", "realtime_data")
where timestamp > now() - 3600000
and device_id in 1..10

// 设备状态统计
select device_id,
       count(*) as total_records,
       sum(iif(status == `error, 1, 0)) as error_count,
       sum(iif(status == `warning, 1, 0)) as warning_count,
       avg(temperature) as avg_temp,
       avg(humidity) as avg_humidity
from loadTable("dfs://device_monitor", "realtime_data")
where timestamp > today()
group by device_id

// 异常设备检测
select device_id, count(*) as error_count
from loadTable("dfs://device_monitor", "realtime_data")
where status == `error
and timestamp > now() - 3600000
group by device_id
having count(*) > 10
order by error_count desc

六、最佳实践

6.1 分区设计原则

原则 说明 示例
查询裁剪 分区键应为常用查询条件 按时间分区,时间范围查询
数据均匀 避免数据倾斜 HASH分区均匀分布
分区大小 单分区建议100MB-10GB 根据数据量调整分区粒度
写入性能 分区数不宜过多 避免小文件问题

6.2 数据类型选择

场景 推荐类型 原因
设备ID INT / SYMBOL 存储高效,查询快
时间戳 TIMESTAMP 精度高,支持时序函数
状态标签 SYMBOL 枚举值,压缩率高
数值测量 DOUBLE 精度足够,计算方便
描述信息 STRING 灵活存储

6.3 性能优化建议

性能优化
分区优化
查询优化
写入优化
合理分区键
分区大小适中
避免数据倾斜
利用分区裁剪
合理使用索引
避免全表扫描
批量写入
异步写入
写入缓存


七、常见问题

7.1 分区不均匀

python 复制代码
// 检查分区大小
select partition, count(*) as records
from getClusterChunksStatus()
group by partition
order by records desc

// 解决方案:使用HASH分区或调整分区粒度

7.2 查询慢

python 复制代码
// 查看执行计划
explain select * from loadTable("dfs://db", "table") where timestamp > now() - 3600000

// 优化建议:
// 1. 确保查询条件包含分区键
// 2. 添加适当的索引
// 3. 减少返回列数

7.3 写入失败

错误 原因 解决方案
分区不存在 数据超出分区范围 扩展分区范围
类型不匹配 数据类型不一致 检查数据类型
内存不足 批量写入过大 减小批次大小

八、总结

本文详细介绍了DolphinDB的数据模型。核心要点如下:

  1. 数据类型:丰富的数据类型体系,满足各种场景需求
  2. 表结构:内存表和分布式表的设计与操作
  3. 分区策略:VALUE、RANGE、HASH、COMPO四种分区类型
  4. 分布式表:创建、写入、查询、管理的完整流程
  5. 最佳实践:分区设计、类型选择、性能优化建议

思考题

  1. 在你的业务场景中,应该如何设计分区策略?
  2. 如何平衡查询性能和写入性能?
  3. 分布式表和内存表各有什么适用场景?

参考资料

相关推荐
ZC跨境爬虫2 小时前
纯requests+Redis实现分布式爬虫(可视化4终端,模拟4台电脑联合爬取)
redis·分布式·爬虫·python
rit843249916 小时前
单向拓扑结构下异构车辆排的分布式模型预测控制(DMPC)
分布式
我要用代码向我喜欢的女孩表白19 小时前
在spark集群上在部署一套spark环境,不要影响过去环境
大数据·分布式·spark
一念春风19 小时前
Qwen2.5 (AI模型 PC搭建)
人工智能·ai·c#·wpf·模型
2603_9547083120 小时前
多微电网系统架构:集群协同与能量互济的网络设计
网络·人工智能·分布式·物联网·架构·系统架构
8Qi821 小时前
RabbitMQ高级篇:消息可靠性、幂等性与延迟消息
java·分布式·微服务·中间件·rabbitmq·springcloud
互联网散修21 小时前
鸿蒙跨设备实时绘图同步:从零到一实现分布式画板
分布式·wpf·harmonyos
REDcker21 小时前
RabbitMQ系列03 - AMQP分层与协议流转
分布式·rabbitmq
一点 内容1 天前
Scrapy框架深度解析:高效构建分布式爬虫的实战指南
分布式·爬虫·scrapy