DolphinDB 用户入门指南之金融篇(2)

该页面是一篇教程文章,给出作者与发布日期信息,并概述“创建数据库和数据表”的章节主题。

Source: https://dolphindb.cn/blogs/137

What this page covers

技能认证特训营第二期报名入口 (cta)

页面顶部提供活动通知信息,并包含限时报名入口链接。

DolphinDB 用户入门指南之金融篇(2):创建数据库和数据表 (product_overview)

该部分给出文章标题、作者与发布日期,并概述本章围绕“创建数据库与数据表”的主题。

分布式架构与数据分区 (definition)

该部分介绍分布式表与分区的定义、集群节点角色分工,以及分布式查询与计算的基本机制。

设置合理分区 (how_it_works)

该部分解释分区的作用与粒度取舍,并介绍 VALUE/HASH/RANGE/LIST/COMPO 等分区方式、引擎选择与若干金融场景建议。

建库建表(SQL 示例) (how_it_works)

该部分以金融快照数据为例,演示用 SQL 创建数据库与分布式表、估算数据量并制定分区方案,以及写入与查询示例。

常见问题 (faq)

该部分集中说明分区与命名限制、库表字段改名支持情况、存储路径、宽窄表与维度表选择、对象类型存储限制、并发写入与删除/排错相关机制。

下一步阅读 (navigation)

该部分提供概念学习与实操最佳实践的延伸阅读入口。

Facts index

