Nosql数据库是非关系的、水平可扩展、分布式并且是开源的。MongoDB的创始人Dwight Merriman表示Nosql可作为一个Web应用服务器、内容管理器、结构化的事件日志、移动应用程序的服务器端和文件存储的后备存储。
分布式数据库公司VoltDB的首席技术官Michael Stonebraker表示Nosql数据库可提供良好的扩展性和灵活性,但他们也有自己的不足。由于不使用sql,Nosql数据库系统不具备高度结构化查询等特性。Nosql其他的问题还包括不能提供ACID(原子性、一致性、隔离性和持久性)的操作。另外不同的Nosql数据库都有自己的查询语言,这使得很难规范应用程序接口。
Nosql数据库按类型可以飞为键值数据库(Key-value)、文档数据库(Document)、列族数据库(Column store)、图数据库(Graph)等。
键值数据库
Oracle | Riak |
---|---|
database instance | Riak cluster |
table | bucket |
row | key-value |
rowid | key |
键值数据库包括Aerospike、riak、redis、memcached等。
键值数据库的特征如下:
- 不同的键值数据库产品,器"事务"的规范也不同,但一般来说,无法保证写入操作的“一致性”;
- 所有的键值数据库都可以按关键字查询。如果想根据“值列”的某些属性来查询,需要应用程序自己读出值,并判断其属性是否符合查询条件;
- 键值数据库并不关心键值对里的值,它可以是二进制块、文本、JSON、XML等;
- 很多键值数据库都可以用“分片”技术扩展,通常键的名字就决定了负责存储该键的节点。
文档数据库
此类数据库可存放并获取文档,格式可以为XML、JSON、BSON(Binary JSON)等。数据库中的文档批次相似,但不必完全相同,文档相当于键值数据库所存放的“值”。下面是Oracle和MongoDB的术语对照:
Oracle | MongoDB |
---|---|
database instance | MongoDB instance |
schema | database |
table | collection |
row | document |
rowid | _id |
join | DBRef |
文档数据库的文档可以包含子文档,形成一个树状结果,例如:
{ "firstname": "Pramod","citiesvisited": ["Chicago","London","Pune","Bangalore"],"addresses": [ { "state": "AK","city": "DILLINGHAM","type": "R" },{ "state": "MH","city": "PUNE" } ] "lastcity": "Chicago" }文档数据库的文档没有空属性,若其中不存在某属性,则认为该属性值未设定或者与此文档无关,向文档中新增属性,无需预先定义,也不用修改已有文档内容。
当前流行的文档数据库有:MongoDB、CouchDB、Terrastore、OrientDB、RavenDB等。
文档数据库的特性如下:
- 文档数据库通常仅包含“单文档级别”的“事务”,也称为“原子事务”。在默认情况下,所有写入操作都将顺利执行,在MongoDB中使用WriteConcern参数可以微调;
- 文档数据库通过主从式数据复制技术来增强“可用性”,多个节点保存同一份数据,当主节点故障后,客户端可从从节点获取数据;
- 各种文档数据库对查询提供了不同的支持,但通常都支持使用键值作为条件来查询,这个特性使得文档数据库的查询功能更接近关系型数据库的查询模型;
- 对于写少读多的场景,文档数据库通过增加“读取从节点”(read slave)来扩展数据库应对频繁读取的能力;而如果要扩展写入能力,则可以把数据“分片”,“分片”操作需要根据特定字段来划分数据,为了让“分片”的负载保持均衡,需要在节点之间动态转移数据。
列族数据库
列族数据库可以存储关键字及其映射值,并且可以把值分为多个列,让每个列代表一张数据映射表。
Oracle | Cassandra |
---|---|
database instance | cluster |
schema | keyspace |
table | column family |
row | row |
column | column |
列族数据库将数据存储在列族中,而列族里的行则把许多列数据关联起来,例如下面的结构:
在Cassandra中,基本存储单元叫做“列”,列中包含列名、值和时间戳,时间戳用于数据过期、解决写入冲突、处理陈旧数据等操作,结构如下:
{ name: "name",value: "Mike",timestamp: 1234567890 }行是列的集合,列都属于某个关键字下,由相似行构成的集合就是列族:
//列族 { //行 "pramod-sadalage" : { firstName: "Pramod",lastName: "Sadalage",lastVisit: "2012/12/12" } //行 "martin-fowler" : { firstName: "Martin",lastName: "Fowler",location: "Boston" } }列族数据库的各行不一定要具备完全相同的列,并且可以随意向其中某列加入一行,而不用把它添加到其他行中。
列族数据库具有如下特性:
- 通常仅支持“行”级别的“原子性”;
- 可以根据应用需求来设置读/写操作的可用性:要么提高写入操作的“可用性”,要么提高读取操作的“可用性”;
- 可支持部分的类sql的查询功能,但功能有限,不支持join和subquery操作,wehere子句通常也比较简单;
- 可通过增加节点来扩展数据库。