为什么要有NoSQL,关系数据库有什么问题
- 不能存储复杂数据结构(所以有了K-V数据库:Redis)
- scheme不好扩展(-> 文档数据库)
- 大数据场景下I/O较高(-> 列式存储 Hbase)
即使读取某列数据,关系数据库也要将整行数据读取到内存
- 全文搜索能力较弱(ES,luence)
K-V存储
优点:复杂数据结构的存储和读取简单:如读取队列第一个元素并出队列
缺点:不支持完整的ACID;Redis支持事务,但只支持I和C,不支持A和D
文档数据库
优点:scheme非常容易扩展,并且新增字段对老数据也无影响,可以很容易的存储复杂数据
缺点:MongoDB不支持事务;无法实现join操作(要查两次)
列式存储
关系数据库按照行来存取数据的好处:
- 读取多列时效率高:列都是按行存储在一起的,一次磁盘操作就能把所有需要的列读取出来
- 存储时,能够一次性完成一行中多列的写操作,保证了针对于行数据写操作的原子性和一致性。否则如果采用列存储,可能出现某些列写成功了,某些列写失败了,导致数据不一致
列式存储:
优势:
- 大数据量的统计操作场景下,节省IO效率,只需读取单列。(整列数据是存储在一块的)
- 压缩比好。单个列的数据相似度较高
劣势:
- 频繁的更新多列时,对磁盘是随机写,效率低;(不同列存储不连续)
全文搜索
- 原理:倒排索引
- 为什么叫倒排索引? 单词到文档的索引;(正排索引指文档到单词的索引;比如根据文章标题查询展示文章内容)
全文搜索引擎支持 关系数据库数据 的搜索,怎么做?
将RDB数据 -> JSON文档 -> 导入 ES
问题
- 文档数据库(如MongoDB)和ES有什么区别,他们都没有scheme的约束
文档数据库定位于存储和访问,ES定位于搜索。但目前差别不是很大,因为系统边界的扩充,就像MongoDB要支持ACID,mysql要支持文档存储
- 跨库操作如何保证最终一致性 / 写mysql,同时写ES,如何保证一致性?
土的方法是 记录操作日志 + 定时校验;牛逼的是 采用分布式一致性算法