CRUD即是增删查改操作,NoSQL是一类数据库,其有一个共有的突出特征:创建和读取操作比更新和删除操作更重要。
创建纪录
- 唯一主键在关系型和非关系型数据库中都很重要。
- MongoDB中没有数据库join的概念,因此要么在客户端利用对象标识符手工实现join操作,要么利用DBRef。
- 面向列数据库没有定义任何关系引用的概念。因为它也避免了集合之间的连接。列数据库里数据是这样存储的:每个行健唯一标识一条记录,一个列族的所有列存储在一起。面向列的数据库,特别是HBase,也有一个保存数据的时间维度,这样创建(插入)操作很重要,而没有更新操作。
HBase是数据的结构扁平化,只有列族和他包含的列之间才有层次关系。此外,他还按照时间维度存储每个单元格的数据,所以讲数据存储入HBase前,需要对嵌套的数据进行扁平化处理。
- Redis为代表的键值对映射表是一种简单强大的数据结构服务器,支持以简单的键值对或者集合元素的形式来存储数据。每个键值对可以是独立的字符串映射表,也可以放在集合里。一个集合可以是一下任何类型:列表,有序表,无序表,哈希表等。单独的字符串键值对很想一个可以接受字符串值的变量。
访问数据
- MongoDB数据集是嵌套文档,所以能按嵌套属性值查询,可以用点符号遍历,访问任何嵌套字段(db.orders.find( { “line_items.item.name” : “latte” } ) )。MongoDB的表达式匹配支持使用正则表达式。
在关系型数据库中,索引很好改进了查询速度,工作方式非常简单,提供了基于B树结构的查询机制,MongoDB也支持索引,所有集合都按_id值索引。MongoDB还可自由建立二级索引,二级索引可以健在顶层字段或者嵌套字段上。
- HBase上基于行健的查询是最简单最高效的。行键是有序的,且连续的行健存储在一起。行键建立很重要,应该在语义上与数据关联起来。但是没有二级索引。如果想要建立可以用第三方工具,如Lucene(搜索引擎框架)。
- Redis一般用get,还有集合操作等。
更新和删除数据
- 关系型数据库建立在ACID(原子性,一致性,隔离性,持久性)语义之上,以此为基础提供数据库完整性,并对数据的更新和修改支持不同的隔离级别。
- NoSQL并不重视ACID事务。
- 锁概念在NoSQL中不存在。但有些技巧可以帮助实现院子的数据更新,MongoDB是更新整个文档而不是字段,可用原子性方法包括:
- $set,如{ $set : { "order_data" : new Date (2010, 10. 01 ) } }
- $inc
- $push
- $pushAll
- $pull
- $pullAll
- $set,如{ $set : { "order_data" : new Date (2010, 10. 01 ) } }
- 另一种策略是如果没变就更新:
- 获取对象
- 在本地修改对象
- 发送一个更新请求:如果对象还能匹配旧值的话,就把它更新成这个新值。
- 文档或行级锁,原子性也适用于HBase,其支持行级别的读写锁。但是空行除外,因为它会一直不可用知道超时。
- Redis支持有限的事务,一个操作可以在这样的事务的范围内执行。Redis的MULTI命令会初始化一个事务。执行MULTI以后用EXEC执行所有命令,用DISCARD回滚操作。
有限原子性和事务完整性
- CAP理论指出以下三个目标同时只能最大化两个:
- 一致性:每个用户都看到同样的数据
- 可用性:每个用户都可读写
- 分区容忍性:系统跨越分布式物理网络仍然工作良好。
- 最终一致性是用在并行编程和分布式编程领域中的一致性模型。
- 给定足够长一段时间,期间无更新,就可认为所有更新最终会传播到整个网络,包括所有副本。
- 当存在持续的更新时,一个被接受的更新最终要么到达副本,要么重试。
- 与ACID相对,最终一致性表示基本可用(basically available),软状态(soft state),以及最终一致(eventual consistency),称为BASE。