NoSQL的了解

作者: i5yue | 来源:发表于2018-04-06 15:55 被阅读50次

    NoSQL简介和基础概念

    NoSQL(NoSQL = Not Only SQL),意即“不仅仅是SQL”,指的是非关系的数据库哭。NoSQL是一项全新的数据库革命性运动,早期就有人提出,发展至2009年趋势越发高涨。NoSQL被我们用得最多的当数key-value 存储,当然还有其他的文档型的、列存储、图型数据库、xml数据库等。NoSQL的拥护者们提倡运用非关系的数据存储,相对扑天盖地的关系型数据库运用,这一概念无疑是一种全新的思维的注入。

    先了解下关系型数据库

    1、遵循ACID规则:A(Atomicity)原子性、C(Consistency)一致性、I(Isolation)独立性、D(Durability)持久性
    2、分布式系统:由多台计算机和通信的软件组件通过计算机网络连接(本地网络或广域网)组成。
    3、分布式计算的优点:可靠性(容错)、可扩展性、资源共享、灵活性、更快的速度、开放系统、更高的性能。
    4、分布式计算的缺点:故障排除、软件、网络、安全性。

    RDBMS vs NoSQL

    RDBMS

    • 高度组织化结构化数据
    • 结构化查询语言(SQL) (SQL)
    • 数据和关系都存储在单独的表中。
    • 数据操纵语言,数据定义语言
    • 严格的一致性
    • 基础事务

    NoSQL

    • 代表着不仅仅是SQL
    • 没有声明性查询语言
    • 没有预定义的模式
      -键 - 值对存储,列存储,文档存储,图形数据库
    • 最终一致性,而非ACID属性
    • 非结构化和不可预知的数据
    • CAP定理
    • 高性能,高可用性和可伸缩性

    NoSQL的优点/缺点

    优点

    • 高可扩展性

    NoSQL数据库种类繁多,但是一个共同的特点都是去掉关系数据库的关系型特性。数据之间无关系,这样就非常容易扩展,也无形之间,在架构测层面上带来了可扩展的能力。

    • 大数据量,高性能

    NoSQL数据库都具有非常高的读写性能,尤其在大数量下,同样表现优秀。这得益于它的无关系性,数据库的结构简单。

    • 分布式计算
    • 低成本
    • 架构的灵活性,半结构化数据
    • 没有复杂的关系

    缺点

    • 没有标准化
    • 有限的查询功能(到目前为止)
    • 最终一致是不直观的程序

    为什么要用NoSQL?

    传统关系数据库的瓶颈

    传统的关系数据库具有不错的性能,高稳定型,久经历历史考验,而且使用简单,功能强大,同时也积累了大量的成功案例。当时一个网站的访问量一般都不大,用单个数据库完全可以轻松应付。特别很多都是静态网页,动态交互类型的网站不多。

    后来随着访问量的上升,几乎大部分使用MySQL架构的网站在数据库上都开始出现了性能问题,web程序不再仅仅专注在功能上,同时也在追求性能。程序员于是开始大量使用缓存技术来缓存数据库的压力,但是当访问量继续增大的时候,多台web机器通过文件缓存不能共享,大量的小文件缓存也带动了比较高的IO压力。

    Memcached 作为一个独立的分布式的缓存服务器,为多个web服务器提供了一个共享的高性能缓存服务。

    但是由于数据库的写入压力增加,Memcached只能缓解数据库的读取压力。读取集中在一个数据库让数据库不堪重负,大部分网站开始使用主从复制技术来达到读写分离,以提高读写性能和读库的可扩展性。

    在互联网大部分的MySQL都应该是IO密集型的,事实上,如果你的MySQL是个cpu密集型的话,那么很可能就需要由于性能问题需要优化了。大数据量高并发环境下的MySql应用开发越来越复杂,也越来越具有技术挑战性。像某些大公司开发了透明的中间件层来屏蔽开发者的复杂性,但是避免不了整个架构的复杂性。分库分表的子库到了一定阶段又面临扩展问题。还有就是需求的变更,可能又需要一种新的分库方式。

    MySQL数据库也经常存储一些大文本字段,导致数据库表非常大,在做数据库恢复的时候就导致非常的慢,不容易快速恢复数据库。比如1000万4KB大小的文本就接近40GB的大小,如果能把这些数据从MySQL省去,那么MySQL将变得非常小。

    关系数据库很强大,但是它并不能很好的应付所有的应用场景。MySQL的扩展性差,大数据下IO压力大,表结构更改困难,正是当前种种的困境,所以NoSQL的发展才会如鱼得水。

    场景的举例

    1、第一步来实现一个基于sql的通讯录系统。然后天真的定义以下字段:
    id (主键ID)
    title (标题)
    firstname (姓)
    lastname (名)
    gender (性别)
    telephone (电话)
    email (邮箱)
    address1 (地址1)
    address2 (地址2)
    address3 (地址3)
    city (城市)
    region (区/县)
    zipcode (邮政编码)
    country (国家)

    问题一:很少人只有一个电话号码。所以我们可能需要至少三个号码:一个座机、一个移动电话、一个工作电话。但是有多少个号码无关紧要——有些人、有些地方需要更多。让我们创建一个单独的 telephone 表,这样的话他们想要多少联系人都可以。这也让我们的数据标准化了——我们不需要没有号码的联系人显示为NULL。
    contact_id
    name (文本,例如座机号,工作手机等)
    number

    问题二:Email地址有同样的问题,因此我们也创建一个类似的 email 表:
    contact_id
    name (text such as home email, work email, etc.)
    address

    问题三:我们可能不想输入一个(地理位置的)地址,或者我们想输入多个地址,工作地,家里,度假住所等。因此我们需要一个新的 address 表:
    contact_id
    name (text such as home, office, etc.)
    address1
    address2
    address3
    city
    region
    zipcode
    country

    太棒了——我们有了一个能存放任意联系人的任意多个电话号码,Email 地址和住址的标准化数据库。不幸的是……

    需求不是固定不变的,这时候就该产品上场了。
    我们没有考虑到联系人的中间名字、出生日期、公司或职位。我们添加多少字段都没关系,我们很快会受到更新的需求要添加备注、纪念日、关系状态、社交媒体账号、内腿测量值、最喜欢的奶酪类型等字段。预测所有选项是不可能的,因此我们可能需要一个 otherdata 表,用来处理名字-值对。

    数据是碎片化的

    对开发者或者系统管理员来说,检查数据库并不容易。程序逻辑会变得更慢、更复杂,因为利用单个 SELECT 和多个 JOIN 语句查询联系人数据不太实际。(你可以这么做,但是结果可能需要包含 telephone,email,和 address字段的每一种组合:如果有个联系人有三个电话号码,五个Email地址和两个住址,那么SQL查询将会产生30条结果。) 最后,全文搜索很困难。如果有人输入字符串”SitePoint”,我们必须检查所有的表,看看它是否为联系人名字、电话、Email或者住址的一部分,并且需要做相应的排序。如果你用过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" }});
    

    SQL和NoSQ两种数据库没有那个绝对比另外一个要好,两种分别各自有自己的长短处,我们只需要在合适他们的场景使用他们,那么机会发挥他们各自的最大的价值。

    相关文章

      网友评论

        本文标题:NoSQL的了解

        本文链接:https://www.haomeiwen.com/subject/wfskcftx.html