SQL VS NoSQL 如何选择数据库

前一篇文章中咱们主要的讨论了SQL与NoSQL数据库之间的主要的差异。接下来,咱们将会利用上一篇中的知识来肯定在特定的场景中如何肯定比较好的选择。html

首先咱们先来总结一下:数据库

SQL数据库:网络

  • ​使用表存储相关的数据ide

  • 在使用表以前须要先定义标的模式工具

  • 鼓励使用规范化来减小数据的冗余性能

  • 支持使用JOIN操做,使用一条SQL语句从多张表中取出相关的数据this

  • 须要知足数据完整性约束规则spa

  • 使用事务来保证数据的一致性.net

  • 可以大规模的使用设计

  • 使用强大的SQL语言进行查询操做

  • 提供大量的支持,专业技能和辅助工具

NoSQL数据库:

  • 使用类JSON格式的文档来存储键值对信息

  • 存储数据不须要特定的模式

  • 使用非规范化的标准存储信息,以保证一个文档中包含一个条目的全部信息

  • 不须要使用JOIN操做

  • 容许数据不用经过验证就能够存储到任意的位置

  • 保证更新的单个文档,而不是多个文档

  • 提供卓越的性能和可扩展性

  • 使用JSON数据对象进行查询

  • 是一种新型的技术

SQL数据库适合那些需求肯定和对数据完整性要去严格的项目。NoSQL数据库适用于那些对速度和可扩展性比较看重的那些不相关的,不肯定和不断发展的需求。简单来讲就是:

  • SQL是精确的。它最适合于具备精确标准的定义明确的项目。典型的使用场景是在线商店和银行系统。

  • NoSQL是多变的。它最适合于具备不肯定需求的数据。典型的使用场景是社交网络,客户管理和网络分析系统。

不多有项目可以很好的适用于一种数据库。若是你对数据的需求比较小或是非标准化的数据任何一种数据库都是能够的。你比我更了解你的项目,我不建议你将SQL上的数据移植到NoSQL上反之亦然,除非它可以提供很是可观的收益。固然选择权在于你本身。在项目的一开始就要考虑好使用它们的利弊,这样才不会致使选择错误。

场景一:通信记录

咱们来从新的定义操做并基于SQL实现通信录系统。咱们初始简单的定义contact表拥有以下几个字段;

  • id

  • title

  • firstname

  • lastname

  • gender

  • telephone

  • email

  • address1

  • address2

  • address3

  • city

  • region

  • zipcode

  • country

问题一:不多有人只拥有一个手机号。或许咱们能够再添加三个字段:固定电话,移动电话和工做电话,可是不管咱们给一个联系人分配了多少个字段总会有人须要更多。咱们须要建立一个单独的telephone表,这样就能够给一个联系人存多个号码了。这样也就规范化了咱们的数据— 咱们不须要一个没有电话的联系人:

  • contact_id

  • name (说明字段:固定,工做,私人等.)

  • number

问题二:对于联系人邮箱咱们也会遇到上述问题,所以咱们也须要建立一个email的表:

  • contact_id

  • name (说明字段:固定,工做,私人等.)

  • address

问题三:咱们在填写联系人信息是咱们并不但愿填写他的地理位置,或者咱们想记录他工做、生活、旅游的地方等。所以咱们须要一个address表:

  • contact_id

  • name (text such as home, office, etc.)

  • address1

  • address2

  • address3

  • city

  • region

  • zipcode

  • country

咱们原先设计的contact表就精简为:

  • id

  • title

  • firstname

  • lastname

  • gender

好了,咱们已经设计了一个规范化的数据库,能够用来存储任何一个联系人的电话号码,邮箱地址和住址了。可是......

模式是固定不变的

咱们并无考虑到联系人的生日,公司或者职位。无论咱们添加多少个字段,咱们会获得更多的需求:备注,周年记念日,关系,社交帐号,喜欢巧克力的种类等等。预测每个需求对于咱们来讲是很是困难的,所以咱们须要建立一张表其中存储的形式是键值对来应对不断增长的需求。

数据是碎片化的

对于开发人员和系统管理员来讲不断地检查数据库是比较麻烦的。程序的逻辑会变得更复杂效率更慢,由于使用一条select语句来JOIN多个表来取出一个联系人的所有信息不太实际。(固然这也是能够实现的,可是当一个联系人中国包含电话号码,邮件地址和住址信息时:若是一我的有3个电话号码,五个邮箱和两个住址,那么SQL查询会产生30个结果,也就是说说这样的效率会很慢。)

最后,全文搜索是很是困难的。若是一我的要查询一个字符型:favorite,咱们须要依次查询上述的四张表判断是不是一个联系人的姓名,电话,邮件或者地址依据这些把结果进行排序。若是你使用过WordPress的搜索,你就会发现是都么的烦人了!

