把几种完全不同的东西统称为NoSQL的原因:基于文档模型的 MongoDB、基于键-值对模型的 Redis等等这些非关系型数据库有其各自独特的特点和适用场景,但它们都没有采用传统关系型数据库的表格设计和 SQL 查询语法,因此被统称为 NoSQL。
一、把几种完全不同的东西统称为NoSQL的原因
将几种完全不同类型的非关系型数据库统称为NoSQL主要是从历史和技术发展的角度考虑。在关系型数据库还没有出现时,数据的存储和访问都是非结构化的,比如文件系统、哈希表等。当关系型数据库出现后,其结构化的模型和 SQL 查询对于数据管理和查询提供了更加方便和高效的方法,逐渐成为主流。
但是,随着互联网和大数据的发展,传统关系型数据库已经无法满足复杂且大规模数据的存储和处理需求。针对这些问题,出现了多种非关系型数据库,比如基于文档模型的 MongoDB、基于键-值对模型的 Redis、基于图模型的 Neo4j 等等。这些非关系型数据库有其各自独特的特点和适用场景,但它们都没有采用传统关系型数据库的表格设计和 SQL 查询语法,因此被统称为 NoSQL(Not Only SQL)。
二、NoSQL数据库的类型
1、 键值(Key-Value)数据库
键值数据库就像在传统语言中使用的哈希表。你可以通过key来添加、查询或者删除数据,鉴于使用主键访问,所以会获得不错的性能及扩展性。
- 产品:Riak、Redis、Memcached、Amazon’s Dynamo、Project Voldemort
- 有谁在使用:GitHub (Riak)、BestBuy (Riak)、Twitter (Redis和Memcached)、StackOverFlow (Redis)、 Instagram (Redis)、Youtube (Memcached)、Wikipedia(Memcached)
适用的场景:储存用户信息,比如会话、配置文件、参数、购物车等等。这些信息一般都和ID(键)挂钩,这种情景下键值数据库是个很好的选择。
不适用场景:
- 取代通过键查询,而是通过值来查询。Key-Value数据库中根本没有通过值查询的途径。
- 需要储存数据之间的关系,在Key-Value数据库中不能通过两个或以上的键来关联数据。
- 事务的支持,在Key-Value数据库中故障产生时不可以进行回滚。
2、 面向文档(Document-Oriented)数据库
面向文档数据库会将数据以文档的形式储存。每个文档都是自包含的数据单元,是一系列数据项的集合。每个数据项都有一个名称与对应的值,值既可以是简单的数据类型,如字符串、数字和日期等;也可以是复杂的类型,如有序列表和关联对象。数据存储的最小单位是文档,同一个表中存储的文档属性可以是不同的,数据可以使用XML、JSON或者JSONB等多种形式存储。
- 产品:MongoDB、CouchDB、RavenDB
- 有谁在使用:SAP (MongoDB)、Codecademy (MongoDB)、Foursquare (MongoDB)、NBC News (RavenDB)
适用的场景:
- 日志。企业环境下,每个应用程序都有不同的日志信息。Document-Oriented数据库并没有固定的模式,所以我们可以使用它储存不同的信息。
- 分析。鉴于它的弱模式结构,不改变模式下就可以储存不同的度量方法及添加新的度量。
不适用场景:在不同的文档上添加事务。Document-Oriented数据库并不支持文档间的事务,如果对这方面有需求则不应该选用这个解决方案。
3、 列存储(Wide Column Store/Column-Family)数据库
列存储数据库将数据储存在列族(column family)中,一个列族存储经常被一起查询的相关数据。举个例子,如果我们有一个Person类,我们通常会一起查询他们的姓名和年龄而不是薪资。这种情况下,姓名和年龄就会被放入一个列族中,而薪资则在另一个列族中。
- 产品:Cassandra、HBase
- 有谁在使用:Ebay (Cassandra)、Instagram (Cassandra)、NASA (Cassandra)、Twitter (Cassandra and HBase)、Facebook (HBase)、Yahoo!(HBase)
适用的场景:
- 日志。因为我们可以将数据储存在不同的列中,每个应用程序可以将信息写入自己的列族中。
- 博客平台。我们储存每个信息到不同的列族中。举个例子,标签可以储存在一个,类别可以在一个,而文章则在另一个。
不适用场景:
- 如果我们需要ACID事务,Vassandra就不支持事务。
- 原型设计,如果我们分析Cassandra的数据结构,我们就会发现结构是基于我们期望的数据查询方式而定。在模型设计之初,我们根本不可能去预测它的查询方式,而一旦查询方式改变,我们就必须重新设计列族。
4、 图(Graph-Oriented)数据库
图数据库允许我们将数据以图的方式储存。实体会被作为顶点,而实体之间的关系则会被作为边。比如我们有三个实体,Steve Jobs、Apple和Next,则会有两个“Founded by”的边将Apple和Next连接到Steve Jobs。
- 产品:Neo4J、Infinite Graph、OrientDB
- 有谁在使用:Adobe (Neo4J)、Cisco (Neo4J)、T-Mobile (Neo4J)
适用的场景:
- 在一些关系性强的数据中
- 推荐引擎。如果我们将数据以图的形式表现,那么将会非常有益于推荐的制定不适用场景不适合的数据模型。图数据库的适用范围很小,因为很少有操作涉及到整个图。
三、流行的NoSQL数据库
1、Redis
- 所用语言:C/C++
- 特点:运行异常快
- 使用许可:BSD
- 协议:类 Telnet
- 有硬盘存储支持的内存数据库,
- 但自2.0版本以后可以将数据交换到硬盘(注意, 2.4以后版本不支持该特性!)
- Master-slave复制(见编注3)
- 虽然采用简单数据或以键值索引的哈希表,但也支持复杂操作,例如 ZREVRANGEBYSCORE。
- INCR & co (适合计算极限值或统计数据)
- 支持 sets(同时也支持 union/diff/inter)
- 支持列表(同时也支持队列;阻塞式 pop操作)
- 支持哈希表(带有多个域的对象)
- 支持排序 sets(高得分表,适用于范围查询)
- Redis支持事务
- 支持将数据设置成过期数据(类似快速缓冲区设计)
- Pub/Sub允许用户实现消息机制
优异应用场景:适用于数据变化快且数据库大小可遇见(适合内存容量)的应用程序。
例如:股票价格、数据分析、实时数据搜集、实时通讯。
2、MongoDB
- 所用语言:C++
- 特点:保留了SQL一些友好的特性(查询,索引)。
- 使用许可:AGPL(发起者:Apache)
- 协议:Custom, binary( BSON)
- Master/slave复制(支持自动错误恢复,使用 sets 复制)
- 内建分片机制
- 支持 javascript表达式查询
- 可在服务器端执行任意的 javascript函数
- update-in-place支持比CouchDB更好
- 在数据存储时采用内存到文件映射
- 对性能的关注超过对功能的要求
- 建议较好打开日志功能(参数 –journal)
- 在32位操作系统上,数据库大小限制在约2.5Gb
- 空数据库大约占 192Mb
- 采用 GridFS存储大数据或元数据(不是真正的文件系统)
优异应用场景:适用于需要动态查询支持;需要使用索引而不是 map/reduce功能;需要对大数据库有性能要求;需要使用 CouchDB但因为数据改变太频繁而占满内存的应用程序。
例如:你本打算采用 MySQL或 PostgreSQL,但因为它们本身自带的预定义栏让你望而却步。
3、Riak
- 所用语言:Erlang和C,以及一些Javascript
- 特点:具备容错能力
- 使用许可:Apache
- 协议:HTTP/REST或者 custom binary
- 可调节的分发及复制(N, R, W)
- 用 JavaScript or Erlang在操作前或操作后进行验证和安全支持。
- 使用JavaScript或Erlang进行 Map/reduce
- 连接及连接遍历:可作为图形数据库使用
- 索引:输入元数据进行搜索(1.0版本即将支持)
- 大数据对象支持( Luwak)
- 提供“开源”和“企业”两个版本
- 全文本搜索,索引,通过 Riak搜索服务器查询( beta版)
- 支持Masterless多站点复制及商业许可的 SNMP监控
优异应用场景:适用于想使用类似 Cassandra(类似Dynamo)数据库但无法处理 bloat及复杂性的情况。适用于你打算做多站点复制,但又需要对单个站点的扩展性,可用性及出错处理有要求的情况。
例如:销售数据搜集,工厂控制系统;对宕机时间有严格要求;可以作为易于更新的 web服务器使用。
4、Membase
- 所用语言:Erlang和C
- 特点:兼容 Memcache,但同时兼具持久化和支持集群
- 使用许可:Apache 2.0
- 协议:分布式缓存及扩展
- 非常快速(200k+/秒),通过键值索引数据
- 可持久化存储到硬盘
- 所有节点都是少数的( master-master复制)
- 在内存中同样支持类似分布式缓存的缓存单元
- 写数据时通过去除重复数据来减少 IO
- 提供非常好的集群管理 web界面
- 更新软件时软无需停止数据库服务
- 支持连接池和多路复用的连接代理
优异应用场景:适用于需要低延迟数据访问,高并发支持以及高可用性的应用程序。
延伸阅读1:什么是NoSQL
NoSQL(Not only SQL)是对不同于传统的关系数据库的数据库管理系统的统称,即广义地来说可以把所有不是关系型数据库的数据库统称为NoSQL。NoSQL 数据库专门构建用于特定的数据模型,并且具有灵活的架构来构建现代应用程序。NoSQL 数据库使用各种数据模型来访问和管理数据。这些类型的数据库专门针对需要大数据量、低延迟和灵活数据模型的应用程序进行了优化,这是通过放宽其他数据库的某些数据一致性限制来实现的。