设计数据持久层(上):理论分析
关系数据库
- 关系
- 事务
数据库范式
第一范式(1 NF):
- 第一范式要求每个属性值都是不可再分的。
第二范式(2 NF):
- 第二范式要求去除局部依赖. 表中的属性完全依赖于全部主键,而不是部分主键。
第三范式(3 NF):
- 第三范式要求去除非主属性的传递依赖
BC 范式:
- 要求消除主属性对主属性的传递依赖, 从而消除所有属性对主属性的传递依赖。
范式的程度更高,冗余度便更低。
NoSQL
- 出现了更适合业务的非关系数据库服务,也就是 NoSQL;
- 把关系数据库搬到云上,从而让互联网企业从繁重的数据库管理工作中解脱出来,例如 RDS。
NoSQL 数据库的分类
键值(Key-value)数据库:
-
hash
-
redis
-
dynamoDB
-
Partition Key: 找到数据存在哪一个存储单元
-
Sort Key: 找到 value 在存储单元上的具体位置
DynamoDB 表结构看起来和传统的关系数据库有些像,并且每一行的 schema 可以完全不同,即“列”可以是任意的。每张表的数据支持有限的范围查询,包括主键的范围查询,以及索引列的范围查询。其中,索引的数量是有着明确限制的,一种是全局的(相当于 Partition Key + Sort Key),每张表上限 20 个;一种是本地的(相当于 Partition Key 已经确定,只通过 Sort Key 索引),每张表上限 5 个。
列式(Columnar)数据库:
- 行数据库存储方式
-
列数据库存储方式
-
处理逻辑是要求取出所有数据中的特定列,那么列数据库就是更好的选择
事实上,对于数据库来说,磁盘的读、写本身,往往还不是最慢的,最慢的是寻址操作。因此,无论是行数据库还是列数据库,如果根据实际需要,我们的实际访问能够从随机访问变成顺序访问,那么就可以极大地提高效率。在大数据处理中经常使用的 HBase 和云上的 Redshift 都属于这一类。
和行数据库相比,列数据库还有一些其它的好处。比如说,对于很多数据来说,某一个特定列都是满足某种特定的格式的,那么列数据库就可以根据这种格式来执行特定的压缩操作。
文档(Document)数据库:
文档数据库是前面提到的键值数据库的演化版,值是以某一种特定的文档格式来存储的,比如 JSON、XML 等等。也就是说,文档携带的数据,是已经指定了既定的编码、格式等等信息的。某一些文档数据库针对文档的特点,提供了对于文档内容查询的功能,这是比原始的键值数据库功能上强大的地方。
- 本地的 MongoDB
- AWS 上的 DocumentDB
对象(Object)数据库:
- 和上面介绍的文档数据库类似,当 value 变成一个可序列化的对象,特别是一个大对象的时候,它就被归类为对象数据库了。
演进趋势
从 Scale Up 到 Scale Out
先回顾一下“扩展性”(Scalability,也有翻译为“伸缩性”的)这个概念。
按理说,扩展性是包括“纵向(垂直)扩展”和“横向(水平)扩展”的。当然,如今使用这个词的时候,我们往往特指的是“Scale Out”,也就是横向扩展,说白了,就是通过在同一层上增加硬件资源的方式来增加扩展性,从而提高系统的吞吐量或容量。
从结构化数据到非结构化数据
们使用关系数据库的时候,每一行数据都是严格符合表结构的定义,有多少列,每一列的类型是什么,等等,我们把这类数据叫做“结构化”(structured)数据,而这个确定的“结构”,就是 schema。结构化的数据具备最佳的查询、校验和关联能力。
但是当我们使用 DynamoDB 这样的 NoSQL 数据库的时候,我们发现,每一行数据依然可以分成一列一列的,但是有多少列,或者每一列的类型,或者表示的具体含义,却变得不再固定了。这时候我们说,这样的结构依然存在,但是共通的部分明显比结构化数据少多了,于是我们把它们叫做“半结构化”(semi-structured)的数据。
再一般化,就是“非结构化”(non-structured)数据了,上面说的 S3 就是一个很好的例子。即便 S3 上存储的文件是符合某种结构的(比如 JSON),我们也无法利用这个存储服务来完成依据结构而进行的查询等等操作了。
公众号:码农架构