• NoSql数据库 设计上面的一些心得


    NoSql数据库这个概念听闻许久了,也陆续看到很多公司和产品都在使用,优缺点似乎都被分析的清清楚楚。但我心里一直存有一个疑惑,它的出现究竟是为了解决什么问题?

    用户信息表,书籍信息表,用户为书籍打分信息表,评论表。

    现在假想要做一个显示评论内容的页面,上面会有用户信息和相关书籍的信息,想必大家脑子里已经出现各种select和join了吧。

    如果用NoSql还是同样的设计的话,那你会惊喜的发现NoSql数据库的性能简直差到爆。性子火爆的估计当场就要掀桌。

    什么破烂数据库,不是号称性能一流的吗!

    好吧,性能问题也就不说了,竟然连事务都不支持!?那我同时插入四张表的数据该怎么保持一致?开玩笑的吧!

     

    NoSql数据库此时默默的泪流满面,冤枉啊……你别说,还真是冤枉它了。

    先从最基本的设计元素说起,几乎所有的NoSql数据库都没有表(table)的概念,取而代之的是文档(document)。文档是个什么东西?Mongodb的解释,文档是一个使用JSON格式以key-value方式存储数据的结构,比如:

    { "item": "pencil", "qty": 500, "type": "no.2" }
    看起来和表没什么不同嘛?咳咳,JSON是支持嵌套结构的,比如可以把书籍信息和用户打分的信息存到一起:
    { 
      "id": "123zxcrweq2", 
      "title": "雪中悍刀行", 
      "author": "烽火戏诸侯", 
      "scores": [ 
        { 
          "userid": "454zxcfwer1", 
          "nickname": "Allen", 
          "score": 3, 
        }, 
        { 
          "userid": "678zxkiou1", 
          "nickname": "Judy", 
          "score": 4, 
        } 
      ], 
    }

    一堆document存储到一起就叫做collection,而同一个collection里面的document可以不一样。注意,这里也是重点概念。如果切换到关系型数据库的话,相当于一张表里每一行数据的列都可以不一样。这不是乱套了吗?用不好确实会乱套的。

    概念说完了,来看看面对下面这种产品要求的时候应该怎么办。产品经理说了,要在书籍信息页面看到所有评论,评论人的信息和打的分也要出现。

    如果是关系数据库,获取数据的思路是这样的:

    1. 根据书籍Id取到书籍信息。

    2. 根据书籍Id取到所有评论信息。

    3. 根据评论信息中的用户Id取到相关用户的信息。

    4. 根据书籍Id和用户Id取到打分信息。

    那在NoSql数据库中如果我们用如下结构存储数据的话……

    { 
      "id": "123zxcrweq2", 
      "title": "雪中悍刀行", 
      "author": "烽火戏诸侯", 
      "comments": [ 
        { 
          "author": { 
            "id": "454zxcfwer1", 
            "nickname": "Allen", 
            "avatarurl": "头像1.png", 
          }, 
          "score": 3, 
          "title": "书评1", 
          "content": "书评内容1", 
        }, 
        { 
          "author": { 
            "id": "454zxcfwer1", 
            "nickname": "Judy", 
            "avatarurl": "头像2.png", 
          }, 
          "score": 4, 
          "title": "书评2", 
          "content": "书评内容2" 
        } 
      ], 
    }

    似乎只要根据书籍Id查询一次就能得到结果了吧……明白为什么说NoSql数据库效率高了吗?一边是从四个集合中查找数据,一边是从一个集合中查找数据,这运行效率肉眼就能看出来差别了吧。

    所以到这里我得到了一条设计心得,尽可能把一次展示所需的必要数据都存储到一起。这是典型的空间换时间。所幸现在的科技条件下空间的价格非常低廉,所以很划算。

    根据这个设计结构,似乎也不需要事务的支持了,用户为一本书籍打分只需要在一个document里面添加数据就够了。

    好,document特性的用处明白了,现在就来研究下NoSql数据库另外一条原则的用途了,还记得是什么吗?同一个collection里面的document可以不一样

    还是从实际应用中来看,某日,产品经理说,书籍详细信息页面上还要显示书评的创建时间。

    如果使用关系数据库该怎么办?

    1. 创建一个为Review表增加”creationtime“列的sql脚本。

    2. 到数据库中运行。

    3. 修改相关代码和存储过程。

    NoSql呢?

    1. 在Comment结构实体中增加CreationTime,增加赋值代码。

    没了,不需要去修改历史数据,因为?同一个collection里面的document可以不一样。那如果取到历史数据怎么办?Comment的CreationTime会被置为空。挺合理的,也不会产生什么危害。

    大 家都知道,互联网产品的更新速度是非常快的,经常根据用户反馈和市场情况调整产品形态,而数据结构也会经常发生变化。为了适应这种环境,如何处理历史数据 就成了老大难。还记得当年看到一个DBA在设计表的时候会留出几个字段叫做”Reserved1,Reserved2……“,感觉好无厘头,浪费空间,后 来随着产品功能的增加才明白这其实是经验丰富的表现。如果用NoSql就不用这么纠结了。

    总结一下,就我浅薄的使用经验来看,NoSql的优点是:1. 在精心的设计下查询性能巨好。2. 数据结构弹性十足,特别适合快速发展中的产品。

    另外需要提醒一下,Mongodb不支持事务,所以务必在设计的时候考虑到这一点。核心业务数据尽可能通过结构设计做到数据插入的一致性。如果实在无法达成,请立即转回去用关系数据库,否则或早或晚你一定会后悔的。

    本文链接:http://www.cnblogs.com/AllenDang/p/3507821.html#!comments

  • 相关阅读:
    为sublime text2 添加SASS语法高亮
    下拉框点链接js
    [JavaScript] 初中级Javascript程序员必修学习目录
    判断页数及切换
    切换加上延迟加载js代码
    jquery 简单弹出层(转)
    左右滑动删除ListView条目Item--第三方开源--SwipeToDismiss
    使用自定义的item、Adapter和AsyncTask、第三方开源框架PullToRefresh联合使用实现自定义的下拉列表(从网络加载图片显示在item中的ImageView)
    从一个URL下载原始数据,基于byte字节,得到byte数组
    动画气泡指示当前滑动值--第三方开源--DiscreteSeekbar
  • 原文地址:https://www.cnblogs.com/wuxl360/p/5461363.html
Copyright © 2020-2023  润新知