多维分区概述
分区方式介绍
- 水平分区:用户可以通过将一个集合中的数据切分到多个复制组中,以达到并行计算的目的。
- 垂直分区:用户也可以将一个集合全局关系的属性分成若干子集,并在这些子集上作投影运算,将这些子集映射到另外的集合上,从而实现集合关系的垂直切分。
- 多维分区是指将集合先通过垂直分区映射到多个子集合中,再通过水平分区将子集合切分到多个复制组中的方式。
多维分区的优势
通常流水类数据选择创建多维分区表进行存放,把不同时间段的数据分布在不同的数据组。多维分区表的好处有:
1)当访问某时间范围的数据能够直接定位到子分区,避免扫描全表数据从而降低 IO。
2)在集群扩容时,把扩展的子表创建在新的机器,无需执行rebalance的操作即可完成表存储空间的扩容。
创建多维分区表
多维分区表是一个包含有垂直分区和水平分区的分区表,由主集合和子集合两部分组成。主集合为一个逻辑结构,用于连接所有子集合。真正的数据存储于交易日志子集合之中。
1)通过 Linux 命令行进入 SequoiaDB Shell;
1 | sdb |
2)通过 javascript 语言连接协调节点,获取数据库连接;
1 | var db = new Sdb("localhost", 11810); |
3)创建域;
1 | db.createDomain( "company_domain", [ "group1", "group2", "group3" ], { "AutoSplit": true } ); |
4)创建主集合空间;
1 | db.createCS("company", { "Domain": "company_domain" } ); |
5)创建主集合;
1 | db.company.createCL("translog", { "IsMainCL": true, "ShardingKey": {"tx_time": 1 }, "ShardingType": "range" } ); |
6)创建子集合空间;
创建子集合空间 year2020 :
1 | db.createCS("year2020", { "Domain": "company_domain" } ); |
创建子集合空间 year2021 :
1 | db.createCS("year2021", { "Domain": "company_domain" } ); |
7)创建两个子集合;
创建子集合 year2020.translog :
1 | db.year2020.createCL("translog", { "ShardingKey": { "_id": 1 }, "ShardingType": "hash", "ReplSize": -1, "Compressed": true, "CompressionType": "lzw", "AutoSplit": true, "EnsureShardingIndex": false } ); |
创建子集合 year2021.translog :
1 | db.year2021.createCL("translog", { "ShardingKey": { "_id": 1 }, "ShardingType": "hash", "ReplSize": -1, "Compressed": true, "CompressionType": "lzw", "AutoSplit": true, "EnsureShardingIndex": false } ); |
8)挂载子集合;
挂载子集合 year2020.translog :
1 | db.company.translog.attachCL("year2020.translog", { "LowBound": { "tx_time": MinKey() }, UpBound: { tx_time: { "$date": "2021-01-01" } } } ); |
挂载子集合 year2021.translog :
1 | db.company.translog.attachCL("year2021.translog", { LowBound: { "tx_time": { "$date": "2021-01-01" } }, "UpBound": { "tx_time": MaxKey() } } ); |
挂载完成后,子集合 year2020.translog 保存小于 2021年的数据,而子集合 year2021.translog 保存大于等于 2021 年的数据。
Note:
挂载语句中的
$date
表示字段 tx_time 的数据类型为 date 型。
更多数据类型请参考如下链接:
9)插入数据;
从主集合插入 2020 年 3 月份的数据:
1 | db.company.translog.insert( { "serial_no": 1, "order_id": "20200302001", "bus_pay_no": "7312a297-21b4-1328-7834-ss21a251708", "tx_time": { "$date": "2020-03-02" } } ); |
从主集合插入 2021 年 1 月份的数据:
1 | db.company.translog.insert( { "serial_no": 2, "order_id": "20210101008", "bus_pay_no": "4321a297-15b4-4528-9034-cc21a256708", "tx_time": { "$date": "2021-01-01" } } ); |
10)查询两个子集合数据分布;
year2020.translog 子集合数据量:
1 | db.year2020.translog.count(); |
year2021.translog 子集合数据量:
1 | db.year2021.translog.count(); |
11)关闭 db 连接;
1 | db.close(); |
12)退出 SequoiaDB Shell;
1 | quit; |
MySQL 实例关联多维分区表
由于 company 集合空间和 translog 集合在 SequoiaDB 数据库已存在,此时 MySQL 的 CREATE DATABASE 和 CREATE TABLE 语句只是映射了 SequoiaDB 的集合空间和集合,做了关联操作。
1)登录 MySQL 实例;
1 | /opt/sequoiasql/mysql/bin/mysql -h 127.0.0.1 -P 3306 -u root |
2)MySQL 创建数据库;
1 | CREATE DATABASE company; |
3)MySQL 创建表;
1 | CREATE TABLE translog |
4)数据查询;
1 | SELECT * FROM translog; |
Note:
此时可以查询到已存在的数据。
5)MySQL 实例中插入数据;
1 | INSERT INTO translog VALUES (3, '20200521009', '3221a297-78b4-2528-7980-cc42a976605', '2020-05-21'); |
6)数据查询;
1 | SELECT * FROM translog; |
通过 MySQL 实例向 translog 表插入的数据,数据最终会保存在 SequoiaDB 巨杉数据库中。
7)退出 MySQL Shell;
1 | \q |
查看分区的数据
1)查看year2020集合空间的数据,有两条
1 | db.year2020.translog.find() |
2)查看year2021集合空间的数据,只有一条
1 | db.year2021.translog.find() |