传统关系数据库一度占据商业数据库应用的主流位置
但是关系数据库无法满足 Web 2.0和大数据时代的需求
关系数据库中的关键特性包括完善的事务机制和高效的查询机制在Web 2.0时代没有发挥
在这样的新的应用背景下,关系数据库实在难以满足要求,于是 NoSQL 数据库就应运而生了。
NoSQL
(Not Only SQL)是对非关系型数据库的统称,采用的是类似键/值、列族、文档等非关系模型。
NoSQL数据库没有固定的表结构,通常也不存在连接操作,也没有严格遵守 ACID 约束。和关系型数据库相比,NoSQL具有灵活的水平拓展性,可以支持海量数据的存储。
NoSQL数据库具有以下三个特点:
关系数据库
NoSQL数据库
比较标准 | 关系数据库RDBMS | NoSQL | 备注 |
---|---|---|---|
数据库原理 | 完全支持 | 部分支持 | RDBMS有关系代数理论作为基础 NoSQL没有统一的理论基础 |
数据规模 | 大 | 超大 | RDBMS很难实现横向扩展,纵向扩展的空间也比较有限,性能会随着数据规模的增大而降低 NoSQL可以很容易通过添加更多设备来支持更大规模的数据 |
数据库模式 | 固定 | 灵活 | RDBMS需要定义数据库模式,严格遵守数据定义和 相关约束条件 NoSQL不存在数据库模式,可以自由灵活定义并存 储各种不同类型的数据 |
查询效率 | 快 | 可以实现高效的简单查询,但是不具备高度结构化查询等特性,复杂查询的性能不尽人意 | RDBMS借助于索引机制可以实现快速查询(包括记 录查询和范围查询) 很多NoSQL数据库没有面向复杂查询的索引 |
一致性 | 强一致性 | 弱一致性 | RDBMS严格遵守事务ACID模型,可以保证事务强一致性 很多NoSQL数据库放松了对事务ACID四性的要求, 而是遵守BASE模型,只能保证最终一致性 |
数据完整性 | 容易实现 | 很难实现 | 任何一个RDBMS都可以很容易实现数据完整性,比如通过主键或者非空约束来实现实体完整性,通过主键、外键来实现参照完整性,通过约束或者触发器来实现用户自定义完整性 但是,在NoSQL数据库却无法实现 |
扩展性 | 一般 | 好 | RDBMS很难实现横向扩展,纵向扩展的空间也比较有限 NoSQL在设计之初就充分考虑了横向扩展的需求, 可以很容易通过添加廉价设备实现扩展 |
可用性 | 好 | 很好 | RDBMS在任何时候都以保证数据一致性为优先目标,其次才是优化系统性能,随着数据规模的增大,RDBMS为了保证严格的一致性,只能提供相对较弱的可用性 大多数NoSQL都能提供较高的可用性 |
标准化 | 是 | 否 | RDBMS已经标准化(SQL) NoSQL还没有行业标准,不同的NoSQL数据库都有自己的查询语言,很难规范应用程序接口 |
技术支持 | 高 | 低 | RDBMS经过几十年的发展,已经非常成熟,Oracle 等大型厂商都可以提供很好的技术支持 NoSQL在技术支持方面还不成熟,缺乏有力的技术支持 |
可维护性 | 复杂 | 复杂 | RDBMS需要专门的数据库管理员(DBA)维护 NoSQL数据库虽然没有DBMS复杂,也难以维护 |
关系数据库和NoSQL数据库各有优缺点,彼此无法取代
有时候也会采用混合架构,比如使用不同类型的数据库来支撑电子商务应用。
MongoDB
的文档数据库中典型的NoSQL数据库通常包括:
键值数据库(Key-Value Database)会使用一个哈希表,这个表中有一个特定的 Key 和一个指针指向特定的 Value。Key可以用来定位 Value,即存储和检索具体的 Value。
Value可以用来存储任意类型的数据,包括整形、字符型、数组、对象等。但是,Value 对数据库而言是透明不可见的,不能对 Value 进行索引和存储,只能通过 Key 进行查询。
键值数据库可以进一步划分为内存键值数据库和持久化键值数据库。
Memcached
、Redis
BerkeleyDb
、Riak
键值数据库有自身的局限,条件查询就是键值数据库的弱项。因此,在使用键值数据库时,应该尽量避免多表关联查询,可以采用双向冗余存储关系来替代表关联,把操作分解为单表操作。
项目 | 描述 |
---|---|
相关产品 | Redis、Riak、SimpleDB、Chordless、Memcached |
数据模型 | 键/值对 键是一个字符串对象 值可以是任意类型的数据,比如整型、字符型、数组、列表、集合等 |
典型应用 | 拥有简单数据模型的应用,涉及频繁读写 内容缓存,比如会话、配置文件、参数、购物车等 |
优点 | 扩展性好,灵活性好,大量写操作时性能高 |
缺点 | 无法存储结构化信息,条件查询效率较低 |
不适用情景 | 不是通过键而是通过值来查:键值数据库没有通过值查询的途径 需要存储数据之间的关系:在键值数据库中,不能通过两个或两个以上的键来关联数据 需要事务的支持:在一些键值数据库中,产生故障时,不可以回滚 |
使用者 | 百度云数据库(Redis)、GitHub(Riak)、BestBuy(Riak)、Twitter(Redis和 Memcached)、StackOverFlow(Redis)、Instagram (Redis)、Youtube (Memcached)、Wikipedia(Memcached) |
目前使用最多的是 Redis,被称为“强化版的Memcached”,被广泛应用在数据缓存方面
列族数据库一般采用列族数据模型,数据库由多个行组成,每行数据包含多个列族,不同的行可以具有不同数量的列族,属于同一列族的数据会被存放在一起。
项目 | 描述 |
---|---|
相关产品 | BigTable、HBase、Cassandra、Hypertable、GreenPlum等 |
数据模型 | 列族 |
典型应用 | 分布式数据存储与管理 数据在地理上分布于多个数据中心的应用程序 可以容忍副本中存在短期不一致情况的应用程序 拥有动态字段的应用程序 拥有潜在大量数据的应用程序,大到几百TB的数据 |
优点 | 查找速度快,可扩展性强,容易进行分布式扩展,复杂性低 |
缺点 | 功能较少,大都不支持强事务一致性 |
不适用情景 | 需要ACID事务支持的情形,Cassandra等产品就不适用 |
使用者 | Ebay(Cassandra)、Instagram(Cassandra)、NASA(Cassandra)、 Twitter(Cassandra and HBase)、Facebook(Cassandra)、Yahoo! (HBase) |
在文档数据库中,文档是数据库的最小单位。文档是一个数据记录,这个记录能够对包含的数据类型和内容进行“自我描述。文档数据库旨在将半结构化数据存储为文档,通常用XML、 JSON 等文档格式来封装和编码数据。
一个文档可以包含非常复杂的数据结构,如嵌套对象,且每个文档可以有完全不同的数据结构,每一条记录包含了所有的有关信息而没有任何外部的引用,这条记录就是“自包含”的,这使得记录很容易完成数据迁移。
文档数据库既可以根据键(Key)来构建索引,也可以根据文档内容构建索引。尤其是基于文档内容的索引和查询这种能力,是文档数据库不同于键值数据库的地方。
项目 | 描述 |
---|---|
相关产品 | MongoDB、CouchDB、Terrastore、MarkLogic、RavenDB |
数据模型 | 键/值 值(value)是版本化的文档 |
典型应用 | 存储、索引并管理面向文档的数据或者类似的半结构化数据 比如,用于后台具有大量读写操作的网站、使用JSON数据结构的应用、 使用嵌套结构等非规范化数据的应用程序 |
优点 | 性能好(高并发),复杂性低,数据结构灵活 提供嵌入式文档功能,将经常查询的数据存储在同一个文档中 既可以根据键来构建索引,也可以根据内容构建索引 |
缺点 | 缺乏统一的查询语法 |
不适用情景 | 在不同的文档上添加事务。文档数据库并不支持文档间的事务,如果对 这方面有需求则不应该选用这个解决方案 |
使用者 | 百度云数据库(MongoDB)、SAP (MongoDB)、Codecademy (MongoDB)、Foursquare (MongoDB)、NBC News (RavenDB) |
图数据库使用图作为数据模型来存储数据,完全不同于键值、文档和列族数据模型,可以高效地存储不同顶点之间的关系。图数据库专门用来处理具有高度相互关联关系的数据,可以高效地处理实体之间的关系,比较适合于社交网络、模式识别、依赖分析、推荐系统以及路径寻找等问题。
但是,除了在处理图和关系这些应用领域具有很好的性能之外,在别的领域,图数据库的性能不如其他 NoSQL 数据库。
项目 | 描述 |
---|---|
相关产品 | Neo4J、Infinite Graph、GraphDB |
数据模型 | 图结构 |
典型应用 | 应用于大量复杂、互连接、低结构化的图结构场合,如社交网络、推荐系统等 |
优点 | 灵活性高,支持复杂的图形算法,可用于构建复杂的关系图谱 |
缺点 | 复杂性高,只能支持一定的数据规模 |
使用者 | Adobe(Neo4J)、Cisco(Neo4J)、T-Mobile(Neo4J) |
MySQL
MongoDB
HBase
Redis
NoSQL的三大基石包括 CAP、BASE 和最终一致性。
CAP理论指的是:
CAP理论告诉我们,一个分布式系统不可能同时满足一致性、可用性和分区容忍性这三个需求,最多只能同时满足其中两个。
处理CAP的问题时的选择:
数据库事务的 ACID 特性
关系数据库系统设计了复杂的事务管理机制来保证事务在执行过程中严格满足 ACID 的要求,较好地满足了银行等领域对数据一致性的要求,因此得到了广泛的商业应用。
但是,NoSQL 数据库通常应用与 Web 2.0网站等应用场景中,对数据一致性要求并不是很高,而是强调系统的高可用性。因此为了获得高可用性,可以考虑适当牺牲一致性或分区容忍性。BASE的基本思想就是在这个基础上发展起来的,是完全不同于 ACID 模型的,BASE 牺牲了高一致性,从而获得了可用性或可靠性。
BASE 的基本含义是 基本可用
、软状态
和 最终一致性
。
最终一致性根据更新数据后各进程访问到数据的时间和方式的不同,又可以区分为:
因果一致性 (Causal consistency):如果进程A通知进 程B它已更新了一个数据项,那么进程B的后续访问将获 得A写入的最新值。而与进程A无因果关系的进程C的访 问,仍然遵守一般的最终一致性规则
“读己之所写”一致性 (Read your writes):可以视为 因果一致性的一个特例。当进程A自己执行一个更新操 作之后,它自己总是可以访问到更新过的值,绝不会看 到旧值
会话一致性 (Session consistency):系统能保证在同 一个有效的会话中实现 “读己之所写” 的一致性,也 就是说,执行更新操作之后,客户端能够在同一个会话 中始终读取到该数据项的最新值
单调读一致性:如果进程已经看到过数据对象的某个值, 那么任何后续访问都不会返回在那个值之前的值
单调写一致性:系统保证来自同一个进程的写操作顺序 执行,对于多副本系统来说,保证写顺序的一致性(串 行化),是很重要的
在分布式数据系统中,将数据冗余的份数记为N,更新数据时需要保证写完成的节点数记为W,读取数据时需要读取的节点数记为R。
对于分布式系统,为了保证高可用性,一般设置N>=3。不同的N,W,R 组合,是在可用性和一致性之间取一个平衡,以适应不同的应用场景。
如果N=W,R=1,任何一个写节点失效,都会导致写失败,因此可用性会降低,但是由于数据分布的N个节点是同步写入的,因此可以保证强一致性
HBase是借助其底层的HDFS来实现其数据冗余备份的。HDFS采用的就是强一致性保证。在数据没有完全同步到N个节点前,写操作不会返 回成功。也就是说它的 W=N,而读操作只需要读到一个值即可,也就是说它的 R=1
而 Cassandra 等系统,通常都允许用户按需要设置N,R,W三个值, 即可设置成W+R<= N,也就是说允许用户在强一致性和最终一致性之 间自由选择。而在用户选择了最终一致性,或者是W 尽管 NoSQL 数据库较好地满足了 Web 2.0应用的需求,但是 NoSQL 不具备高度结构化查询等特性,复杂查询的效率不如关系数据库,而且不支持事务ACID。 在这样的背景下,NewSQL 数据库开始升温。NewSQL 是对各种新的可扩展/高性能数据库的简称,这类数据库不仅具有NoSQL对海量数据的存储管理能力, 还保持了传统数据库支持ACID和SQL等特性。 在大数据时代,数据库架构开始向着多元化方向发展,并形成了传统关系数据库(OldSQL)、NoSQL 和 NewSQL 数据库三个阵营,三者各有自己的应用场景和发展空间。在未来的一段时间内,三个阵营共存共荣的局面还将持续。NewSQL数据库