Entity Attribute Value Confidence
DolphinDB 用户入门指南之金融篇(2)发布日期2025-01-07high
DolphinDB 用户入门指南之金融篇(2)作者署名momohigh
DolphinDB 数据表存储分布式存储方式数据表按分区划分成小粒度数据块,分布式地存储在各个节点上;建库建表需要额外设置分区方案、存储引擎等更复杂参数medium
DolphinDB 分布式表定义分布式表是 DolphinDB 对用户开放的“接口”,指路径以“dfs://”开头的数据库下存储的表high
DolphinDB 分布式实现逻辑/物理属性分布式基于分布式文件系统实现,是逻辑概念而非物理多机存储;单服务器单节点也可创建分布式表high
DolphinDB 分区(partition)定义分布式表的数据按1个或多个维度在逻辑上分成很多部分,每个部分称为分区high
DolphinDB 分布式集群目的/收益用于保证高可用性、可扩展性并提升系统负载均衡medium
DolphinDB 控制节点(controller)高可用部署要求多个控制节点(至少3个)可以构成一个 raft 组,以实现高可用集群部署high
DolphinDB 控制节点(controller)职责负责集群监控与元数据管理;不参与数据存储与计算工作high
DolphinDB 数据节点(datanode)能力负责数据存储,同时也支持内存计算;分区可按设定包含固定数量副本并分散存储在数据节点上high
DolphinDB 计算节点(computenode)能力/限制只支持计算不支持存储,主要用于复杂且开销较大的计算任务high
DolphinDB 代理节点(agent node)作用每台物理机通过一个代理节点对其上部署的数据节点和计算节点进行管理high
单节点部署的 server 实例节点角色既是控制节点又是数据节点high
DolphinDB 分布式查询与计算核心框架以 map-reduce 框架为核心;查询下沉到各分区并行计算后汇总到发起节点,必要时基于汇总结果进一步 reducehigh
数据分区作用缩小查询范围(分区剪枝)、提高计算性能(并行处理)、提高可靠性与容错(复制/冗余与从副本恢复)、增强可扩展性(水平扩展)high
分区粒度过大影响单分区数据量大导致IO开销高;受 license 内存限制可能导致内存溢出、内存磁盘频繁切换等问题medium
分区粒度过小影响涉及分区多导致子任务数大、节点间通信成本增加;控制节点分区元数据可能“爆炸”导致内存不足;频繁读写小文件造成系统负荷过重medium
VALUE 分区机制用户指定分区字段的部分值(列表形式),数据按分区字段值分区,一个值对应一个分区high
DolphinDB 默认配置(安装包)newValuePartitionPolicy 默认值与行为newValuePartitionPolicy=add:写入不在值分区内的数据时,值分区可自动拓展high
VALUE 分区配置建议建议可只指定少量字段值以避免元数据过多(举例:指定2000.01.01..2030.01.01会造成分区元数据很大)medium
HASH 分区机制用户指定固定的 HASH 分区数;数据按分区字段值调用哈希函数 hashBucket 映射后分区,每个哈希值对应一个分区high
RANGE 分区机制与扩展方式用户指定分区范围;数据按分区字段值落入范围分区;不支持自动拓展,需手动调用 addRangePartitionshigh
LIST 分区金融场景使用情况实践中金融场景客户很少使用这种分区方式medium
COMPO 分区定义将多个字段的不同分区方案进行组合high
金融领域分区字段选择常见做法通常将时间字段作为分区字段;常用 VALUE 与 RANGE;示例:日K线按年RANGE、分钟K线按日VALUE;逐笔数据可用VALUE(日)+HASH(股票代码)的COMPO组合high
HASH 分区用途是灵活调整分区粒度的重要方式medium
调整分区粒度的方法降低分区粒度采用COMPO分区;增加分区个数;将RANGE分区改为VALUE分区high
调整分区粒度的方法增加分区粒度采用RANGE分区取代VALUE分区;HASH分区减小哈希映射数high
OLAP 引擎推荐分区大小(压缩前)100MB - 300MBhigh
TSDB/PKEY 引擎推荐分区大小(压缩前)400MB - 1GBhigh
DolphinDB 分布式存储引擎可选项TSDB、OLAP、PKEYhigh
TSDB 引擎与 OLAP 的差异(用户层面显著特点)除分区机制外,额外增加一层字段索引机制,更适用于大数据点查场景high
OLAP 存储适用场景较小数据量可继续用 OLAP 存储或存储为无分区维度表medium
PKEY 引擎适用场景对数据有主键约束需求可使用 PKEY 引擎存储high
股票数据分区方案示例表(表3-1)内容列出多类股票数据集的存储引擎、分区方案、分区列、排序列(如Level2/Level1快照、逐笔委托/成交、日K线、分钟K线等)high
Level2 快照(沪深分表)分区与引擎示例TSDB;按天VALUE分区 + 按股票代码HASH25分区;分区列:交易日期+股票代码;排序列:股票代码+交易时间high
Level1 快照(沪深合并)分区与引擎示例TSDB;按天VALUE分区 + 按股票代码HASH50分区;分区列:交易日期+股票代码;排序列:交易所类型+股票代码+交易时间high
日K线分区与引擎示例OLAP;按年RANGE分区;分区列:交易时间;排序列:无high
分钟K线分区与引擎示例OLAP;按天VALUE分区;分区列:交易时间;排序列:无high
分区方案指定时机规则分区方案在创建数据库时指定;指定后该数据库下的表将以该方案划分数据high
create database 示例示例代码与含义create database "dfs://stock_lv2_snapshot" partitioned by VALUE(2024.01.01..2024.01.02), HASH([SYMBOL, 50]), engine='TSDB':分区方案为按天VALUE + SYMBOL字段HASH 50;engine为TSDBhigh
TSDB 引擎参数 sortColumns性质排序列(sortColumns)是 TSDB 引擎特有参数,用于设置 TSDB 引擎的索引机制;OLAP 引擎无需指定排序列high
按年分区与时间精度限制与结论DolphinDB 事件类型精度最粗到月(如2021.01M);按年分区无法通过值分区实现,必须使用 RANGE 分区high
按年 RANGE 分区示例参考代码dataRange = 2020.01M + (0..10)*12; create database "dfs://year" partitioned by RANGE(dataRange)high
DolphinDB 建库建表方式方式可通过函数建库建表,也可使用 SQL;本教程以 SQL 编程示例high
沪深股票 Level2 快照(沪深合并)分区方案(表3-2)存储引擎与分区方案TSDB;按天分区 + 按股票代码 HASH50 分区high
示例数据库 stock_lv2_snapshot创建代码参数create database "dfs://stock_lv2_snapshot" partitioned by VALUE(2024.01.03..2024.01.04), HASH([SYMBOL, 50]), engine='TSDB'high
示例数据库 stock_lv2_snapshot重复试验的清理操作drop database if exists "dfs://stock_lv2_snapshot"(并提示同名库会被删除)high
模拟快照数据单日单只股票行数(示例)4802 行(tradeDate=2020.01.06, securityNumber=1)high
单行数据大小估算(方法一)计算结果1,556(B)high
单日单只股票数据量估算(方法一)结果7.12(MB)high
单行数据大小估算(方法二)计算结果(示例第一行memSize)1,728(B)high
单日单只股票数据量估算(方法二)结果7.9(MB)high
时间类型分区类型选择(TSDB 粒度与自动扩展)推荐RANGE 分区不支持自动拓展且范围外数据可能无法写入、需手动 addRangePartitions;因此对时间类型推荐使用可自动拓展的 VALUE 分区作为分区类型high
分区方案一(示例推导)方案描述与规模推导按日VALUE + 按股票字段HASH;若HASH桶数50,5000只股票每桶约100只,则单分区数据量约800MBmedium
分区方案二(示例推导)方案描述与桶数范围按月VALUE + 按股票字段HASH;为满足需求每桶股票数为3或4,则HASH桶数为1250~1666medium
分区方案二(按月VALUE + HASH)局限性HASH桶数过多且每桶仅3~4只股票;快照按日检索高频,按月分区性能不如按日;一般不按HASH值查询,HASH更多用于降低分区粒度medium
最终选择的分区方案(示例结论)结论选择方案一:按天分区 + 按股票代码 HASH 50 分区high
DolphinDB SQL 建表语法可配置项(示例列举)支持 partitioned by(分区列)、sortColumns(排序列)、keepDuplicates、sortKeyMappingFunction、softDelete、comment 等配置(部分为引擎专属)high
示例分布式表 snapshot(dfs://stock_lv2_snapshot)分区列与排序列(表3-3/代码)分区列:TradeDate、SecurityID;sortColumns:['SecurityID','TradeTime'];keepDuplicates=ALLhigh
示例分布式表 snapshot(dfs://stock_lv2_snapshot)建表方式(分布式表命名)create table 语句中表名使用 dbPath.tbName(数据库名.数据表名)的形式以支持分布式表high
DolphinDB ARRAY 类型字段类型与用途INT[], LONG[], DOUBLE[] 为 DolphinDB 特有 ARRAY 类型(数组向量字段),用于存储可变长度二维数组high
写入示例脚本(snapshot 表)交易日历与写入结果(示例输出)getMarketCalendar('XSHE', 2022.01.01, 2022.01.10) 返回5个交易日;每个job写入返回 [480200,...];最终 exec count(*) 为 2401000high
按年分区(FAQ)限制DolphinDB 不支持年这一数据类型,因此无法按年进行值分区;按年分区需使用 RANGE 分区high
按年 RANGE 分区示例(FAQ)示例脚本create database "dfs://yearDB" partitioned by RANGE(date(2010.01M+12*1..10)), engine='TSDB'high
修改分区方案(FAQ)是否支持建库建表完成后不支持直接修改分区方案;最佳做法是新建库表并迁移数据后删除旧库表high
分区方案迁移(FAQ)迁移方法可借助 mr + repartitionDS 进行数据迁移;示例中先创建新库 dfs://stock_lv2_snapshot_1,再对原表做 repartitionDS 并用 mr 写入新表,最后删除旧库high
repartitionDS限制repartitionDS 只能按照一个字段重新分区(示例选择 TradeDate 字段以避免写入分区冲突)high
社区版默认配置迁移数据可能报错可能报错:The size of the write table cannot exceed the size of cacheEngine 或 Out of Memory;建议调整写入粒度(如按日拆分、parallel=false等)high
表字段命名规范(FAQ)规则创建表时列名必须由中文或英文字母、数字或下划线组成,且必须以中文或英文字母开头high
特殊列名产生场景(FAQ)示例可通过 as 取别名、addColumn 添加列、pivot by 行列转换产生不满足命名规范的特殊列名(给出示例代码与输出)high
修改数据库名、表名、字段名(FAQ)支持情况不支持修改数据库名;可用 renameTable 与 rename! 修改表名和字段名;但 TSDB 引擎存储的分布式表不支持对字段改名、修改值和删除操作high
dfs:// 路径(FAQ)含义“dfs://”用于声明数据库类型为分布式数据库;另有“oltp://”用于声明在线事务处理数据库high
dfs:// 数据库存储路径(FAQ)存储位置规则所有“dfs://”开头数据库的数据都存储在 volumes 参数配置路径下,可通过 getConfig("volumes") 查看high
volumes 默认目录(FAQ)单节点/集群默认值单节点默认:<HomeDir>/storage;集群默认:<HomeDir>/<nodeAlias>/storagehigh
宽表 vs 窄表(FAQ)适用性对比宽表:截面计算便捷、写入速度更优但字段级增删改开销大;窄表:记录级增删改便捷但截面计算不便需pivot转宽表high
中高频因子存储(FAQ)建议因增删因子操作频繁,综合性能考虑窄表优于宽表(并建议参考相关最佳实践教程评估)medium
维度表(dimension table)定义维度表实质是持久化且不进行分区的表high
分布式表 vs 维度表(FAQ)选择建议数据量较小且需要持久化推荐维度表;否则推荐分布式表medium
表中存储对象类型(FAQ)不支持项与替代方案不支持存储字典;类似json可用BLOB超长字符串存储;表中只能存储数组向量、列式元组(仅内存表)等类型强一致的二维对象,不支持超过二维或类型不一致二维数组存储high
并发写入同一分区(FAQ)默认限制与报错原因默认不允许对同一分区并发写入,否则造成分区冲突并报错:filepath xxx has been owned by transactionhigh
atomic='CHUNK'(FAQ)作用与风险创建数据库时配置 atomic='CHUNK' 可允许多线程并发写入同一分区;但不能完全保证事务原子性,可能部分分区写入成功而部分失败;采用重试机制可能导致写入较慢high
删除数据库/分区事务(FAQ)事务与回滚删除数据库(dropDatabase)或删除分区(dropParition)失败时系统会自动回滚事务high
删除数据时报错 deleteSubChunks failed(FAQ)原因概述在数据节点删除数据时找不到对应 chunk 分区信息会产生相关报错(示例:path does not exist;chunk not in COMPLETE state)medium
删除数据报错排查思路(FAQ)排查步骤控制节点用 getClusterChunksStatus 查看分区状态并关注 version/state/replicaCount;数据节点用 pnodeRun(getAllChunks{"/dbName%"}) 统计副本数并核对 version/state;检查控制/数据节点版本与副本一致性并确认 chunk 为 COMPLETEhigh
强制删除恢复中的分区(FAQ)脚本use ops; dropRecoveringPartitions(dbPath="dfs://xxx", tableName="zzz")(tableName可选)high
问题升级建议(FAQ)建议做法若排查得到分区不一致,建议截图上述信息提交给官方进行排查medium
下一步阅读推荐链接主题概念:数据分区、分布式事务;实操:存储金融数据的分区方案最佳实践、中高频多因子库存储最佳实践high