声明:本文译自SQL vs NoSQL The Differences,如需转载请注明出处。
SQL(结构化查询语言)数据库作为一个主要的数据存储机制已经超过40个年头了。随着web应用和像MySQL、PostgreSQL和SQLite这些开源项的兴起,SQL使用量大大增加。
NoSQL数据库在20世纪60年代就已经出现了,但最近因为MongoDB、CouchDB,Redis和Apache Cassandra等才受到广泛的关注。
你会发现很多教程都会解释如何根据你的兴趣选择去使用SQL还是NoSQL,但是很少讨论为什么应该去选择它。我希望能够填补这一空白。在这篇文章中,我们将介绍基本的差异。在稍后的后续的文章中,我们将查看一些典型的场景,并确定***的选择。
大多数的例子都适用于目前流行的MySQL SQL和MongoDB NoSQL数据库系统。其他SQL/NOSQL数据库都是类似的,但会有细微的差别和语法特征。
SQL和NoSQL的圣战
在我们开始之前,先纠正一些所谓的神话…
神话1:NoSQL将取代SQL
这么说就好比说船将被车取代,因为它是新的技术。SQL和NoSQL做的是相同的事:数据存储。它们采取的方法不同,这可能回帮组或阻碍你的项目。尽管感觉技术更新,并经常在最近上头条,NoSQL不是SQL的替代品——而是一种选择。
神话2:NoSQL比SQL更好或更坏
一些项目更适合使用SQL数据库,一些更适合NoSQL,而一些可以两者交替使用。这边文章不会是SitePoint Smackdown,因为你不能在所有方面都应用相同的广泛性假设。
神话3:SQL和NoSQL天壤之别
这不一定是个事实。一些SQL数据库采用NoSQL的特点,反之亦然。选择可能会变得越来越模糊,NewSQL混合数据库可能会在将来提供一些有趣的选择。
神话4:语言/框架决定了使用什么样的数据库
我们已经习惯了技术堆,比如——
LAMP: Linux, Apache, MySQL (SQL), PHP
MEAN: MongoDB (NoSQL), Express, Angular, Node.js
.NET, IIS and SQL Server
Java, Apache and Oracle.
有实践的、历史的和商业的原因来解释这些stack的发展——但不能认为它们就是规则。你可以在你的PHP或.NET项目中使用MongoDB NoSQL数据库。你可以在Node.js中连接MySQL或者SQL服务器。你可能没有找到很多教程和资源,但是是你的需求决定数据库的类型——而不是所谓的语言。
(有句话是这么说的,不要让生活有目地为难自己!选择一个不寻常的技术组合或者SQL和NoSQL组合是可行的,但困难的是找到支持和聘请有经验的开发者)
有了这样的想法,我们来看看主要的差异。
SQL表VS 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",
- 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无模式
在一个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规范化VS 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关系连接VS NoSQL
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 VS NoSQL数据完整性
大多数SQL数据库允许你使用外键约束去强制性数据完整性(除非你仍在使用旧的,在MySQL已不存在的MyISAM存储引擎)。我们的书店可以——
确保所有的书都有一个有效的publisher_id编码,这个编码在 publisher表中都有匹配的条目
如果一个或多个书被分配给它们,则出版商不能被删除。
模式强制数据库遵循这些规则。开发者或用户则不能增加、编辑或者移除可能引起无效数据或孤立的数据
相同数据完整性选项在NoSQL数据库中不可用;你可以存储所有你想存储的东西。理想情况下,单一文档将成为项目所有信息的唯一来源。
SQL VS NoSQL事务
在SQL数据库中,两个或多个更新可以在同一个事务中执行——一个all-or-nothing的封装保证成功或失败。例如,假设我们的书店包含了order和stock表。当一本书被订购时,我们在order表添加一条记录并减少stock表中的库存数。如果我们分别地执行这两个更新,一个可能成功另外一个会失败——因此我们的数据会不同步。在一个事务中放置相同更新可以保证同时成功或失败。
在NoSQL数据库中,单个文档的修改是微小的。换句话说。如果你正在文档中更新三个值,要不三个值都是成功的,要不三个值都保持不变。然而,却没有相等的事务去更新不同的文档。有类似的选项,但是,在写这些的时候,必须在你的代码中手动处理。
SQL VS NoSQL CRUD 语法
创建、读取更新和删除数据是上所有数据库系统的基础。本质上——
SQL是一个轻量级的陈述性语言。这是非常强大的,并已经成为一个国际化的标准,虽然大多数系统实现略有不同的语法。
NoSQL数据库使用与JSON类似 JavaScripty-looking查询!基本操作很简单,但嵌套的JSON对于复杂的查询会变得更加的繁杂。
简单的比较:
SQL VS NoSQL性能
这也许是最有争议的比较,NoSQL经常被认为比SQL更快。这并不奇怪;NoSQL更加简单的反规范化存储允许你使用单个请求去在所有信息中查询一个特定的项目。不需要使用相关的JSON或复杂的SQL查询。
也就是说,你的项目设计和数据要求将产生***的影响。一个良好设计的SQL数据库必然会比一个设计很差的NoSQL表现要好,反之亦然。
SQL VS NoSQL缩放
随着你的数据的增长,你可能会发现在多个服务器之前分配负载是很必要的。这对于SQL为基础的系统可能很棘手。如何分配相关的数据呢?聚类可能是最简单的选择;多个服务器访问相同的中央存储——但即使这样也会存在挑战。
NoSQL的简单数据模型可以让这个过程容易很多,许多一开始就建立了缩放功能。这是一个概论性的,所以如果碰到这种情况请去咨询专家意见。
SQL VS NoSQL实用性
***,我们来考虑安全和系统的问题。最有名的NoSQL数据库才存在了几年;他们比更成熟的SQL产品更易出现问题。许多的问题已经被曝光,但大部分还是归结为一个问题:知识。
开发人员和系统管理员对于新的数据库系统有较少的经验,所以错误常常发生。选择NoSQL是因为它感觉会更快,或因为你想去避免架构设计而导致之后的问题。
SQL VS NoSQL的总结
SQL和NoSQL数据库用不同的方式做同样的事情。从一个切换到另一个是可能的,但是一点计划可以节约很多的时间和金钱。
更适合SQL的项目:
可预先确定的逻辑关系离散数据的要求
数据完整性是必不可少的
有良好开发经验和支持的标准基础技术
更适合NoSQL的项目:
不相关的、不确定或不断变化的数据要求
更加简单宽松的项目对象,可以立即编码
速度和扩展性是必要的
在这个书店例子的背景下,SQL数据库是最实用的选项——特别是当我们引进电商设施,需要强大的事务支持。