关系型数据库几乎是很多开发者和DBA对于传统三层架构应用的唯一选择。使用这种场景的原因有很多,数据建模方法,与数据交互的查询语言,保证数据的一致部署,能够服务于复杂的应用程序。然而,这并不是所有数据存储问题的唯一解决方案,也是NoSQL的由来。NoSQL提供了一种新方法,而不是采用标准的面向SQL的范例。NoSQL技术无缝集成,具有高扩展性,众多技术同时具备高分布和高性能,是大数据分析的存储基石。大多数时候,它们完成了现有RDBMS技术实现的架构,例如作为缓存服务器、搜索引擎、非结构化存储、易失性信息存储等。主要分为4类:Key/value列存储面向文档存储现在图存储深入各种技术,选择最适合使用场景的技术。Key/Value最早也是最早的NoSQL数据存储是key/value。这些数据像字典一样根据key匹配值,通常用来存储需要高性能的基础信息,比如需要快速读写的session信息。这些商店在这种情况下非常高效,并且通常具有很高的可扩展性。Key/value也常用于上下文队列,保证数据不丢失,比如日志架构或者搜索引擎索引架构。Redis和RiakKV是非常著名的键/值数据存储;Redis使用更广泛,因为它有一个内存中的K/V存储并且持久化是可选的。Redis常用于web应用中,用于存储session相关数据,如node或-PHPweb应用;每秒可以提取数千个会话信息而不会造成性能损失。另一个典型的场景就是后面会提到的序列化:Redis位于Logstash和ElasticSearch之间,用于存储ElasticSearch查询中的索引。当Column达到key/value存储的极限时,需要使用列存储,因为它需要存储大量的记录信息。列存储技术对于RDBMS世界的工程师来说可能不太容易理解,但其实很简单。RDBMS中的数据是按行存储的,而在列存储中是按列存储的。使用列式数据库的主要好处是可以高速访问海量数据。一行RDBMS在硬盘上是一个连续的存储,多行可能存储在硬盘的不同位置,访问有点复杂。列数据库中的一列数据是连续存储的。例如,考虑在RDBMS中查询索引博客的标题,尤其是当有数百万数据时,需要大量的IO操作,而在列式数据库中,这样的查询只是一次访问。这样的数据库在从特定集群中提取海量数据时非常得心应手,但代价是缺乏灵活性。使用最多的列存储数据库是GoogleCloudBigtable,但开源的列存储数据库是ApacheHBase和Cassandra。列存储数据库的另一个优点是易于扩展,这些列在大量存储时具有很高的可扩展性。这就是为什么它们主要用于保存非易失和持久的信息。文档列存储数据库不适合存储具有深层嵌套结构的结构化数据。这个场景需要使用面向文档的数据存储。数据实际上存储为键/值,但所有压缩数据都称为文档。文档依赖于XML等结构或编码,但更常见的是JSON(JavaScript对象表示法)。虽然基于文档的数据库对于数据的结构化存储和表达非常有用,但它们也有其脆弱的一面,尤其是在数据交互操作方面。它们基本上遍历整个文档,例如在读取特定字段时,遍历会影响性能。当需要存储嵌套信息时,可以使用文档数据库。比如考虑在一个应用中如何表达一个账号,大概有以下信息:基本信息:姓名、生日、照片、URL、创建日期等复杂信息:地址、认证方式(密码、Facebook等)第三方认证),兴趣等。这就是为什么NoSQL文档数据库在Web应用中经常被使用的原因:它非常容易表达嵌套对象,而且由于它们都使用JSON,所以它们也可以与前端JavaScript技术无缝集成.最常用的文档数据库是MongoDB、Couchbase和ApacheCouchDB。它们都非常容易安装和启动,有很好的文档,而且都是可扩展的。此外,它们也是开放式现代Web应用程序的明确选择。.GraphGraph数据库与其他数据库有着根本的不同。它使用不同的范例来表示数据-树结构,其中节点和边缘连接称为关系。这些数据库天生就带有社交网络,比如表达用户的朋友圈,他们的朋友关系等等。对于其他类型的数据存储,可以在文档中存储用户的好友关系,但是存储好友关系还是很复杂;使用图数据库很简单,为每个朋友创建节点,通过关系将它们连接起来,依靠Query需求和scope浏览图。最流行的图形数据库是Neo4j。前面提到,主要的使用场景是处理复杂的关系信息,比如实体之间的连接关系,也可以用于分类场景。图2-1显示了这三个实体在图形数据库中的连接方式。图中的两天账户节点Jane和John,他们之间的每条边定义了他们的关系,他们在某一天认识,另外一组节点连接的两个账户表明Jane和Joh都成为了fo??otball的成员团队。NoSQL在使用场景中根据使用场景,首先需要一个基于文档的NoSQL数据库,一个JSON文档,将数据存储在关系数据库中。如前所述,传统的RDBMS将数据存储在多个关系表中,在获取完整对象时变得更加复杂和低效。图2-2中可以看到一个帐户拆分为多个表的示例。如果要获取所有的账户信息,基本上需要join两到三个表。现在考虑这样一种情况,您需要处理应用程序中所有用户的每个连接,并且这些连接具有不同的业务逻辑。***,想要查看帐户本身。什么样的文档可以通过API传递一个账号标识符从所有用户视图中获取?{"id":"account_identifier","email":"account@email.com","firstname":"account_firstname","lastname":"account_lastname","birthdate":"account_birthdate","authentication":[{“token”:“authentication_token_1”,“source”:“authenticaton_source_1”,“created”:“16-12-12”},{“token”:“authentication_token_2”,“source”:“authenticaton_source_2”,“created”:"16-12-12"}],"地址":[{"street":"address_street_1","city":"address_city_1""zip":"address_zip_1""country":"address_country_1""created":"16-12-12"}]}好处显而易见:通过保留实体的JSON表示,您可以更快更好地访问数据。进一步推广这种方法,从NoSQL数据库中读取所有的读操作,而将所有的写操作(创建、更新、删除)保留在RDBMS上。但是必须实现一个逻辑来保持从RDBMS到NoSQL的数据同步,如果它不在缓存中,则创建一个关系数据库对象。当NoSQL高效且可扩展地创建文档时,为什么还要使用RDBMS?因为那不是应用程序的真正目的。我不想产生大爆炸效应。假设RDBMS已准备就绪,但由于RDBMS缺乏灵活性而集成了NoSQL存储。希望充分利用两项最好的技术——尤其是RDBMS的数据一致性和NoSQL的可扩展性。【本文来自专栏作家老曹的原创文章,作者微信公众号:哦家ArchiSelf,id:wrieless-com】
