数据库——NoSQL
-
全称 Not Only SQL,非关系型数据库
- 指的是除了关系型以外的其他类型数据库
-
好处
- 没有基于表关系建模,没有SQL多表连查的性能顾虑,范式约束也不存在
- 把一部分工作转移到应用层,更容易做扩展
- 不必预先定义数据模式,支持存取快速变化的各种结构的数据
- 读写性能很高
-
缺点
- 大多数不提供事务支持
- 分布式下只提供最终一致性(不能立刻读到最新的数据),至于强一致性需要应用层处理
-
有4种分类
-
键值存储key-value store- 数据模型是哈希表,能达到O(1)的读写性能
- 经常用作
内存缓存- 只把值存下来,不管它是什么
- 比如Redis、Memcached等
-
文档存储Document store- 以文档(XML、JSON等半结构化数据)为中心建模
- 相当于增强版的键值存储,提供更精细的数据操作
- 数据库能理解并处理所存储的值
- 根据值的特征查询和建立索引
- 经常用作
持久化存储 - 比如MongoDB、CouchDB等
-
宽列存储Wide column store- 数据模型是二维Map
- 列是最小的数据单元,多列可以进一步构成超级列,多个列(或多个超级列)可以组成一个列族,一个列族可以看成一行,代表一个实体,包含该实体所有信息
- 适用于非常大的数据集
- 被Twitter、Facebook等社交网络用来存储海量用户产生的数据
- 比如HBase、Cassandra、Bigtable
-
图形数据库Graph store- 数据模型是图
- 图中每个节点代表一条记录,每条边表示节点之间的关系
- 适用于描述复杂的多对多关系
- 比如社交网络关系
- 比如Neo4j、Oracle Spatial and Graph、ArangoDB
-
-
用作缓存
-
全称 Caching
-
在 应用层 和 数据存储 之间加上键值存储,通过内存去缓存高频数据,尽量减少数据库操作,吸收不均匀的负载和流量高峰
-
两种缓存模式
-
不建议缓存查询结果,因为源数据变化后,很难判定缓存是否过期,难以精确删除
-
建议缓存对象
- 缓存根据 原始数据 组装出的 数据模型(比如一个Java类实例)
- 优势在于获知数据变化后,能够丢弃与之具有逻辑关联的对象,解决缓存过期的难题
-
-
六种缓存访问策略
-
预留缓存
- 缓存位于数据库一旁,没有直接关系
- 由应用程序负责处理,请求优先走缓存
- 如果没命中,就由应用程序跑到数据库取出,并把结果缓存起来
- 是按需的,实际访问过才会缓存起来
- 缺点
- 未命中的话,需要多走一遍缓存,有延迟
- 缓存可能变旧(可设置TTL强制更新)
-
直读式
- 缓存挡在数据库前面,查数据由缓存代查
-
直写式
- 缓存挡在数据库前面,写数据先写到缓存,再同步写入数据库
- 可与 直读式 结合
-
回写式
- 缓存挡在数据库前面,写数据先写到缓存,在异步写入数据库(可通过批处理及写操作合并,提高性能,但仅保证最终一致性)
- 可与 直读式 结合
-
绕写式
- 写操作不经过缓存,由应用程序直接写入数据库
-
提前刷新
- 在缓存过期前,自动刷新最近访问过的条目,通过预加载减少延迟
- 但如果预测不准,反而性能下降
-
-
四种缓存逐出策略(防止缓存爆满)
- LRU
- 全称 Least Recently Used
- 最常用,将最近没有用到的最久远数据剔除
- LFU
- 全称 Least Frequently Used
- 根据使用频率剔除
- MRU
- 全称 Most Recently Used
- 有些情况,需要删除最近用过的,比如已读,不再提醒
- FIFO
- 先进先出,剔除最早访问过的数据
- LRU
-