共计 2921 个字符,预计需要花费 8 分钟才能阅读完成。
1. 为什么对数据进行分区?
对数据库进行分区能够极大的升高零碎响应提早同时进步数据吞吐量。具体来说,分区有以下几个益处:
- 分区使得大型表更易于治理。对数据子集的保护操作也更加高效,因为这些操作只针对须要的数据而不是整个表。一个好的分区策略将通过只读取满足查问所需的相干数据来缩小要扫描的数据量。当所有的数据都在同一个分区上,对数据库的查问,计算,以及其它操作都会被限度在磁盘拜访 IO 这个瓶颈上。
- 分区使得零碎能够充分利用所有资源。一个良好的分区计划搭配并行计算,分布式计算就能够充分利用所有节点来实现通常要在一个节点上实现的工作。当一个工作能够拆分成几个扩散的子工作,每个子工作拜访不同的分区,就能够达到晋升效率的目标。
- 分区减少了零碎的可用性。因为分区的正本通常是寄存在不同的物理节点的。所以一旦某个分区不可用,零碎仍然能够调用其它正本分区来保障作业的失常运行。
2. 分区形式
DolphinDB database 反对多种分区形式:范畴分区(RANGE),哈希分区(HASH),值分区(VALUE),列表分区(LIST),复合分区(COMPO)。
- 范畴分区每个区间创立一个分区,是最罕用的也是举荐的一种分区形式。能够把数值在一个区间内的所有记录搁置到一个分区。
- 哈希分区利用哈希函数对分区列操作,不便建设指定数量的分区。
- 值分区每个值创立一个分区,例如股票交易日期,股票交易月。
- 列表分区是依据用户枚举的列表来进行分区,比值分区更加灵便。
- 复合分区实用于数据量特地大而且查问常常波及两个或以上的分区列。每个分区抉择都能够采纳区间,值或列表分区。例如按股票交易日期进行值分区,同时按股票代码进行范畴分区。
咱们能够应用 database 函数创立数据库。
语法:_database(directory, [partitionType], [partitionScheme], [locations])_
参数
_directory:_数据库保留的目录。DolphinDB 有三种类型的数据库,别离是内存数据库、磁盘上的数据库和分布式文件系统上的数据库。创立内存数据库,directory 为空;创立本地数据库,directory 应该是本地文件系统目录;创立分布式文件系统上的数据库,directory 应该以“dfs://”结尾。本教程以创立 Windows 本地数据库为例。
_partitionType:_分区形式,有 5 种形式:范畴分区(RANGE),哈希分区(HASH),值分区(VALUE),列表分区(LIST),复合分区(COMPO)。
_partitionScheme:_分区计划。各种分区形式对应的分区计划如下:
_locations:_指定每个分区所在的节点地位。如果是分布式文件系统的数据库或者复合分区(COMPO)类型的数据库,不能应用 locations 参数。
2.1 范畴分区
范畴分区是由分区向量决定。分区向量示意区间,蕴含起始值,不蕴含结尾值。
在上面的例子中,数据库 db 有两个分区:[0,5)和[5,10)。应用函数 append! 在数据库 db 中保留表 t 为分区表 pt,并应用 ID 作为分区列。
n=1000000
ID=rand(10, n)
x=rand(1.0, n)
t=table(ID, x)
db=database("dfs://rangedb", RANGE, 0 5 10)
pt = db.createPartitionedTable(t, `pt, `ID)
pt.append!(t);
pt=loadTable(db,`pt)
select count(x) from pt
2.2 哈希分区
哈希分区对分区列应用哈希函数以产生分区。哈希分区是产生指定数量的分区的一个简便办法。然而要留神,哈希分区不能保障分区的大小统一,尤其当分区列的值的散布存在偏态的时候。此外,若要查找分区列上一个间断区域的数据时,哈希分区的效率比区域分区或值分区要低。
在上面的例子中,数据库 db 有两个分区。应用函数 append! 在数据库 db 中保留表 t 为分区表 pt,并应用 ID 作为分区列。
n=1000000
ID=rand(10, n)
x=rand(1.0, n)
t=table(ID, x)
db=database("dfs://hashdb", HASH, [INT, 2])
pt = db.createPartitionedTable(t, `pt, `ID)
pt.append!(t);
pt=loadTable(db,`pt)
select count(x) from pt
2.3 值分区
值分区用一个值代表一个分区。上面的例子定义了 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("dfs://valuedb", VALUE, 2000.01M..2016.12M)
pt = db.createPartitionedTable(t, `pt, `month)
pt.append!(t)
pt=loadTable(db,`pt)
select count(x) from pt
2.4 列表分区
在列表(LIST)分区中,咱们用一个蕴含多个元素的列表代表一个分区。上面的例子有两个分区,第一个分区蕴含 3 个股票代码,第二个分区蕴含 2 个股票代码。
n=1000000
ticker = rand(`MSFT`GOOG`FB`ORCL`IBM,n);
x=rand(1.0, n)
t=table(ticker, x)
db=database("dfs://listdb", LIST, [`IBM`ORCL`MSFT, `GOOG`FB])
pt = db.createPartitionedTable(t, `pt, `ticker)
pt.append!(t)
pt=loadTable(db,`pt)
select count(x) from pt
2.5 组合分区
组合(COMPO)分区能够定义 2 或 3 个分区列。每列能够独立采纳范畴 (RANGE),值(VALUE) 或列表 (LIST) 分区。组合分区的多个列在逻辑上是并列的,不存在从属关系或优先级关系。
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("dfs://compoDB", COMPO, [dbDate, dbID])
pt = db.createPartitionedTable(t, `pt, `date`ID)
pt.append!(t)
pt=loadTable(db,`pt)
select count(x) from pt
下面的例子创立了 5 个值分区。
在 20170807 这个分区,有 2 个范畴分区。
DolphinDB 分区数据库教程(二)将会介绍 DolphinDB 分区准则以及非凡的分区计划。