使用NoSQL来替代SQL

咱们的联系人关注的是人这个实体。然而关于人的信息是不可预测的而且在不一样的阶段的需求也会不同。若是咱们使用NoSQL数据库会比较方便,NoSQL将一我的的信息存储为一个文档并放入contacts的集合中: 

{
  name: [
    "Billy", "Bob", "Jones"
  ],
  company: "Fake Goods Corp",
  jobtitle: "Vice President of Data Management",
  telephone: {
    home: "0123456789",
    mobile: "9876543210",
    work: "2244668800"
  },
  email: {
    personal: "bob@myhomeemail.net",
    work: "bob@myworkemail.com"
  },
  address: {
    home: {
      line1: "10 Non-Existent Street",
      city: "Nowhere",
      country: "Australia"
    }
  },
  birthdate: ISODate("1980-01-01T00:00:00.000Z"),
  twitter: '@bobsfakeaccount',
  note: "Don't trust this guy",
  weight: "200lb",
  photo: "52e86ad749e0b817d25c8892.jpg"
}

在这个示例中,咱们没有存储这我的的性别和职衔,而且能够添加一些别的联系人没用的信息。在NoSQL中这样的存储是合法的,而且咱们能够按照各人的意愿来添加和删除一个字段。

由于一个联系人存储在一个文档中,所以咱们可使用一个查询语句取出一我的的全部信息。对于全文搜索,在MongoDB中咱们能够在contact的字段中定义一个索引:

db.contact.createIndex({ "$**": "text" });

而后咱们就可使用以下的语句进行全文搜索:

db.contact.find({
  $text: { $search: "something" }
});

 

场景二:社交网络

一个典型的社交网络使用的联系人的信息是类似,可是也会增长一些新的功能例如:社交网络,状态更新,私信和点赞。这些功能会根据用户的需求进行添加或者删除,预测用户的需求对开发人员来讲是很是困难的。

另外:

  • 大多数的更新都有一个原始的出发点:用户。可是,对于开发人员来讲一次性的把全部的回馈都进行更新是不可能的。

  • 无论用户怎么想,一个失败的版本并可能形成太大的经济损失。一个应用的接口设计和功能表现是比数据的完整性的优先级要高。

所以,NoSQL是一个不错的选择。数据库容许咱们存储不一样类型的数据以便于咱们快速的开发出新的功能。例如,由于全部的数据状态的更新均可以在status的集合中的一个文档中进行:

 
{
  user_id: ObjectID("65f82bda42e7b8c76f5c1969"),
  update: [
    {
      date: ISODate("2015-09-18T10:02:47.620Z"),
      text: "feeling more positive today"
    },
    {
      date: ISODate("2015-09-17T13:14:20.789Z"),
      text: "spending far too much time here"
    }
    {
      date: ISODate("2015-09-17T12:33:02.132Z"),
      text: "considering my life choices"
    }
  ]
}

 

尽管对于这个文档来讲数据会变得多一些,可是咱们能够仅仅取出文档的一个子集,例如:最新的状态等。对于每个用户来讲历史记录也会很容易搜索的到。

场景三:仓库管理系统

如今,咱们来分析一下一个仓库的管理系统。咱们须要记录以下的信息:

  • 货物入库的信息和存放的位置信息

  • 货物在仓库中的移动,例如:为相同的货物分配相邻的位置存放

  • 货物的摆放顺序以及配送货物以后的一系列问题。

数据需求:

  1. 保存货物的基本信息例如:尺寸、大小、颜色等,这些不相关的数据咱们要可以用到任何的货物上。咱们不可能去考虑一些货物个性化的信息例如:笔记本处理器的速度或者是一部手机电池的寿命。

  2. 咱们要尽量的避免错误的发生。咱们不能让货物凭空消失或者将货物存放到已经存放货物的位置上去。

  3. 以更加简单的方式操做。咱们记录将一件货物从一个位置移动到另外一个位置或者从A移动到B的操做是相同的。

所以,咱们须要考虑对数据的完整性和对于事务的支持。目前来讲也就是SQL可以很好地知足咱们的需求。

总结

我但愿上述的案例可以对你有必定的帮助,可是每个实际的项目都是不一样的,对一无二的你须要本身去作决定选择一种适合的。(尽管,对于咱们开发人员来讲咱们不太愿意去改变咱们现有的选择,不管新的技术有多好!O(∩_∩)O)

建议:去尝试了解更多新的技术。这样咱们就能够很是有理由的选择一种数据库进行开发。祝你好运!

相关文章
相关标签/搜索