在中我们主要的讨论了 SQL 与 NoSQL 数据库之间的主要的差别。接下来,我们将会利用上一篇中的知识来确定在特定的场景中如何确定比较好的选择。
首先我们先来总结一下:
SQL 数据库:
NoSQL 数据库:
SQL 数据库适合那些需求确定和对数据完整性要去严格的项目。NoSQL 数据库适用于那些对速度和可扩展性比较看重的那些不相关的,不确定和不断发展的需求。简单来说就是:
很少有项目能够很好的适用于一种数据库。如果你对数据的需求比较小或是非标准化的数据任何一种数据库都是可以的。你比我更了解你的项目,我不建议你将 SQL 上的数据移植到 NoSQL 上反之亦然,除非它能够提供非常可观的收益。当然选择权在于你自己。在项目的一开始就要考虑好使用它们的利弊,这样才不会导致选择错误。
我们来重新的定义操作并基于 SQL 实现通讯录系统。我们初始简单的定义
表拥有如下几个字段;
- contact
问题一:很少有人只拥有一个手机号。或许我们可以再添加三个字段:固定电话,移动电话和工作电话,但是无论我们给一个联系人分配了多少个字段总会有人需要更多。我们需要创建一个单独的
表,这样就可以给一个联系人存多个号码了。这样也就规范化了我们的数据— 我们不需要一个没有电话的联系人:
- telephone
问题二:对于联系人邮箱我们也会遇到上述问题,因此我们也需要创建一个
的表:
问题三:我们在填写联系人信息是我们并不希望填写他的地理位置,或者我们想记录他工作、生活、旅游的地方等。因此我们需要一个
表:
- address
我们原先设计的
表就精简为:
- contact
好了,我们已经设计了一个规范化的数据库,可以用来存储任何一个联系人的电话号码,邮箱地址和住址了。但是......
模式是固定不变的
我们并没有考虑到联系人的生日,公司或者职位。不管我们添加多少个字段,我们会得到更多的需求:备注,周年纪念日,关系,社交账号,喜欢巧克力的种类等等。预测每一个需求对于我们来说是非常困难的,因此我们需要创建一张表其中存储的形式是键值对来应对不断增加的需求。
数据是碎片化的
对于开发人员和系统管理员来说不断地检查数据库是比较麻烦的。程序的逻辑会变得更复杂效率更慢,因为使用一条
语句来
- select
多个表来取出一个联系人的全部信息不太实际。(当然这也是可以实现的,但是当一个联系人中国包含电话号码,邮件地址和住址信息时:如果一个人有 3 个电话号码,五个邮箱和两个住址,那么 SQL 查询会产生 30 个结果,也就是说说这样的效率会很慢。)
- JOIN
最后,全文搜索是非常困难的。如果一个人要查询一个字符型:favorite,我们需要依次查询上述的四张表判断是否是一个联系人的姓名,电话,邮件或者地址依据这些把结果进行排序。如果你使用过
的搜索,你就会发现是都么的烦人了!
- WordPress
我们的联系人关注的是人这个实体。然而关于人的信息是不可预测的并且在不同的阶段的需求也会不一样。如果我们使用 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"
- }]
- }
尽管对于这个文档来说数据会变得多一些,但是我们可以仅仅取出文档的一个子集,例如:最新的状态等。对于每一个用户来说历史记录也会很容易搜索的到。
现在,我们来分析一下一个仓库的管理系统。我们需要记录如下的信息:
数据需求:
因此,我们需要考虑对数据的完整性和对于事务的支持。目前来说也就是 SQL 能够很好地满足我们的需求。
我希望上述的案例能够对你有一定的帮助,但是每一个实际的项目都是不同的,对一无二的你需要自己去做决定选择一种适合的。(尽管,对于我们开发人员来说我们不太愿意去改变我们现有的选择,无论新的技术有多好!O(∩_∩)O)
建议:去尝试了解更多新的技术。这样我们就可以非常有理由的选择一种数据库进行开发。祝你好运!
来源: http://www.cnblogs.com/beilin/p/6007080.html