SQL(结构化的查询语言)数据库是过去四十年间存储数据的主要方式。20世纪90年代末随着Web应用和MySQL、PostgreSQL和SQLite等开源数据库的兴起,用户爆炸式的增加。数据库
NoSQL数据库自从20世纪60年代就已经存在了,直到MongoDB, CouchDB, Redis 和 Apache Cassandra等数据库的流行才获取了更多的关注。编程
你能够很容易地找到许多关于如何使用一款特定的SQL或NoSQL的教程,可是不多有讨论你为何优先的使用一款而不适用另外一款。我但愿我可以填补这个空白。在这篇文章中将会介绍它们之间的不一样。在后续的文章中,咱们将会根据典型的场景来肯定最佳的选择。安全
大多数的例子都适用于流行的关系型数据库MySQL和MongoDB NoSQL数据库.其它的SQL/NoSQL也是相似的,可是在语法和特色上会有一些细微的差异。服务器
SQL与NoSQL之间的战争框架
在咱们进一步讨论以前,咱们先不去考虑各类观点......性能
观点一:NoSQL将会取代SQLspa
这个观点就像是说船将会取代汽车,由于船是一种新的技术同样,这是不可能发生的事情。SQL和NoSQL有着相同的目标:存储数据。它们存储数据的方式不一样,这可能会影响到你开发的项目,一种会简化你的开发,一种会阻碍你的开发。尽管目前NoSQL数据库很是的火爆,可是NoSQL是不能取代SQL的--它仅仅是SQL的一种替代品。设计
观点二:NoSQL要比SQL好/坏code
一些项目可能会更适合使用SQL数据库,然而一些项目可能会比较适合使用NoSQL,有些项目使用哪种均可以很好地达到预期的效果。本文不支持任何一方,由于没有一种方式可使用到全部的项目中去。orm
观点三:SQL与NoSQL之间有明显的差异
这个观点并非很正确。一些SQL数据库也采用了NoSQL数据库的特性,反之亦然。在选择数据库方面的界限变得愈来愈模糊了,而且一些新的混合型数据库将会在不久的未来提供更多的选择。
观点四:语言或框架决定使用何种数据库
咱们已经习惯于使用一些现有的框架进行开发,例如:
LAMP:Linux,Apache,MySQL(SQL),PHP
MEAN:MongoDB(NoSQL),Express,Angular,Node.js
.NET,IIS和SQL Server
Java,Apache和Oracle
因为不少实际的,历史的和商业化的缘由致使了这些框架的发展,可是它们并非一种规则约束。你能够在你的PHP和.NET的项目中使用MongoDB。也能够在Node.js中使用MySQL或者SQL Service。或许在你使用上诉开发模式下不能找到很好的教程和资源,可是咱们开发应该是需求决定使用数据库的类型,而不是数据库语言来决定的。
(换句话说,不要自讨苦吃!选择一种小众的技术组合或者是将SQL和NoSQL进行组合开发是有可能的,可是那样你会发现寻找有经验的开发者和相关的技术支持是很是困难的)
下面咱们来看一下它们之间的主要的差异......
SQL中的表与NoSQL中的文档
SQL数据库提供关系型的表来存储数据。例如,若是你在维护一个在线的书店,书籍信息应该存放到book的表中:
每一行是一本不一样书籍的一个记录。这样的设计有些死板,你不能使用同一张表来存储不一样结构的信息或者在规定插入数字的位置插入字符串。
NoSQL数据库采用类JOSN的键值对来存储文档,例如:
{
ISBN: 9780992461225,
title: "JavaScript: Novice to Ninja",
author: "Darren Jones",
format: "ebook",
price: 29.00
}
同一类型的文档存储为一个集合(collection),相似于关系型数据库中的表结构。然而,你能够在任意的文档中存储任意的数据,NoSQL数据库不会去进行比较。例如:
{
ISBN: 9780992461225,
title: "JavaScript: Novice to Ninja",
author: "Darren Jones",
year: 2014,
format: "ebook",
price: 29.00,
description: "Learn JavaScript from scratch!",
rating: "5/5",
review: [
{ name: "A Reader", text: "The best JavaScript book I've ever read." },
{ name: "JS Expert", text: "Recommended to novice and expert developers alike." }
]
}
SQL中的表结构具备严格的数据模式约束,所以存储数据很难出错。NoSQL存储数据更加灵活自由,可是也会致使数据不一致性问题的发生。
SQL模式 VS NoSQL的无模式
在关系型数据库中,除非你事先定义了表和字段的模式不然你没法向其中添加数据。模式中包含了许多的信息:
主键 — 独一无二的标志就像ISBN惟一肯定一条记录
索引 — 一般设置索引字段加快搜索的速度
关系 — 字段之间的逻辑链接
设计功能例如触发器和存储程序
在进行数据的逻辑操做以前咱们必需要定义数据模式。数据模式能够在后期进行更改,可是对于模式的大改将会是很是复杂的。
在NoSQL的数据库中,数据在任什么时候候均可以进行添加。不须要事先去定义文档和集合。例如在MongoDB中以下的操做将会在book集合中从新建立一个文档若是以前没有建立。
db.book.insert(
ISBN: 9780994182654,
title: "Jump Start Git",
author: "Shaumik Daityari",
format: "ebook",
price: 29.00
);
(MongoDB会在集合中为每个文档添加一个独一无二的_id。若是你仍然想要定义索引,你也能够本身在以后定义)
一个NoSQL数据库更适合于那些不可以肯定数据需求的的工程项目。也就是说,不要为本身的懒惰而制造麻烦:不在项目开始的时候设计一个好的数据存储模型在未来会带来必定的麻烦。
SQL语言的规范化 VS NoSQL语言的非规范化
假设咱们想要在书店的数据库中添加一项出版社信息。一个出版社会出版不少书,所以在数据库中咱们建立了一个表publisher:
id | name | country | |
---|---|---|---|
SP001 | SitePoint | Australia | feedck@sitepoint.com |
咱们要在book表中添加一个publisher_id的字段,用于引用出版社信息中的id:
这样的设计可以最小化数据的冗余,咱们不须要为每一本书重复的添加出版社的全部信息—只须要去引用就能够了。这项技术叫作数据库的规范化,具备实际的意义。咱们能够更改出版社信息而不用修改book中的数据。
在NoSQL中咱们也可使用规范化技术。在book集合中的文档:
{
ISBN: 9780992461225,
title: "JavaScript: Novice to Ninja",
author: "Darren Jones",
format: "ebook",
price: 29.00,
publisher_id: "SP001"
}
引用publisher集合中的一个文档
{
id: "SP001"
name: "SitePoint",
country: "Australia",
email: "feedback@sitepoint.com"
}
然而,在实际中咱们并不会这样作。咱们会更倾向于选择非规范化咱们的文档为每一本书中都重复出版社的信息
{
ISBN: 9780992461225,
title: "JavaScript: Novice to Ninja",
author: "Darren Jones",
format: "ebook",
price: 29.00,
publisher: {
name: "SitePoint",
country: "Australia",
email: "feedback@sitepoint.com"
}
}
这样会使查询更快,可是在更新出版社信息的记录变多时效率将会显著地降低。
SQL关系的JOIN操做 VS NoSQL
SQL语言为查询提供了强大的JOIN操做。咱们可使用单个SQL语句在多个表中获取相关数据。例如:
SELECT book.title, book.author, publisher.name
FROM book
LEFT JOIN book.publisher_id ON publisher.id;
这条SQL语句会返回全部书的书名,做者和相关的出版社的名称。
在NoSQL中没有与JOIN相同的操做,对于具备SQL语言经验的人来讲是很是使人震惊的。若是咱们使用是上面的规范化的集合,咱们须要取出book集合中全部的文档,检索全部的publisher的文档,并在程序中进行手动链接。这也是非规范化存在的缘由之一。
SQL VS NoSQL 数据完整性
大多数的数据库容许经过定义外键来进行数据库的完整性约束。咱们的数据库可以保证:
确保全部的书的publisher_id都会对应于publisher中的一个实体,
若是有一本或多本书中的publisher_id与publisher中的id对应,那么该出版社就不能被删除。
数据模式确保了这些规则被数据库遵照。开发者或者用户不能添加、修改和移除一条记录,若是这些操做致使数据产生无效的数据或者单条无用记录。
在NoSQL数据库中没有数据完整性的约束选项。你能够存储任何你想要存储的数据。理想状况下,单个文档将是项目的全部信息的惟一来源。
SQL VS NoSQL 事务
在SQL数据库中,两条或者多条更新操做能够结合成一个事务(或者所有执行成功不然失败)执行。例如,假设咱们的book数据库中包含了order和stock表。当一本书被订购以后,咱们要在order中添加一条记录并减小stock中的库存数目。若是咱们将两条更新操做分别执行,一条成功另外一个失败---这将会致使数据库的不一致性。将两条更新操做绑定为一个事务确保了它们要么所有成功要么所有失败。
在NoSQL数据库中,对于一个文档的更新操做是原子性的。换句话说,若是你要更新一个文档中的三个值,要么三个值都更新成功要么它们保持不变。然而,对于操做多个文档时没有雨事务相对应的操做。在MongoDB中有一个操做是transaction-like options,可是,须要咱们手动的加入到代码中。
SQL VS NoSQL CRUD(增删改查)语法
增删改查是数据库的基本操做。本质上:
SQL是一种声明性语言。SQL语言的功能强大,而且已经成为了一种国际的通用标准,尽管大多数系统在语法上有一些细微的差异。
NoSQL数据库使用相似JOSN为参数的JavaScript来进行查询!基本操做是相同的,可是嵌套的JOSN将会产生复杂的查询。
比较:
SQL VS NoSQL 表现
或许最具备争议性的比较是:一般状况下,NoSQL比SQL语言更快。这并无什么好震惊的,NoSQL中更加简单的非规范化存储容许咱们在一次查询中获得特定项的全部信息。不须要使用SQL中复杂的JOIN操做。
也就是说,你的项目的设计和数据的需求会有很大的影响。一个好的SQL数据库的设计的表现必定会比一个设计很差的NoSQL数据库性能好不少,反之亦然。
SQL VS NoSQL 规模
随着数据量的增加,咱们或许会发现有必要将负载分配到到不一样的服务器上。对于基于SQL语言的开发的系统是很是困难的。如何分配相关的数据?集群是一种最简单可能的解决方案,多个服务器访问同一个中央存储器—及时是这样也会有许多的问题。
NoSQL的简单的数据模型可以简化其过程,许多NoSQL数据库在一开始就构建了解决大规模数据的功能。这仅仅是一个归纳,若是你遇到了这样的问题应该去寻求专家的帮助。
SQL VS NoSQL 可行性
最后,咱们考虑一下安全性和系统性的问题。流行的NoSQL数据库已经存在好几年了,它们展示的问题可能会比成熟的关系型数据库多。许多问题都已经被发现了,可是全部的问题都指向了同一个问题:了解程度。
开发人员和系统管理员对于管理新型数据库有不多的经验,所以会产生许多问题。选择NoSQL是由于感受它比较新颖,或者你想要避免数据模式的设计,都会在未来带来一些问题。
SQL VS NoSQL 总结
SQL和NoSQL数据库只是用不一样的方式来完成相同的事情。咱们可能会先选择其中之一而后更换到另外一个上,可是在选择以前制定一个计划将会节约许多的时间和金钱。
适合使用SQL开发的项目:
能够预先定义逻辑相关的离散数据的需求
数据一致性是必要的
具备良好的开发者经验和技术支持的标准的成熟技术
适合使用NoSQL开发的项目:
不相关,不肯定和逐步发展的数据需求
更简单或者更宽松的可以快速开始编程的项目
速度和可扩展性相当重要的
在咱们的例子中,一个关系型数据库是一种更好的选择— 尤为是当咱们须要引入强大的事务支持的电子商务设备。在接下来的一篇文章中,咱们将讨论更多的项目场景,并肯定使用一个SQL或NoSQL数据库是不是最好的解决方案。