文档记录

SequoiaDB 巨杉数据库存储的记录( Record )也称为文档( Document ) 。文档在分布式存储引擎中,以 BSON 的方式存储,而 BSON 是 JSON 数据模型的二进制编码。由于文档是一种基于 JSON 数据模型的灵活键值对,而且它支持嵌套结构与数组,所以它既可以存储关系型数据,也可以存储半结构化和非结构化数据。

文档概念

文档的字面形式如同 JSON 数据类型。而 JSON 是一种轻量级的数据交换格式,非常易于用户阅读和编写,同时也易于机器生成和解析。

文档结构

一般来说,一条文档由一个或多个字段构成,每个字段分为键与值两个部分,如下为包含两个字段的文档:

  1. { "姓名" : "张三", "性别" : "男" }

其中 “姓名”和”性别”为字段的键,而”张三”和”男”为字段的值。

文档支持嵌套结构和数组,如下为包含嵌套结构和数组的文档:

  1. { "姓名" : "张三", "性别" : "男", "地址" : { "省份" : "yy", "城市" : "xx", "街道" : "水蓝街" }, "电话" : [ "138xxxxxxxx", "180xxxxxxxx" ] }

其中名为”地址”的字段的值为一个嵌套 JSON 对象, 而名为”电话”的字段的值为一个 JSON 数组。

Note:

关于 JSON 的更多内容,可参考 JSON 官网的介绍

字段的键与值

字段的键又称为字段名,其类型为字符串。

字段的值又称为字段值。它可以为多种类型,如:整数、长整数、浮点数、字符串和对象等。关于字段值的类型,用户可以参考数据类型章节的介绍。

文档的限制

文档存在如下限制:

  • 每条文档的 BSON 编码最大长度为 16MB。
  • 每条文档必须包括 “_id” 字段。如果用户没有提供该字段,系统会自动生成一个 OID 类型的 “_id” 字段。
  • “_id” 字段名需要在集合内唯一(若集合为切分集合,则 “_id” 字段名需要在每个切分子集合内唯一)。
  • 文档中各个字段无排列顺序,在进行数据操作时(例如进行数据更新),字段之间的顺序可能会被调换。

字段名存在如下限制:

  • 用户插入的文档不允许包含重复的字段名。
  • 用户自定义的字段名不允许以 “$” 字符起始。
  • 用户自定义的字段名不允许包含 “.” 字符。

Note:

  • 由于 C/CPP BSON 能够构建重复字段名的 BSON, 而 Java/C# 等其它 BSON 无法构建重复字段名的 BSON,为了保证数据的正确性,用户无须构建重复字段的 BSON。
  • SequoiaDB 内部程序创建的一些文档(一般为元数据)可能含有重复字段名,但 SequoiaDB 不会向用户的文档添加重复字段名。

文档与 SQL 实例记录的比较

与 MySQL 和 PostgreSQL 等传统关系型数据库表定义需要指定记录的 schema 信息不同,SequoiaDB 的集合元数据并不会存储文档(记录)的 schema。在 SequoiaDB 中,文档的 schema 信息存储在文档自身当中。

如上介绍所述,文档是一种灵活的数据结构。它存储的数据包含了字段名和字段值。每个字段在 BSON 中的存储结构可以简化为如下格式:

bson存储结构图

因此文档自身已经包含了足够的 schema 信息。如下显示在 MySQL 及在 SequoiaDB 查询数据的情况,用户可以比较两种记录组织方式的差异。

在 MySQL shell 创建名为 sample 的数据库和名为 employee 表。该数据库和表分别自动映射到 SequoiaDB 名为sample的集合空间和名为 employee 的集合上:

  1. mysql> create database sample;
  2. mysql> use sample;
  3. mysql> create table employee(name varchar(50), sex int, age int, department varchar(100));
  4. mysql> insert into employee values("Tom", 0, "25", "R&D");
  5. mysql> insert into employee values("Mary", 1, "23", "Test");
  6. mysql> select * from employee;
  7. +-------+-------+-------+------------+
  8. | name | sex | age | department |
  9. +-------+-------+-------+------------|
  10. | "Tom" | 0 | 25 | "R&D" |
  11. | "Mary"| 1 | 23 | "Test" |
  12. +-------+-------+-------+------------|

在 SequoiaDB 上查询插入的数据:

  1. sdb> db.sample.employee.find()
  2. { "_id": { "$oid": "5d1da52b38892b0af758ee5f" }, "name": "Tom", "sex": 0, "age": 25, "department": "R&D" }
  3. { "_id": { "$oid": "5d1da53138892b0af758ee60" }, "name": "Mary", "sex": 1, "age": 23, "department": "Test" }