声明:本文译自SQL vs NoSQL The Differences,如需转载请注明出处。前端
SQL(结构化查询语言)数据库做为一个主要的数据存储机制已经超过40个年头了。随着web应用和像MySQL、PostgreSQL和SQLite这些开源项的兴起,SQL使用量大大增长。web
NoSQL数据库在20世纪60年代就已经出现了,但最近由于MongoDB、CouchDB,Redis和Apache Cassandra等才受到普遍的关注。sql
你会发现不少教程都会解释如何根据你的兴趣选择去使用SQL仍是NoSQL,可是不多讨论为何应该去选择它。我但愿可以填补这一空白。在这篇文章中,咱们将介绍基本的差别。在稍后的后续的文章中,咱们将查看一些典型的场景,并肯定最佳的选择。数据库
大多数的例子都适用于目前流行的MySQL SQL和MongoDB NoSQL数据库系统。其余SQL/NOSQL数据库都是相似的,但会有细微的差异和语法特征。安全
在咱们开始以前,先纠正一些所谓的神话…服务器
神话1:NoSQL将取代SQL架构
这么说就比如说船将被车取代,由于它是新的技术。SQL和NoSQL作的是相同的事:数据存储。它们采起的方法不一样,这可能回帮组或阻碍你的项目。尽管感受技术更新,并常常在最近上头条,NoSQL不是SQL的替代品——而是一种选择。框架
神话2:NoSQL比SQL更好或更坏nosql
一些项目更适合使用SQL数据库,一些更适合NoSQL,而一些能够二者交替使用。这边文章不会是SitePoint Smackdown,由于你不能在全部方面都应用相同的普遍性假设。性能
神话3:SQL和NoSQL天壤之别
这不必定是个事实。一些SQL数据库采用NoSQL的特色,反之亦然。选择可能会变得愈来愈模糊,NewSQL混合数据库可能会在未来提供一些有趣的选择。
神话4:语言/框架决定了使用什么样的数据库
咱们已经习惯了技术堆,好比——
有实践的、历史的和商业的缘由来解释这些stack的发展——但不能认为它们就是规则。你能够在你的PHP或.NET项目中使用MongoDB NoSQL数据库。你能够在Node.js中链接MySQL或者SQL服务器。你可能没有找到不少教程和资源,可是是你的需求决定数据库的类型——而不是所谓的语言。
(有句话是这么说的,不要让生活有目地为难本身!选择一个不寻常的技术组合或者SQL和NoSQL组合是可行的,但困难的是找到支持和聘请有经验的开发者)
有了这样的想法,咱们来看看主要的差别。
SQL数据库提供相关数据表的存储。例如,若是你有一个网上书店,图书的信息将会被添加到一个book的表中:
每一行是一个不一样的记录。设计是刚性的;你不能使用同一个表来存储不一样的信息,或者在一个数字格式输入字符。
NoSQL数据库存储JSON格式的字段值对文档,好比:
{ ISBN: 9780992461225, title: "JavaScript: Novice to Ninja", author: "Darren Jones", format: "ebook", price: 29.00 }
类似的文档能够存储于一个集合里,这相似于一个SQL表。然而你能够存储任何数据在任何文档里;而NoSQL数据库永远不会抱怨,例如:
{ ISBN: 9780992461225, title: "JavaScript: Novice to Ninja", author: "Darren Jones", format: "ebook", price: 29.00 }
SQL表建立一个严格的数据模板,所以很难犯错误。NoSQL更加的灵活和宽容,但可以存储任何数据可能会致使一致性的问题。
在一个SQL数据库中,除非你在指定模式中定义了表格和字段格式,否则不可能添加数据。该模式还能够包含其余的信息,例如——
主键——惟一的标识符,如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数据库里,咱们建立一个新的publisher表:
咱们接下来能够增长publisher_id到book表,这个表是publisher.id引用。
这最大限度的减小数据的冗余;咱们不用重复每本书的出版商信息——仅仅只用索引。这种技巧能够称做规范化,并有实际的好处。咱们只用更新单一的出版商而不用改变整个book数据。
在NoSQL中,咱们也可使用规范化技巧。在book集中的文档——
{ ISBN: 9780992461225, title: "JavaScript: Novice to Ninja", author: "Darren Jones", format: "ebook", price: 29.00, publisher_id: "SP001" }
——在一个出版商集合中引用一个文档:
{ 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条款。咱们可使用单个SQL语句获取不一样表中的相关数据。例如:
SELECT book.title, book.author, publisher.name
FROM book
LEFT JOIN book.publisher_id ON publisher.id;
这将返回全部的书名、做者和相关出版商名称。
NoSQL没有等效的JOIN,有SQL的经验的可能会惊讶. 若是咱们使用上述的规范化集合,咱们将须要获取全部的book文档,检索全部的相关publisher文档,并手动在程序逻辑中链接二者。这就是反规范化经常是必不可少的一个缘由。
大多数SQL数据库容许你使用外键约束去强制性数据完整性(除非你仍在使用旧的,在MySQL已不存在的MyISAM存储引擎)。咱们的书店能够——
模式强制数据库遵循这些规则。开发者或用户则不能增长、编辑或者移除可能引发无效数据或孤立的数据
相同数据完整性选项在NoSQL数据库中不可用;你能够存储全部你想存储的东西。理想状况下,单一文档将成为项目全部信息的惟一来源。
在SQL数据库中,两个或多个更新能够在同一个事务中执行——一个all-or-nothing的封装保证成功或失败。例如,假设咱们的书店包含了order和stock表。当一本书被订购时,咱们在order表添加一条记录并减小stock表中的库存数。若是咱们分别地执行这两个更新,一个可能成功另一个会失败——所以咱们的数据会不一样步。在一个事务中放置相同更新能够保证同时成功或失败。
在NoSQL数据库中,单个文档的修改是微小的。换句话说。若是你正在文档中更新三个值,要不三个值都是成功的,要不三个值都保持不变。然而,却没有相等的事务去更新不一样的文档。有相似的选项,可是,在写这些的时候,必须在你的代码中手动处理。
建立、读取更新和删除数据是上全部数据库系统的基础。本质上——
简单的比较:
这也许是最有争议的比较,NoSQL常常被认为比SQL更快。这并不奇怪;NoSQL更加简单的反规范化存储容许你使用单个请求去在全部信息中查询一个特定的项目。不须要使用相关的JSON或复杂的SQL查询。
也就是说,你的项目设计和数据要求将产生最大的影响。一个良好设计的SQL数据库必然会比一个设计不好的NoSQL表现要好,反之亦然。
随着你的数据的增加,你可能会发如今多个服务器以前分配负载是很必要的。这对于SQL为基础的系统可能很棘手。如何分配相关的数据呢?聚类多是最简单的选择;多个服务器访问相同的中央存储——但即便这样也会存在挑战。
NoSQL的简单数据模型可让这个过程容易不少,许多一开始就创建了缩放功能。这是一个概论性的,因此若是碰到这种状况请去咨询专家意见。
最后,咱们来考虑安全和系统的问题。最有名的NoSQL数据库才存在了几年;他们比更成熟的SQL产品更易出现问题。许多的问题已经被曝光,但大部分仍是归结为一个问题:知识。
开发人员和系统管理员对于新的数据库系统有较少的经验,因此错误经常发生。选择NoSQL是由于它感受会更快,或由于你想去避免架构设计而致使以后的问题。
SQL和NoSQL数据库用不一样的方式作一样的事情。从一个切换到另外一个是可能的,可是一点计划能够节约不少的时间和金钱。
更适合SQL的项目:
可预先肯定的逻辑关系离散数据的要求
数据完整性是必不可少的
有良好开发经验和支持的标准基础技术
更适合NoSQL的项目:
不相关的、不肯定或不断变化的数据要求
更加简单宽松的项目对象,能够当即编码
速度和扩展性是必要的
在这个书店例子的背景下,SQL数据库是最实用的选项——特别是当咱们引进电商设施,须要强大的事务支持。
因为咱们云巴是作跨设备平台的消息服务的,对数据存取的速度和扩展要求很是高,NoSQl对咱们来讲是最合适的。