DolphinDB使用案例2:数据表分区
程序员文章站
2022-07-13 14:55:25
...
-
关于分区,参见《数据库分区、分表、分库、分片》。
数据表分区后,只是物理存储上分为不同的区,对于软件层面,代码处理的还是同一张表,代码不会因为分区而改变。
当需要加载的表比系统内存大,就需要使用分区表。
本文以
btcusdt_1t.csv
为例进行操作。决定分区数量的原则是:每个分区的大小不超过系统内存的四分之一。 -
分区方式一:顺序分区
分区方式:根据行的顺序,将
btcusdt_1t.csv
分成2区。# 构建分区数据库 db = database("D:/DolphinDB/Data/seqdb", SEQ, 2) # 将分区表并行载入 btcusdt = loadTextEx(db, "btcusdt",,"D:/DolphinDB/Data/btcusdt_1t.csv")
-
database
数据库创建函数database(directory, [partitionType], [partitionScheme], [locations])
参数 意义 备注 directory 保存数据库的目录地址 如果创建分布式文件系统中的数据库,以“dfs://” partitionType 六种分区类型 顺序分区(SEQ),范围分区(RANGE),哈希分区(HASH),数值分区(VALUE),列表分区(LIST)和组合分区(COMPO) partitionScheme 分区方案,描述分区是如何创建的 CHAR, SHORT, INT, DATE, MONTH, TIME, MINUTE, SECOND, DATETIME和SYMBOL locations 元组指定分区位置 元组中元素数量,应与分区类型、分区方案共同决定的分区数量相同。
如果不指定,则所有分区属于当前节点分区类型与分区方案对应表:
分区类型 分区符号 分区方案 顺序分区 SEQ 整型标量。表示分区的数量。 范围分区 RANGE 向量。 向量的任意两个相邻元素定义分区的范围。 哈希分区 HASH 元组。第一个元素是分区列的数据类型,第二个元素是分区的数量。 值分区 VALUE 向量。 向量的每个元素定义了一个分区。 列表分区 LIST 向量。 向量的每个元素定义了一个分区。 组合分区 COMPO 向量。向量的每个元素是一个数据库句柄。 -
loadTextEx
文本载入函数loadTextEx(dbHandle, tableName, partitionColumns, fileName, [delimiter=','], [schema])
参数 意义 备注 dbHandle 保存数据的分布式数据库的句柄 该数据库可以是本地文件系统的数据库,也可以是分布式文件系统的数据库 tableName 表示分布式表的名字 一个字符串 partitionColumns 表示分区列 字符串标量或向量。
对于顺序分区,为空
对于组合分区,是字符串向量filename 绝对路径的文件名 需载入的数据 delimiter 表格列的分隔符 schema 表对象,用于指定保存数据的表的结构 第一列的内容为字段名,第二列的内容为表示数据类型的字符串(不区分大小写)。 loadTextEx
函数采用Pipeline
机制,一个线程解析数据,同时另一个线程不停的往数据库写。如此实现并行存储功能。
-
-
分区方式二:范围分区
分区方式:根据数据表中某列的范围进行分区。
# 2.1根据某列(open)的范围进行分区 db = database("D:/DolphinDB/Data/rangedb1", RANGE, 0 7500 8000) btcusdt = loadTextEx(db, "btcusdtrange", `open, "D:/DolphinDB/Data/btcusdt_1t.csv")
**出现问题:**The data type of column [open] doesn’t match the database partition scheme.**原因:**浮点数不能作为分区方案,实际业务中 一般也不会用到。即便是下面的值分区也不可以。
# 2.1(修正)改用时间作为分区方案 db = database("D:/DolphinDB/Data/rangedb1", RANGE, 2018.03.29T00:00:00 2018.06.29T00:00:00 2018.10.12T00:00:00 ) btcusdt = loadTextEx(db, "btcusdtrange", `candle_begin_time, "D:/DolphinDB/Data/btcusdt_1t.csv")
举另外一个例子:
# 2.2 另外一个例子 n = 1000000 ID= rand(10, n) x = rand(1.0, n) t = table(ID, x) db = database("D:/DolphinDB/Data/rangedb2", RANGE, 0 5 10) pt = db.createPartitionedTable(t, `pt, `ID) pt.append!(t) pt = loadTable(db, `pt) select count(*) from pt
-
createPartitionedTable()创建磁盘或内存中的分区表
createPartitionedTable(dbHandle, table, [tableName], partitionColumns)
参数 意义 备注 dbHandle 保存分区表的分布式数据库 可以是本地文件系统;
或者分布式文件系统;
如果没有指定,会是内存的分区表table 一个或一个系列的表 系统将会根据表的结构创建新的分区表 tablename 保存到磁盘的分布式表的表名 或者是内存的分区表的表名 partitionColumns 一个字符串或者字符串向量,表示分区列 对于多层次分区,是一个字符串向量 与append!或savePartition来生成一个分区表,不能用于创建顺序分区的表。
创建分区表时只会使用参数table的结构,并不会把table中的数据插入到新的分区表中。
-
-
分区方式三:值分区
分区方式:根据列中元素的值分区
# 204个分区,每个分区代表2000.1到2016.12之间的每个月份 n=1000000 month=take(2000.01M..2016.12M, n) x=rand(1.0, n) t=table(month, x) db=database("C:/DolphinDB/Data/valuedb", VALUE, 2000.01M..2016.12M) pt = db.createPartitionedTable(t, `pt, `month) pt.append!(t) pt=loadTable(db,`pt) select count(x) from pt
-
分区方式四:层次分区
分区方式:一个数据库可以有二级或三级分区
# 两级分区,第一级分区是值分区;第二级分区是范围分区 n=1000000 ID=rand(100, n) dates=2017.08.07..2017.08.11 date=rand(dates, n) x=rand(10.0, n) t=table(ID, date, x) dbDate = database(, VALUE, 2017.08.07..2017.08.11) dbID=database(, RANGE, 0 50 100) db = database("C:/DolphinDB/Data/hierDB", HIER, [dbDate, dbID]) pt = db.createPartitionedTable(t, `pt, `date`ID) pt.append!(t) pt=loadTable(db,`pt) select count(x) from pt
上一篇: elasticsearch doc和segment原理
下一篇: es近实时搜索原理