上一章提到不同业务场景需要不同的架构设计来支撑,那么在数据存储和检索/查询这个阶段,我们有哪些工具可以选择,这些工具在不同数据场景中的优缺点有哪些。
简单了整理了一张表格, 以数据存储方式/特点,适合场景描述,数据查询/操作纬度进行简单描述,来辅助理解不同类型数据存储方式的差异(主要关注数据存储方式,查询特点,查询优化,以及适合的业务场景)
数据存储方式 | 数据查询/操作特点 | 适合场景 | 开源例子 |
关系型数据库 (Relational Database) | 1. 需要事先定义schema (schema-on-write) 2. 声明式查询(Declarative query language), 查询方式简洁,易开发 3. 查询方式易于并行化(因为描述式查询指令不要求按循序执行, 对比与命令式查询(Imperative Query Language)) | 还是主流存储方式,较适合业务场景中实体关系较为简单(关联纬度较低) 这样在查询过程中减少代码应用层对于关联查询的次数 很多业务场景也会为了match 关联性数据库的特点,将业务场景的数据模型降维存储 | PostgreSQL, MySQL, DB2 |
文件型数据库 (Document Model Database) | 1. 无schema限制(schema-on-read),应用层代码方便迭代开发, 特别是对接第三方无法统一规范化字段的业务场景; 2. 数据存储在单一连续字符串, i.e. JSON, XML | 适合存储大量一对多实体的业务场景, 对接不同和不可控的外部来源数据(无需固定的schema),但是对于大量文件block较大,并且需要频繁更新,此过程中需要重新把block写入磁盘,性能会出现问题 | MongoDB |
图型数据库 (Graph Model Database) | 1. 命令式查询(Imperative Query Language), 即查询方式和指令按特定方式执行 | 适合存储多对多实体关系,在查询阶段采用遍历式查询 |
书中提到用关联型数据库存储网络型数据库(即图型数据库), 比较有意思,分享一下
- 数据关系设计
因为每个实体可能有多个关联实体,实体之间有各种不同的关联关系,把实体当做一个个节点(vertices), 实体间的关系当做线(edges), 这样我们即可以进行实体索引,找到他关联的所有其他实体(比如写作,出演的作品,学校等),也可基于关系(edge)进行筛选;
然而这会产生一个业务问题,即如何进行较为长的深度关联查询,比如一个人喜欢汽车>高档车>SUV系列>陆虎揽胜;
在这个例子中,如果有一个搜索场景,搜索较深的子节点(揽胜)
- 存储场景一,我们只存相近实体的关系,即个人->汽车, 汽车->高档车, 高档车->SUV系列, SUV系列->陆虎揽胜; 那么在查询阶段,我们需要进行较为深度的关联搜索;
- 存储场景二,我们存储实体和所有子节点的信息, 个人->汽车, 个人->高档车, 个体->SUV系列, 个体->陆虎揽胜; 进行查询时可减少关联查询的次数,但是将成倍的放大存储空间;
建表阶段
CREATE TABLE vertices {
vertex_id integer PRIMARY KEY,
properties json
};
CREATE TABLE edges {
edge_id integer PRIMARY_KEY;
tail_vertex integer REFERENCE vertices (vertex_id),
head_vertex integer REFERENCE vertices (vertex_id),
label text,
properties json
};
CREATE INDEX edges_tails ON edges (tail_vertex);
CREATE INDEX edges_heads ON edges (head_vertex);
查询阶段
书写查询语句需要进行多次关联查询,较为冗长
可扩展阅读部分
Triple-Store
网络型数据结构,可以采用实体(subject), 断言(predicate), 客体(object) 来组织存储(i.e. (Lucy, Married, Alain));
语意网络(Semantic Web), 初衷为了整理和结构化互联中的所有数据