---
# System prepended metadata

title: 各个类型的数据库的优劣势的分析
tags: [database]

---

# 各个类型的数据库的优劣势的分析
---

## K-V 存储

**描述**

K-V 存储的全称是 Key-Value 存储，其中 Key 是数据的标识，和关系数据库中的主键含义一样，Value 就是具体的数据。

**优势**

Redis 是 K-V 存储的典型代表，它是一款开源（基于 BSD 许可）的高性能 K-V 缓存和存储系统。Redis 的 Value 是具体的数据结构，包括 string、hash、list、set、sorted set、bitmap 和 hyperloglog，所以常常被称为数据结构服务器。

**劣势**

Redis 的缺点主要体现在并不支持完整的 ACID 事务，Redis 虽然提供事务功能，但 Redis 的事务和关系数据库的事务不可同日而语，Redis 的事务只能保证隔离性和一致性（I 和 C），无法保证原子性和持久性（A 和 D）。虽然 Redis 并没有严格遵循 ACID 原则，但实际上大部分业务也不需要严格遵循 ACID 原则。以上面的微博关注操作为例，即使系统没有将 A 加入 B 的粉丝列表，其实业务影响也非常小，因此我们在设计方案时，需要根据业务特性和要求来确定是否可以用 Redis，而不能因为 Redis 不遵循 ACID 原则就直接放弃。

## 文档数据库

**描述**

为了解决关系数据库 schema 带来的问题，文档数据库应运而生。文档数据库最大的特点就是 no-schema，可以存储和读取任意的数据。目前绝大部分文档数据库存储的数据格式是 JSON（或者 BSON），因为 JSON 数据是自描述的，无须在使用前定义字段，读取一个 JSON 中不存在的字段也不会导致 SQL 那样的语法错误。

**优势**

1. 新增字段简单
    - 业务上增加新的字段，无须再像关系数据库一样要先执行 DDL 语句修改表结构，程序代码直接读写即可。
2. 历史数据不会出错
    - 对于历史数据，即使没有新增的字段，也不会导致错误，只会返回空值，此时代码进行兼容处理即可。
3. 可以很容易存储复杂数据
    - JSON 是一种强大的描述语言，能够描述复杂的数据结构。

**劣势**

- 不支持事务。
- 无法实现关系数据库的 join 操作。

## 列式数据库

**描述**

列式数据库就是按照列来存储数据的数据库
**优势**

- 除了节省 I/O
- 列式存储还具备更高的存储压缩比，能够节省更多的存储空间。

**劣势**
- 列式存储将不同列存储在磁盘上不连续的空间，导致更新多个列时磁盘是随机写操作
- 列式存储高压缩率在更新场景下也会成为劣势，更新时需要将存储数据解压后更新，然后再压缩，最后写入磁盘。

## 行式数据库

**描述**

按照行来存储数据的（比如：关系数据库）

**优势**

- 业务同时读取多个列时效率高，因为这些列都是按行存储在一起的，一次磁盘操作就能够把一行数据中的各个列都读取到内存中。能够一次性完成对一行中的多个列的写操作，保证了针对行数据写操作的原子性和一致性；否则如果采用列存储，可能会出现某次写操作，有的列成功了，有的列失败了，导致数据不一致。
- 行式存储时同一行多个列都存储在连续的空间，一次磁盘写操作就可以完成，列式存储的随机写效率要远远低于行式存储的写效率。

**劣势**

- 某种场景下，I/O会有一些浪费
- 某种场景下，存储压缩比可能不如列式数据库

## 全文搜索引擎

### 关系数据库的全文搜索的缺陷

- 全文搜索的条件可以随意排列组合，如果通过索引来满足，则索引的数量会非常多。
- 全文搜索的模糊匹配方式，索引无法满足，只能用 like 查询，而 like 查询是整表扫描，效率非常低。

**描述**

- 全文搜索引擎的技术原理被称为“倒排索引”（Inverted index），也常被称为反向索引、置入档案或反向档案，是一种索引方法，其基本原理是建立单词到文档的索引。（“正排索引” 的基本原理是建立文档到单词的索引）

**优势**

- 全文搜索引擎的索引对象是单词和文档
- 关系数据库的索引对象是键和行
- 为了让全文搜索引擎支持关系型数据的全文搜索，需要做一些转换操作，即将关系型数据转换为文档数据。目前常用的转换方式是将关系型数据按照对象的形式转换为 JSON 文档，然后将 JSON 文档输入全文搜索引擎进行索引。
- 全文搜索引擎能够基于 JSON 文档建立全文索引，然后快速进行全文搜索。

**劣势**

- 相对来说可能会依赖JSON文件的正确性吧

###### tags: `database`

