1. 概述
对数据库进行合理的分区能够明显下降体系呼应推迟,进步数据吞吐量。合理的分区规划需要归纳考虑数据分布的特征、查询和核算的典型场景、数据更新的频率等方方面面。
本文为入门级教程,针对几种常见的金融数据给出了较为通用的分区计划和示例脚本,以帮助初度体验 DolphinDB 的用户快速完成建库建表。
本文扩展阅读:
2. 数据存储计划总览
存储计划包括金融数据存储计划和因子库存储计划两大部分。
2.1 金融数据存储计划
针对不同金融数据,给出以下的分区存储计划:
2.2 因子库窄表存储计划
因子发掘是量化买卖的必备环节之一。随着量化买卖和AI模型训练规划的发展,量化出资团队在投研环节必然需要处理很多因子数据。因子的存储也是一个关键问题,本文推荐运用窄表存储因子库。
(窄表存储模型)
(宽表存储模型)
相较于宽表,窄表存储有以下优势:
-
愈加高效地删去过期失效因子
- 宽表的计划是删去全表的某一列,相比窄表计划功率低下
-
愈加高效地增加新因子
- 宽表的计划是先增加列,然后更新新增列的值,相比窄表计划功率低下
-
愈加高效地依照因子名更新指定因子的值
- 宽表的计划是 update 全表的某一列,相比窄表功率低下
-
单次多因子面板数据的查询功率和宽表近似
- DolphinDB 经过对 pivot by 办法的并行优化,确保了窄表存储计划的多因子数据查询功率
针对不同频率的因子数据,给出以下的分区存储计划,均选用 TSDB 存储引擎:
3. 金融数据存储计划实践
依据上一章的分区计划,本章将供给对应的 DolphinDB 脚本。
3.1 股票数据
3.1.1 Levle-2 行情数据
股票 Levle-2 行情数据包括 Levle-2 快照数据、逐笔托付数据、逐笔成交数据,由于在分布式数据库中,如果多个分区的数据表要连接(join)通常非常耗时,由于涉及到的分区可能在不同的节点上,需要在不同节点之间仿制数据。为处理这个问题,DolphinDB 推出了共存储方位的分区机制,确保同一个分布式数据库里一切表在相同分区的数据存储在相同的节点上。这样的安排,确保了这些表在连接的时候非常高效。因而在本计划中,把 Levle-2 快照数据、逐笔托付数据、逐笔成交数据这些分区计划共同的数据表存入同一个数据库中。
上交所和深交所两个买卖所的数据在字段结构上略有不同,用户在树立库表时能够考虑是否将两个买卖所的数据进行兼并,如果选择存为一张表,则表中的字段是两个买卖所数据字段的并集,并新增字段 Market 用于标识数据来自哪个买卖所。level-1 的分区计划选用 level-2 的即可。
如果您希望将通联数据导入 DolphinDB 数据库,能够参考如下教程,运用封装好的模块即可完成建库建表和 level-2 行情数据导入:
下面将依据是否将沪深买卖所分隔存储介绍不同建库建表的分区规矩。
3.1.1.1 Levle-2快照(沪深分表)
深交所
create database "dfs://split_SZ_TB"
partitioned by VALUE(2020.01.01..2021.01.01), HASH([SYMBOL, 25])
engine='TSDB'
create table "dfs://split_SZ_TB"."split_SZ_snapshotTB"(
TradeTime TIMESTAMP[comment="时刻列", compress="delta"]
MDStreamID SYMBOL
SecurityID SYMBOL
SecurityIDSource SYMBOL
TradingPhaseCode SYMBOL
PreCloPrice DOUBLE
NumTrades LONG
TotalVolumeTrade LONG
TotalValueTrade DOUBLE
LastPrice DOUBLE
OpenPrice DOUBLE
HighPrice DOUBLE
LowPrice DOUBLE
DifPrice1 DOUBLE
DifPrice2 DOUBLE
PE1 DOUBLE
PE2 DOUBLE
PreCloseIOPV DOUBLE
IOPV DOUBLE
TotalBidQty LONG
WeightedAvgBidPx DOUBLE
TotalOfferQty LONG
WeightedAvgOfferPx DOUBLE
UpLimitPx DOUBLE
DownLimitPx DOUBLE
OpenInt INT
OptPremiumRatio DOUBLE
OfferPrice DOUBLE[]
BidPrice DOUBLE[]
OfferOrderQty LONG[]
BidOrderQty LONG[]
BidNumOrders INT[]
OfferNumOrders INT[]
LocalTime TIME
SeqNo INT
OfferOrders LONG[]
BidOrders LONG[]
)
partitioned by TradeTime, SecurityID,
sortColumns=[`SecurityID,`TradeTime],
keepDuplicates=ALL
Levle-2行情数据运用”时刻维度按天 股票维度 HASH25”的分区规矩,运用存储引擎TSDB,运用“股票代码 买卖时刻”作为排序列。下面对上述脚本进行说明:
- TSDB 引擎只支撑创立分布式数据库,库名前必须增加”dfs://”;
- 在此处树立分区表时对某些列运用了指定紧缩算法,对TradeTime列运用了“delta”紧缩算法,其他列则默许运用“lz4”紧缩算法;
- 建表时指定 OfferPrice 为 DOUBLE[] 类型, 表明将 10 档卖价数据存储在一个字段中,该字段类型为 DOUBLE 类型的数组向量(arrray vector),更详细的 array vector 介绍见:DolphinDB 中有关 array vector 的最佳实践指南;
- sortColumns 参数用于将写入的数据依照指定字段进行排序,体系默许 sortColumns (指定多列时) 最终一列为时刻列,其他列字段作为排序的索引列,称作 sort key。频繁查询的字段适合设置为 sortColumns,且主张优先把查询频率高的字段作为 sortColumns 中方位靠前的列;
- keepDuplicates 参数表明在每个分区内怎么处理一切 sortColumns 之值皆相同的数据,在两个函数中该参数的值均为“ALL”表明保留一切数据。
上交所
create database "dfs://split_SH_TB"
partitioned by VALUE(2020.01.01..2021.01.01), HASH([SYMBOL, 25])
engine='TSDB'
create table "dfs://split_SH_TB"."split_SH_snapshotTB"(
TradeTime TIMESTAMP[comment="时刻列", compress="delta"]
SecurityID SYMBOL
ImageStatus INT
PreCloPrice DOUBLE
OpenPrice DOUBLE
HighPrice DOUBLE
LowPrice DOUBLE
LastPrice DOUBLE
ClosePrice DOUBLE
TradingPhaseCode SYMBOL
NumTrades LONG
TotalVolumeTrade LONG
TotalValueTrade DOUBLE
TotalBidQty LONG
WeightedAvgBidPx DOUBLE
AltWAvgBidPri DOUBLE
TotalOfferQty LONG
WeightedAvgOfferPx DOUBLE
AltWAvgAskPri DOUBLE
ETFBuyNumber INT
ETFBuyAmount LONG
ETFBuyMoney DOUBLE
ETFSellNumber INT
ETFSellAmount LONG
ETFSellMoney DOUBLE
YieldToMatu DOUBLE
TotWarExNum DOUBLE
UpLimitPx DOUBLE
DownLimitPx DOUBLE
WithdrawBuyNumber INT
WithdrawBuyAmount LONG
WithdrawBuyMoney DOUBLE
WithdrawSellNumber INT
WithdrawSellAmount LONG
WithdrawSellMoney DOUBLE
TotalBidNumber INT
TotalOfferNumber INT
MaxBidDur INT
MaxSellDur INT
BidNum INT
SellNum INT
IOPV DOUBLE
OfferPrice DOUBLE[]
BidPrice DOUBLE[]
OfferOrderQty LONG[]
BidOrderQty LONG[]
BidNumOrders INT[]
OfferNumOrders INT[]
LocalTime TIME
SeqNo INT
OfferOrders LONG[]
BidOrders LONG[]
)
partitioned by TradeTime, SecurityID,
sortColumns=[`SecurityID,`TradeTime],
keepDuplicates=ALL
上交所的数据格式与深交所略有不同,但分区计划共同。
3.1.1.2 逐笔托付(沪深分表)
深交所
create database "dfs://split_SZ_TB"
partitioned by VALUE(2020.01.01..2021.01.01), HASH([SYMBOL, 25])
engine='TSDB'
create table "dfs://split_SZ_TB"."split_SZ_entrustTB"(
ChannelNo INT
ApplSeqNum LONG
MDStreamID SYMBOL
SecurityID SYMBOL
SecurityIDSource SYMBOL
Price DOUBLE
OrderQty LONG
Side SYMBOL
TradeTime TIMESTAMP[comment="时刻列", compress="delta"]
OrderType SYMBOL
LocalTime TIME
SeqNo INT
)
partitioned by TradeTime, SecurityID,
sortColumns=[`SecurityID,`TradeTime],
keepDuplicates=ALL
用户能够运用上述代码以创立存储深交所逐笔托付数据的数据库表,分区规矩选用了“时刻维度按日 股票代码HASH25”的组合分区方法存储,运用存储引擎TSDB, 运用 “股票代码 买卖时刻” 作为排序列。
上交所
create database "dfs://split_SH_TB"
partitioned by VALUE(2020.01.01..2021.01.01), HASH([SYMBOL, 25])
engine='TSDB'
create table "dfs://split_SH_TB"."split_SH_entrustTB"(
DataStatus INT
ApplSeqNum LONG
ChannelNo INT
SecurityID SYMBOL
TradeTime TIMESTAMP[comment="时刻列", compress="delta"]
OrderType SYMBOL
OrderNO INT
Price DOUBLE
OrderQty LONG
Side SYMBOL
BizIndex INT
LocalTime TIME
SeqNo INT
)
partitioned by TradeTime, SecurityID,
sortColumns=[`SecurityID,`TradeTime],
keepDuplicates=ALL
上交所的数据格式与深交所略有不同,但分区计划共同。
3.1.1.3 逐笔成交(沪深分表)
深交所
create database "dfs://split_SZ_TB"
partitioned by VALUE(2020.01.01..2021.01.01), HASH([SYMBOL, 25])
engine='TSDB'
create table "dfs://split_SZ_TB"."split_SZ_tradeTB"(
ChannelNo INT
ApplSeqNum LONG
MDStreamID SYMBOL
BidApplSeqNum LONG
OfferApplSeqNum LONG
SecurityID SYMBOL
SecurityIDSource SYMBOL
TradePrice DOUBLE
TradeQty INT
ExecType SYMBOL
TradeTime TIMESTAMP[comment="时刻列", compress="delta"]
LocalTime TIME
SeqNo INT
OrderKind SYMBOL
)
partitioned by TradeTime, SecurityID,
sortColumns=[`SecurityID,`TradeTime],
keepDuplicates=ALL
用户能够运用上述代码以创立存储深交所逐笔托付数据的数据库表,分区规矩选用了“时刻维度按日 股票代码HASH25”的组合分区方法存储,运用存储引擎TSDB,运用“股票代码 买卖时刻”作为排序列。
上交所
create database "dfs://split_SH_TB"
partitioned by VALUE(2020.01.01..2021.01.01), HASH([SYMBOL, 25])
engine='TSDB'
create table "dfs://split_SH_TB"."split_SH_tradeTB"(
DataStatus INT
ApplSeqNum INT
ChannelNo INT
SecurityID SYMBOL
TradeTime TIMESTAMP[comment="时刻列", compress="delta"]
TradePrice DOUBLE
TradeQty LONG
TradeMoney DOUBLE
BidApplSeqNum LONG
OfferApplSeqNum LONG
TradeBSFlag SYMBOL
BizIndex LONG
LocalTime TIME
SeqNo INT
)
partitioned by TradeTime, SecurityID,
sortColumns=[`SecurityID,`TradeTime],
keepDuplicates=ALL
上交所的数据格式与深交所略有不同,但分区计划共同。
3.1.1.4 Levle-2快照(沪深兼并)
create database "dfs://merge_TB"
partitioned by VALUE(2020.01.01..2021.01.01), HASH([SYMBOL, 50])
engine='TSDB'
create table "dfs://merge_TB"."merge_snapshotTB"(
Market SYMBOL
TradeTime TIMESTAMP[comment="时刻列", compress="delta"],
MDStreamID SYMBOL
SecurityID SYMBOL
SecurityIDSource SYMBOL
TradingPhaseCode SYMBOL
ImageStatus INT
PreCloPrice DOUBLE
NumTrades LONG
TotalVolumeTrade LONG
TotalValueTrade DOUBLE
LastPrice DOUBLE
OpenPrice DOUBLE
HighPrice DOUBLE
LowPrice DOUBLE
ClosePrice DOUBLE
DifPrice1 DOUBLE
DifPrice2 DOUBLE
PE1 DOUBLE
PE2 DOUBLE
PreCloseIOPV DOUBLE
IOPV DOUBLE
TotalBidQty LONG
WeightedAvgBidPx DOUBLE
AltWAvgBidPri DOUBLE
TotalOfferQty LONG
WeightedAvgOfferPx DOUBLE
AltWAvgAskPri DOUBLE
UpLimitPx DOUBLE
DownLimitPx DOUBLE
OpenInt INT
OptPremiumRatio DOUBLE
OfferPrice DOUBLE[]
BidPrice DOUBLE[]
OfferOrderQty LONG[]
BidOrderQty LONG[]
BidNumOrders INT[]
OfferNumOrders INT[]
ETFBuyNumber INT
ETFBuyAmount LONG
ETFBuyMoney DOUBLE
ETFSellNumber INT
ETFSellAmount LONG
ETFSellMoney DOUBLE
YieldToMatu DOUBLE
TotWarExNum DOUBLE
WithdrawBuyNumber INT
WithdrawBuyAmount LONG
WithdrawBuyMoney DOUBLE
WithdrawSellNumber INT
WithdrawSellAmount LONG
WithdrawSellMoney DOUBLE
TotalBidNumber INT
TotalOfferNumber INT
MaxBidDur INT
MaxSellDur INT
BidNum INT
SellNum INT
LocalTime TIME
SeqNo INT
OfferOrders LONG[]
BidOrders LONG[]
)
partitioned by TradeTime, SecurityID,
sortColumns=[`Market,`SecurityID,`TradeTime],
keepDuplicates=ALL
用户能够运用上述代码树立一起存储沪深Levle-2行情数据的数据库表,运用”时刻维度按天 股票维度 HASH50”的分区规矩,运用存储引擎TSDB, 运用 “买卖所类型 股票代码 买卖时刻” 作为排序列。与沪深分隔存储的建库建表的分区规矩相似,仅在HASH数量和排序列方面有所区别。
3.1.1.5 逐笔托付(沪深兼并)
create database "dfs://merge_TB"
partitioned by VALUE(2020.01.01..2021.01.01), HASH([SYMBOL, 50])
engine='TSDB'
create table "dfs://merge_TB"."merge_entrustTB"(
ChannelNo INT
ApplSeqNum LONG
MDStreamID SYMBOL
SecurityID SYMBOL
SecurityIDSource SYMBOL
Price DOUBLE
OrderQty LONG
Side SYMBOL
TradeTime TIMESTAMP[comment="时刻列", compress="delta"]
OrderType SYMBOL
LocalTime TIME
SeqNo LONG
OrderNO LONG
DataStatus INT
BizIndex LONG
Market SYMBOL
)
partitioned by TradeTime, SecurityID,
sortColumns=[`Market,`SecurityID,`TradeTime],
keepDuplicates=ALL
用户能够运用上述代码树立一起存储沪深Levle-2行情数据的数据库表,运用”时刻维度按天 股票维度 HASH50”的分区规矩,运用存储引擎TSDB,运用 “买卖所类型 股票代码 买卖时刻” 作为排序列。与沪深分隔存储的建库建表的分区规矩相似,仅在HASH数量和排序列方面有所区别。
3.1.1.6 逐笔成交(沪深兼并)
create database "dfs://merge_TB"
partitioned by VALUE(2020.01.01..2021.01.01), HASH([SYMBOL, 50])
engine='TSDB'
create table "dfs://merge_TB"."merge_tradeTB"(
ChannelNo INT
ApplSeqNum LONG
MDStreamID SYMBOL
BidApplSeqNum LONG
OfferApplSeqNum LONG
SecurityID SYMBOL
SecurityIDSource SYMBOL
TradePrice DOUBLE
TradeQty LONG
ExecType SYMBOL
TradeTime TIMESTAMP[comment="时刻列", compress="delta"]
LocalTime TIME
SeqNo LONG
DataStatus INT
TradeMoney DOUBLE
TradeBSFlag SYMBOL
BizIndex LONG
OrderKind SYMBOL
Market SYMBOL
)
partitioned by TradeTime, SecurityID,
sortColumns=[`Market,`SecurityID,`TradeTime],
keepDuplicates=ALL
用户能够运用上述代码树立一起存储沪深Levle-2行情数据的数据库表,运用”时刻维度按天 股票维度 HASH50”的分区规矩,运用存储引擎TSDB,运用 “买卖所类型 股票代码 买卖时刻” 作为排序列。与沪深分隔存储的建库建表的分区规矩相似,仅在HASH数量和排序列方面有所区别。
3.1.2 股票日K数据
create database "dfs://k_day_level"
partitioned by RANGE(2000.01M (0..30)*12)
engine='OLAP'
create table "dfs://k_day_level"."k_day"(
securityid SYMBOL
tradetime TIMESTAMP
open DOUBLE
close DOUBLE
high DOUBLE
low DOUBLE
vol INT
val DOUBLE
vwap DOUBLE
)
partitioned by tradetime
用户能够运用上述代码树立一起存储日K的数据库表,运用”时刻维度按年”的分区规矩,运用存储引擎OLAP。每个分区内都包括了这一年一切股票的日K数据。
3.1.3 股票分钟 K 数据
create database "dfs://k_minute_level"
partitioned by VALUE(2020.01.01..2021.01.01)
engine='OLAP'
create table "dfs://k_minute_level"."k_minute"(
securityid SYMBOL
tradetime TIMESTAMP
open DOUBLE
close DOUBLE
high DOUBLE
low DOUBLE
vol INT
val DOUBLE
vwap DOUBLE
)
partitioned by tradetime
用户能够运用上述代码树立一起存储日K的数据库表,运用”时刻维度按天”的分区规矩,存储引擎运用OLAP。每个分区内都包括了当天一切股票的分钟K数据。
3.2 期权数据
3.2.1 期权快照数据
create database "dfs://ctp"
partitioned by VALUE(2020.01.01..2021.01.01), HASH([SYMBOL, 20])
engine='TSDB'
create table "dfs://ctp"."options"(
TradingDay DATE[comment="时刻列", compress="delta"]
ExchangeID SYMBOL
LastPrice DOUBLE
PreSettlementPrice DOUBLE
PreClosePrice DOUBLE
PreOpenInterest DOUBLE
OpenPrice DOUBLE
HighestPrice DOUBLE
LowestPrice DOUBLE
Volume INT
Turnover DOUBLE
OpenInterest DOUBLE
ClosePrice DOUBLE
SettlementPrice DOUBLE
UpperLimitPrice DOUBLE
LowerLimitPrice DOUBLE
PreDelta DOUBLE
CurrDelta DOUBLE
UpdateTime SECOND
UpdateMillisec INT
BidPrice DOUBLE[]
BidVolume INT[]
AskPrice DOUBLE[]
AskVolume INT[]
AveragePrice DOUBLE
ActionDay DATE
InstrumentID SYMBOL
ExchangeInstID STRING
BandingUpperPrice DOUBLE
BandingLowerPrice DOUBLE
tradeTime TIME
receivedTime NANOTIMESTAMP
perPenetrationTime LONG
)
partitioned by TradingDay, InstrumentID,
sortColumns=[`InstrumentID,`ReceivedTime],
keepDuplicates=ALL
用户能够运用上述代码以创立存储期权快照数据的数据库表,分区规矩选用了“时刻维度按天 期权代码维度 HASH20”的组合分区方法存储,运用存储引擎TSDB,运用 “期权代码 接收时刻” 作为排序列。经测验期货快照数据选用这种方法分区存储,归纳功能最佳。
3.3 期货数据
3.3.1 期货快照数据
create database "dfs://ctp"
partitioned by VALUE(2020.01.01..2021.01.01), HASH([SYMBOL, 10])
engine='TSDB'
create table "dfs://ctp"."futures"(
TradingDay DATE[comment="时刻列", compress="delta"]
ExchangeID SYMBOL
LastPrice DOUBLE
PreSettlementPrice DOUBLE
PreClosePrice DOUBLE
PreOpenInterest DOUBLE
OpenPrice DOUBLE
HighestPrice DOUBLE
LowestPrice DOUBLE
Volume INT
Turnover DOUBLE
OpenInterest DOUBLE
ClosePrice DOUBLE
SettlementPrice DOUBLE
UpperLimitPrice DOUBLE
LowerLimitPrice DOUBLE
PreDelta DOUBLE
CurrDelta DOUBLE
UpdateTime SECOND
UpdateMillisec INT
BidPrice DOUBLE[]
BidVolume INT[]
AskPrice DOUBLE[]
AskVolume INT[]
AveragePrice DOUBLE
ActionDay DATE
InstrumentID SYMBOL
ExchangeInstID STRING
BandingUpperPrice DOUBLE
BandingLowerPrice DOUBLE
tradeTime TIME
receivedTime NANOTIMESTAMP
perPenetrationTime LONG
)
partitioned by TradingDay, InstrumentID,
sortColumns=[`InstrumentID,`ReceivedTime],
keepDuplicates=ALL
用户能够运用上述代码以创立存储期货快照数据的数据库表,分区规矩选用了“时刻维度按天 期货代码维度 HASH10”的组合分区方法存储,运用存储引擎TSDB,运用 “期货代码 接收时刻” 作为排序列。经测验期货快照数据选用这种方法分区存储,归纳功能最佳。
3.3.2 期货日 K 数据
由于期货K数据与股票K数据相似,因而能够运用股票K数据的表格结构作为期货K数据的表格结构
create database "dfs://ctp_k_day_level"
partitioned by RANGE(2000.01M (0..30)*12)
engine='OLAP'
create table "dfs://ctp_k_day_level"."ctp_k_day"(
securityid SYMBOL
tradetime TIMESTAMP
open DOUBLE
close DOUBLE
high DOUBLE
low DOUBLE
vol INT
val DOUBLE
vwap DOUBLE
)
partitioned by tradetime
用户能够运用上述代码以创立存储期货日K数据的数据库表,与股票日K数据的分区规矩相同,运用”时刻维度按年”的分区规矩,存储引擎运用OLAP。在一个分区中包括了这一年一切期货的日K数据。
3.3.3 期货分钟 K 数据
create database "dfs://ctp_k_minute_level"
partitioned by VALUE(2020.01.01..2021.01.01)
engine='OLAP'
create table "dfs://ctp_k_minute_level"."ctp_k_minute"(
securityid SYMBOL
tradetime TIMESTAMP
open DOUBLE
close DOUBLE
high DOUBLE
low DOUBLE
vol INT
val DOUBLE
vwap DOUBLE
)
partitioned by tradetime
用户能够运用上述代码以创立存储期货分钟K数据的数据库表,与股票分钟K数据的分区规矩相同,运用”时刻维度按天”的分区规矩,存储引擎运用OLAP。每个分区内都包括了当天一切期货的分钟K数据。
3.4 银行间债券
3.4.1 X-Bond 报价
create database "dfs://XBondDepth"
partitioned by VALUE(2023.01.01..2023.12.31)
engine='TSDB'
create table "dfs://XBondDepth"."XBondDepthTable"(
bondCodeVal SYMBOL
createTime TIMESTAMP
marketDepth LONG
mdBookType LONG
messageId LONG
messageSource STRING
msgSeqNum LONG
msgType STRING
bidmdEntryPrice DOUBLE[]
offermdEntryPrice DOUBLE[]
bidmdEntrySize LONG[]
offermdEntrySize LONG[]
bidsettlType LONG[]
offersettlType LONG[]
bidyield DOUBLE[]
offeryield DOUBLE[]
bid1yieldType STRING
offer1yieldType STRING
bid2yieldType STRING
offer2yieldType STRING
bid3yieldType STRING
offer3yieldType STRING
bid4yieldType STRING
offer4yieldType STRING
bid5yieldType STRING
offer5yieldType STRING
bid6yieldType STRING
offer6yieldType STRING
securityID SYMBOL
senderCompID STRING
senderSubID STRING
sendingTime TIMESTAMP
)
partitioned by createTime,
sortColumns=[`securityID, `createTime]
用户能够运用上述代码以创立存储X-Bond报价数据的数据库表,运用”时刻维度按天”的分区规矩,运用存储引擎TSDB,运用 “债券代码 创立时刻” 作为排序列。每个分区内都包括了当天一切 X-Bond 报价数据。
3.4.2 X-Bond 成交
create database "dfs://XBondTrade"
partitioned by VALUE(2023.01.01..2023.12.31)
engine='TSDB'
create table "dfs://XBondTrade"."XBondTradetable"(
createTime TIMESTAMP
securityID SYMBOL
beforeClosingPrice DOUBLE
beforeClosingYield DOUBLE
beforeWeightedAveragePrice DOUBLE
beforeWeightedAverageYield DOUBLE
fillSide LONG
highestPrice DOUBLE
highestYield DOUBLE
lowestPrice DOUBLE
lowestYield DOUBLE
marketIndicator LONG
mdSubType LONG
mdType LONG
messageId LONG
messageSource STRING
msgSeqNum LONG
msgType STRING
openingValence DOUBLE
openingYield DOUBLE
priceRiseFallAmplitude DOUBLE
senderCompID STRING
sendingTime TIMESTAMP
settlType LONG
symbol STRING
tradeMethod LONG
transactTime TIMESTAMP
transactionNumber LONG
uniqueOutputKey LONG
upToDatePrice DOUBLE
upToDateYield DOUBLE
weightedAveragePrice DOUBLE
weightedAverageYield DOUBLE
yieldRiseFall DOUBLE
)
partitioned by createTime,
sortColumns=[`securityID, `createTime]
用户能够运用上述代码以创立存储X-Bond成交数据的数据库表,运用”时刻维度按天”的分区规矩,运用存储引擎TSDB,运用 “债券代码 创立时刻” 作为排序列。每个分区内都包括了当天一切 X-Bond 成交数据。
3.4.3 ESP 报价
create database "dfs://ESPDepth"
partitioned by VALUE(2023.01.01..2023.12.31)
engine='TSDB'
create table "dfs://ESPDepth"."ESPDepthtable"(
createTime TIMESTAMP
bondCodeVal SYMBOL
marketDepth LONG
marketIndicator LONG
mdBookType LONG
mdSubBookType LONG
messageId LONG
messageSource STRING
msgSeqNum LONG
msgType STRING
askclearingMethod LONG[]
bidclearingMethod LONG[]
askdeliveryType LONG[]
biddeliveryType LONG[]
askinitAccountNumSixCode LONG[]
bidinitAccountNumSixCode LONG[]
asklastPx DOUBLE[]
bidlastPx DOUBLE[]
askmdEntryDate DATE[]
bidmdEntryDate DATE[]
askmdEntrySize LONG[]
bidmdEntrySize LONG[]
askmdEntryTime TIME[]
bidmdEntryTime TIME[]
askmdQuoteType LONG[]
bidmdQuoteType LONG[]
askquoteEntryID LONG[]
bidquoteEntryID LONG[]
asksettlType LONG[]
bidsettlType LONG[]
askyield DOUBLE[]
bidyield DOUBLE[]
ask1initPartyTradeCode STRING
bid1initPartyTradeCode STRING
ask2initPartyTradeCode STRING
bid2initPartyTradeCode STRING
ask3initPartyTradeCode STRING
bid3initPartyTradeCode STRING
ask4initPartyTradeCode STRING
bid4initPartyTradeCode STRING
ask5initPartyTradeCode STRING
bid5initPartyTradeCode STRING
ask6initPartyTradeCode STRING
bid6initPartyTradeCode STRING
ask7initPartyTradeCode STRING
bid7initPartyTradeCode STRING
ask8initPartyTradeCode STRING
bid8initPartyTradeCode STRING
ask9initPartyTradeCode STRING
bid9initPartyTradeCode STRING
ask10initPartyTradeCode STRING
bid10initPartyTradeCode STRING
securityID SYMBOL
securityType STRING
senderCompID STRING
senderSubID STRING
sendingTime TIMESTAMP
symbol STRING
)
partitioned by createTime,
sortColumns=[`securityID, `createTime]
用户能够运用上述代码以创立存储ESP报价数据的数据库表,运用”时刻维度按天”的分区规矩,运用存储引擎TSDB,运用 “债券代码 创立时刻” 作为排序列。每个分区内都包括了当天一切 ESP 报价数据。
3.4.4 ESP 成交
create database "dfs://ESPTrade"
partitioned by VALUE(2023.01.01..2023.12.31)
engine='TSDB'
create table "dfs://ESPTrade"."ESPTradetable"(
createTime TIMESTAMP
securityID SYMBOL
execId STRING
execType STRING
lastQty LONG
marketIndicator LONG
messageSource STRING
msgSeqNum LONG
msgType STRING
price DOUBLE
senderCompID STRING
stipulationType STRING
stipulationValue DOUBLE
symbol STRING
tradeDate DATE
tradeMethod LONG
tradeTime TIME
tradeType LONG
transactTime TIMESTAMP
)
partitioned by createTime,
sortColumns=[`securityID, `createTime]
用户能够运用上述代码以创立存储ESP成交数据的数据库表,运用”时刻维度按天”的分区规矩,运用存储引擎TSDB,运用 “债券代码 创立时刻” 作为排序列。每个分区内都包括了当天一切 ESP 成交数据。
3.4.5 QB 报价
create database "dfs://QB_QUOTE"
partitioned by VALUE(2023.10.01..2023.10.31)
engine='TSDB'
create table "dfs://QB_QUOTE"."qbTable"(
SENDINGTIME TIMESTAMP
CONTRIBUTORID SYMBOL
MARKETDATATIME TIMESTAMP
SECURITYID SYMBOL
BONDNAME SYMBOL
DISPLAYLISTEDMARKET SYMBOL
BIDQUOTESTATUS INT
BIDYIELD DOUBLE
BIDPX DOUBLE
BIDPRICETYPE INT
BIDPRICE DOUBLE
BIDDIRTYPRICE DOUBLE
BIDVOLUME INT
BIDPRICEDESC STRING
ASKQUOTESTATUS INT
ASKYIELD DOUBLE
OFFERPX DOUBLE
ASKPRICETYPE INT
ASKPRICE DOUBLE
ASKDIRTYPRICE DOUBLE
ASKVOLUME INT
ASKPRICEDESC STRING
)
partitioned by MARKETDATATIME,
sortColumns=[`SECURITYID,`MARKETDATATIME]
用户能够运用上述代码以创立存储QB报价数据的数据库表,运用”时刻维度按天”的分区规矩,运用存储引擎TSDB,运用 “债券代码 市场时刻” 作为排序列。每个分区内都包括了当天一切 QB 报价数据。
3.4.6 QB 成交
create database "dfs://QB_TRADE"
partitioned by VALUE(2023.10.01..2023.10.31)
engine='TSDB'
create table "dfs://QB_TRADE"."lastTradeTable"(
SECURITYID SYMBOL
BONDNAME SYMBOL
SENDINGTIME TIMESTAMP
CONTRIBUTORID SYMBOL
MARKETDATATIME TIMESTAMP
MODIFYTIME SECOND
DISPLAYLISTEDMARKET SYMBOL
EXECID STRING
DEALSTATUS INT
TRADEMETHOD INT
YIELD DOUBLE
TRADEPX DOUBLE
PRICETYPE INT
TRADEPRICE DOUBLE
DIRTYPRICE DOUBLE
SETTLSPEED STRING
)
partitioned by MARKETDATATIME,
sortColumns=[`SECURITYID,`MARKETDATATIME]
用户能够运用上述代码以创立存储QB买卖数据的数据库表,运用”时刻维度按天”的分区规矩,运用存储引擎TSDB,运用 “债券代码 市场时刻” 作为排序列。每个分区内都包括了当天一切 QB 买卖数据。
4 因子库窄表存储计划实践
4.1 日频因子库
create database "dfs://dayFactorDB"
partitioned by RANGE(date(datetimeAdd(1980.01M,0..80*12,'M'))), VALUE(`f1`f2),
engine='TSDB'
create table "dfs://dayFactorDB"."dayFactorTB"(
tradetime DATE[comment="时刻列", compress="delta"],
securityid SYMBOL,
value DOUBLE,
factorname SYMBOL
)
partitioned by tradetime, factorname,
sortColumns=[`securityid, `tradetime],
keepDuplicates=ALL,
sortKeyMappingFunction=[hashBucket{, 500}]
用户能够运用上述代码以创立存储日频因子库的数据库表,分区规矩选用了“时刻维度按年 因子名”的组合分区方法存储,运用存储引擎TSDB,运用 “股票代码 买卖时刻” 作为排序列。经测验日频因子数据选用这种方法分区存储,归纳功能最佳。
对于分区内的分组排序存储来说,DolphinDB 中的 TSDB 存储引擎供给排序键设置,每一个分区的数据写在一个或多个level file中。每一个level file内部的数据依照指定的列进行排序且创立块索引。排序列中除了最终一列的其他列通常为在点查中过滤条件会用到的列,其仅有值组合称为 SortKeys。为确保功能最优,每个分区的 SortKeys 主张不超过1000个。 如 SortKeys 较多可经过设置 sortKeyMappingFunction 对 SortKeys 降维。经测验日频因子数据选用“securityid tradetime”的方法进行排序,sortKeyMapping设置为500时,归纳功能最佳。
4.2 半小时频因子库
create database "dfs://halfhourFactorDB"
partitioned by RANGE(date(datetimeAdd(1980.01M,0..80*12,'M'))), VALUE(`f1`f2),
engine='TSDB'
create table "dfs://halfhourFactorDB"."halfhourFactorTB"(
tradetime TIMESTAMP[comment="时刻列", compress="delta"],
securityid SYMBOL,
value DOUBLE,
factorname SYMBOL,
)
partitioned by tradetime, factorname,
sortColumns=[`securityid, `tradetime],
keepDuplicates=ALL,
sortKeyMappingFunction=[hashBucket{, 500}]
用户能够运用上述代码以创立存储半小时频因子库的数据库表,分区规矩选用了“时刻维度按年 因子名”的组合分区方法存储,运用存储引擎TSDB,运用 “股票代码 买卖时刻” 作为排序列。经测验半小时频因子数据选用这种方法分区存储,归纳功能最佳。
4.3 非常钟频因子库
create database "dfs://tenMinutesFactorDB"
partitioned by VALUE(2023.01M..2023.06M),
VALUE(`f1`f2),
engine='TSDB'
create table "dfs://tenMinutesFactorDB"."tenMinutesFactorTB"(
tradetime TIMESTAMP[comment="时刻列", compress="delta"],
securityid SYMBOL,
value DOUBLE,
factorname SYMBOL
)
partitioned by tradetime, factorname,
sortColumns=[`securityid, `tradetime],
keepDuplicates=ALL,
sortKeyMappingFunction=[hashBucket{, 500}]
用户能够运用上述代码以创立存储非常钟频因子库的数据库表,分区规矩选用了“时刻维度按月 因子名”的组合分区方法存储,运用存储引擎TSDB,运用 “股票代码 买卖时刻” 作为排序列。经测验非常钟频因子数据选用这种方法分区存储,归纳功能最佳。
4.4 分钟频因子库
create database "dfs://minuteFactorDB"
partitioned by VALUE(2012.01.01..2021.12.31), VALUE(`f1`f2),
engine='TSDB'
create table "dfs://minuteFactorDB"."minuteFactorTB"(
tradetime TIMESTAMP[comment="时刻列", compress="delta"],
securityid SYMBOL,
value DOUBLE,
factorname SYMBOL
)
partitioned by tradetime, factorname,
sortColumns=[`securityid, `tradetime],
keepDuplicates=ALL,
sortKeyMappingFunction=[hashBucket{, 500}]
用户能够运用上述代码以创立存储分钟频因子库的数据库表,分区规矩选用了“时刻维度按日 因子名”的组合分区方法存储,运用存储引擎TSDB,运用 “股票代码 买卖时刻” 作为排序列。经测验分钟频因子数据选用这种方法分区存储,归纳功能最佳。
4.5 秒钟频因子库
create database "dfs://secondFactorDB"
partitioned by VALUE(datehour(2022.01.01T00:00:00)..datehour(2022.01.31T00:00:00)), VALUE(`f1`f2),
engine='TSDB'
create table "dfs://secondFactorDB"."secondFactorTB"(
tradetime TIMESTAMP[comment="时刻列", compress="delta"],
securityid SYMBOL,
value DOUBLE,
factorname SYMBOL
)
partitioned by tradetime, factorname,
sortColumns=[`securityid, `tradetime],
keepDuplicates=ALL,
sortKeyMappingFunction=[hashBucket{, 500}]
用户能够运用上述代码以创立存储秒钟频因子库的数据库表,分区规矩选用了“时刻维度按小时 因子名”的组合分区方法存储,运用存储引擎TSDB,运用 “股票代码 买卖时刻” 作为排序列。经测验秒钟频因子数据选用这种方法分区存储,归纳功能最佳。
4.6 Level-2 快照频因子库
create database "dfs://level2FactorDB" partitioned by VALUE(2022.01.01..2022.12.31), VALUE(["f1", "f2"]),
engine='TSDB'
create table "dfs://level2FactorDB"."level2FactorTB"(
tradetime TIMESTAMP[comment="时刻列", compress="delta"],
securityid SYMBOL,
value DOUBLE,
factorname SYMBOL
)
partitioned by tradetime, factorname,
sortColumns=[`securityid, `tradetime],
keepDuplicates=ALL,
sortKeyMappingFunction=[hashBucket{, 500}]
用户能够运用上述代码以创立存储Level-2快照频因子库的数据库表,分区规矩选用了“时刻维度按日 因子名”的组合分区方法存储,运用存储引擎TSDB,运用 “股票代码 买卖时刻” 作为排序列。经测验Level-2快照频因子数据选用这种方法分区存储,归纳功能最佳。
4.7 逐笔频因子库
create database "dfs://tickFactorDB" partitioned by VALUE(2022.01.01..2022.12.31), VALUE(["f1", "f2"]), HASH([SYMBOL,10])
engine='TSDB'
create table "dfs://tickFactorDB"."tickFactorTB"(
tradetime TIMESTAMP[comment="时刻列", compress="delta"],
securityid SYMBOL,
value DOUBLE,
factorname SYMBOL
)
partitioned by tradetime, factorname,securityid,
sortColumns=[`securityid, `tradetime],
keepDuplicates=ALL
用户能够运用上述代码以创立存储逐笔频因子库的数据库表,分区规矩选用了“时刻维度按日 因子名维度 股票维度 HASH10“的组合分区方法存储,运用存储引擎TSDB,运用 “股票代码 买卖时刻” 作为排序列。经测验逐笔频因子数据选用这种方法分区存储,归纳功能最佳。与上述因子的存储计划不同的当地在于没有对sortKey进行降维,由于1天数据股票代码维度HASH 10,每个最小分区内是500个股票,不需要再进行降维。
4.8 期货500ms频因子库
create database "dfs://futuresFactorDB"
partitioned by VALUE(2022.01.01..2023.01.01), VALUE(["f1", "f2"]),
engine='TSDB'
create table "dfs://futuresFactorDB"."futuresFactorTB"(
tradetime TIMESTAMP[comment="时刻列", compress="delta"],
securityid SYMBOL,
value DOUBLE,
factorname SYMBOL
)
partitioned by tradetime, factorname,
sortColumns=[`securityid, `tradetime],
keepDuplicates=ALL,
sortKeyMappingFunction=[hashBucket{, 500}]
用户能够运用上述代码以创立存储L期货500ms频因子库的数据库表,分区规矩选用了“时刻维度按日 因子名”的组合分区方法存储,运用存储引擎TSDB,运用 “期货代码 买卖时刻” 作为排序列。经测验期货500ms频因子数据选用这种方法分区存储,归纳功能最佳。
5. 结语
针对常见的金融数据,咱们经过最佳实践,给出上述建库建表的推荐计划,用户能够依据实践事务场景,进行恰当调整和修正。
6. 常见问题与回答(FAQ)
6.1 创立数据库表时报错:已经存在重名库表
执行创立数据库表的代码后,报出如下过错:
create database partitioned by VALUE(["f1","f2"]), engine=TSDB => It is not allowed to overwrite an existing database.
处理办法: 主张运用其他名字或者删掉该数据库。
删去指定数据库的代码如下:
dropDatabase("dfs://dayFactorDB")
检查指定数据库是否存在的代码如下:
existsDatabase("dfs://dayFactorDB")