文档数据库的学习报告

0 目录:

       1 大数据环境下的背景

       2传统关系数据库的瓶颈

       3文档数据库的选择

       4 什么是文档数据库

                4.1 什么是文档?

4.2 JSON数据格式

4.3那么是什么是文档型数据库呢?

4.4有哪些文档数据库?

       5文档数据库的一些关键特点

6 文档数据库数据模型

7文档数据库数据建模技术

8文档数据库的适用场景

    8.1文档数据库适用场景的考虑因子

8.2适用的场景

8.3不适用场景

       9引用参考


1 大数据环境下的背景

随着互联网web2.0网站的兴起,Web 技术的最新进展使得所有用户都可以轻松地提供和使用所有格式的内容. 另外, 后web2.0时代是网络发展中一个重要的阶段,它连接着下一代互联网Web3.0. 在这个时代背景下,互联网、物联网每天都在产生大量的数据,这些庞大的数据资源,使得’‘大数据’‘得以问世. 大数据的出现,直接导致’‘资源’‘的含义发生极大的变化,例如:

* 构建一个个人网站(比如,Google Sites)

* 创建一个博客(使用 WordPress、Blogger 和 LiveJournal)

* 在网络社区进行交互(使用 Facebook、Twitter、LinkedIn等等)

这些渠道已成为商品和工具,使更多的人能够更多元化地轻松创建、使用和传输更多数据,比如,采用博客、微博、微信、社交网络交互、视频、音频和照片的形式,数据可以是结构化的,也可是非结构化的. 就创建、交流、访问内容、共享信息和购买产品而论,快速扩展的新一代基于 Internet 的服务(比如电子邮件、博客、社交媒体、搜索和电子商务)实际上重新定义了 Web 用户的行为和趋势. 由于这些系统的数量的不断增多, 所生成数据和所消耗数据的规模的不断扩大,不断增长的伸缩性需求和新功能需求, 为传统关系型数据库管理系统 (RDBMS) 带来了新的挑战.

2 传统关系数据库的瓶颈

随着互联网web2.0网站的兴起,非关系型的数据库现在成了一个极其热门的新领域,非关系数据库产品的发展非常迅速. 而传统的关系数据库在应付 web2.0网站,特别是超大规模和高并发的SNS类型的web2.0动态网站已经显得力不从心,暴露了很多难以克服的问题

1对数据库高并发读写的需求

web2.0网站要根据用户个性化信息来实时生成动态页面和提供动态信息,所以基本上无法使用动态页面静态化技术,因此数据库并发负载非常高,往往要达到每秒上万次读写请求. 关系数据库应付上万次SQL查询还勉强顶得住,但是应付上万次SQL写数据请求,硬盘IO早已经无法承受了. 其实对于普通的 BBS网站,往往也存在对高并发写请求的需求,例如像JavaEye网站的实时统计在线用户状态,记录热门帖子的点击次数,投票计数等,因此这是一个相当普遍的需求.

2对海量数据的高效率存储和访问的需求

类似Facebook,Twitter,Instagram,  Friendfeed这样的社交网站,每天用户产生海量的用户动态,以Friendfeed为例,一个月就达到了2.5亿条用户动态. 对于关系数据库来说,在一张2.5亿条记录的表里面进行SQL查询,效率是极其低下乃至不可忍受的. 再例如大型web网站的用户登录系统,例如腾讯,盛大,动辄数以亿计的帐号,关系数据库也很难应付.

3对数据库的高可扩展性和高可用性的需求

在基于web的架构当中,数据库是最难进行横向扩展的,当一个应用系统的用户量和访问量与日俱增的时候, 数据库却没有办法像web server和app server那样简单的通过添加更多的硬件和服务节点来扩展性能和负载能力. 对于很多需要提供24小时不间断服务的网站来说,对数据库系统进行升级和扩展是非常痛苦的事情,往往需要停机维护和数据迁移,为什么数据库不能通过不断的添加服务器节点来实现横向扩展呢?

然而在上面提到的’‘三高’‘需求面前,关系数据库遇到了难以克服的障碍,而对于web2.0网站来说,关系数据库的很多主要特性却往往无用武之地,例如:

1数据库事务一致性需求

很多web实时系统并不要求严格的数据库事务,对读一致性的要求很低,有些场合对写一致性要求也不高. 因此数据库事务管理成了数据库高负载下的一个沉重负担.

2数据库的写实时性和读实时性需求

对关系数据库来说,插入一条数据之后立刻查询,是肯定可以读出来这条数据的,但是对于很多web应用来说,并不要求这么高的实时性,举个例子, 如某用户在某个blog网站上发一条消息之后,过几秒乃至十几秒之后,该用户的订阅者才看到这条动态是完全可以接受的.

3复杂的SQL查询,特别是多表关联查询的需求

任何大数据量的web系统,都非常忌讳多个大表的关联查询,以及复杂的数据分析类型的复杂SQL报表查询,特别是SNS类型的网站,从需求以及产品设计角度来看,就需要避免这种情况的产生. 往往更多的只是单表的主键查询,以及单表的简单条件分页查询,SQL的功能被极大地弱化了.

在这些情况下, 大部分的MySQL都应该是IO密集型的. 然而事实上,如果MySQL是个CPU密集型的话,那么很可能MySQL在设计存在性能优化问题. 大数据量高并发环境下的MySQL应用开发越来越复杂,也越来越具有技术挑战性. 分表分库的规则把握都是需要经验的. 虽然有像淘宝这样技术实力强大的公司开发了透明的中间件层来屏蔽开发者的复杂性,但是避免不了整个应用架构的复杂性. 分库分表的子库到一定阶段又面临扩展问题. 还有就是需求的变更,可能又需要一种新的分库方式. 除此之外,  MySQL数据库也经常存储一些大文本字段,导致数据库表非常的大,在做数据库恢复的时候就导致非常的慢,不容易快速恢复数据库. 比如1000万4KB大小的文本就接近40GB的大小,如果能把这些数据从MySQL省去,MySQL将变得非常的小.

尽管关系数据库很强大,但是它并不能很好的应付所有的应用场景.  MySQL的扩展性差(需要复杂的技术来实现),大数据下IO压力大,表结构更改困难,正是当前使用MySQL的开发人员面临的问题.

3 文档数据库的选择

如今的社交网站越来越普及,而随着用户量不断壮大,每个用户的使用方式或者是发布的内容类型都不尽相同. 有人会发布风景照片或者剪短的视频、有人发布对时事的评论, 还有人分享音乐用于表达心情等. 面对如此大量而多样性的数据,如果使用关系型模型,就需要不断修改数据操作模式,这样,可能会引起系统负载的大幅度提升,同时也会大大增加处理的响应时间.

在这个背景下,希望新类型的数据库可以有以下特点:

1易扩展:关系型数据库是一种’’纵向扩展’’的技术,想要扩展容量(无论数据存储还是I/O),都需要更换更大的服务器. 现代应用结构的解决却是使用’’横向扩展’’ --无需新购买更大的服务器,只需要在负载均衡器下增加一般的服务器、虚拟机或是云服务器就可以实现扩展. 此外,容量在不再需要的时候还可以轻易的缩减. 事实上, NoSQL数据库种类繁多,但它们的一个共同特点就是去掉关系数据库的关系型特性. 数据之间无关系,这样就非常容易扩展. 在架构的层面上带来了可扩展的能力.

2大数据量,高性能:NoSQL数据库都具有非常高的读写性能,尤其在大数据量下,同样表现优秀. 这得益于它的无关系性,数据库的结构简单. 一般MySQL使用Query Cache,每次表的更新Cache就失效,是一种大粒度的Cache,在针对web2.0的交互频繁的应用,Cache性能不高. 而NoSQL的Cache是记录级的,是一种细粒度的Cache,所以NoSQL在这个层面上来说就要性能高很多了.

3灵活的数据模型::NoSQL的’’横向扩展’’部署方案的优点已经受到了业界的注意,但是同时很多人忽略的是NoSQL数据管理的简洁,不需要很复杂的操作模式构建,这一点对于数据库的提升也和扩展模型一样重要. 在使用传统关系数据库时,添加数据前,需要定义操作模式. 之后每一条记录的加入都需要严格的按照定义的操作模式进行,比如固定的列数和数据类型. 因此,改变那些分区关系型数据库的操作模式,就会非常的麻烦. 如果数据获取和数据管理需求经常变化,那这种严格的模式限制将会成为制约表现的屏障. 然而NoSQL无需事先为要存储的数据建立字段,随时可以存储自定义的数据格式. 而在关系数据库里,增删字段是一件非常麻烦的事情. 如果是非常大数据量的表,增加字段简直就是一个噩梦. 这点在大数据量的web2.0时代及后web2.0时代尤其明显.

4高可用:NoSQL在不太影响性能的情况,就可以方便的实现高可用的架构. 比如Cassandra,HBase模型,通过复制模型也能实现高可用.

这时,文档型模型存储就凸显其优点了,面对复杂多变的数据,使用文档型模型就直接保留了原有数据的样貌,不需要另外创建新的表, 新的操作模式来处理,这样不仅存储直接快速,再过后调用时,也可以做到’‘整存整取’‘,不需要关系型模型那样再到各种链接的表上取出需要显示的记录. 在RDBMS中,需要尽可能的标准化数据. 而在NoSQL中,则是可以尽可能的对数据’‘去标准化’‘. 另外在社交网络当中,用户的操作量很大,许多人每天会花很多的时间泡在社交网络之中. 使用传统关系数据模型时,例如,两个用户的发布信息同时链接到了’‘地点’‘,那么其中一个人回头修改自己的发布时,因为链接到了’‘地点’‘表,系统为了保证一致性就会把’‘地点’‘表锁住不让其他用户同时提出修改,这时另外的用户暂时就没办法操作’‘地点’‘表了. 如果使用文档型模型,每个人的发布就是独立的一个’‘文档’‘,这一个文档文件就包含了这一条发布的所有信息. 因为这种’‘自包含’‘的特性,不同的用户修改数据只需要修改自己的文档而不会影响别人的操作. 这样就实现了高的并发性!

4 什么是文档数据库

4.1 什么是文档?

使用’‘文档’‘这个词似乎让人觉得奇怪,但是其实 ‘‘文档型数据模型’‘真的和传统意义的文字’‘文档’‘没有什么关系. 它不是书、信或者文章,这里说的’‘文档’‘其实是一个数据记录,这个记录能够对包含的数据类型和内容进行’‘自我描述’‘.

文档是文档数据库中的主要概念. 此类数据库可存放并获取文档,其格式可以是XML,JSON,BSON, YAML等. 这些文档具备自述性(self-describing),呈现分层的树状结构(hierarchical tree datastructure). 可以包含映射表、集合和纯量值.

说到底, 文档其实是一个数据记录,这个记录能够对包含的数据类型和内容进行’‘自我描述’‘. 每个文档都是自包含的数据单元,是一系列数据项的集合. 每个数据项都有一个名称与对应的值,值既可以是简单的数据类型,如字符串、数字和日期等;也可以是复杂的类型,如有序列表和关联对象. 每个文档都有一个全局惟一的标识符(ID)以及一个修订版本号(revision number).  ID用来惟一标识一个文档,而修订版本号则用来实现多版本并发控制(Multiversion concurrencycontrol,MVVC).

另外对于文档的处理往往指的是文档存储. 文档存储指的是用于存储、搜索与管理面向文档的信息(半结构化数据)的程序,其中心概念就是文档. 具体的面向文档数据库的实现是不同的,不过总的来说,他们都会以各种标准化格式对数据(即文档)进行封装与加密. 文档往往是以 JSON对象的形式保存的.

4.2那么JSON格式什么样的数据格式, 又为什么选择JSON格式来存储文档?

JSON (JavaScript Object Notation) 是IETF RFC 4627中指定的一种轻量型数据交换格式. 它被设计为极小的、可移植、文本化的JavaScript子集,JSON易于实现、容易阅读且容易使用. 它不依赖于任何语言,因为大多数语言都拥有能与 JSON 轻松对应的特性.  JSON可用于在使用所有现代编程语言编写的程序之间交换数据. 另外,由于JSON采用了文本格式,所以它容易被人类和机器阅读.  JSON通过定义很少的一些概念,帮助实现结构化数据的可移植性. JSON中的主要概念是对象,它是’’名称/值’’对的一个无序集合,其中的值可以是任何JSON值. JSON中有4个可在大多数编程语言中通用的原子概念:

字符串, 数字, 布尔值和特殊的’‘null’‘值

此外JSON数组引入了有序的值序列,这同样可以是具有前面提到的4种JSON类型之一的JSON 值.  JSON 对象可以嵌套,但通常不会嵌套很深. 如下图所示:

尽管JSON是JavaScript 编程语言的子集,但它本质上是与语言无关的. 大多数语言,无论新旧,都拥有可轻松地与JSON 概念建立对应关系的特性. 例如,哈希图、对象、结构、记录和关联数组都是与JSON对象类型相关的数据类型,而数组、矢量和列表类型与JSON数组类型相关.

基于这样的事实: ‘‘在互操作方面需要达成一致的意见越少,就越容易实现互操作’‘, JSON 是应用程序新时代的首选数据交换格式. 它的出现和流行有一些推动因素. 最重要的因素是JavaScript的普遍性. JavaScript无处不在.

常常流传的对JSON的一种赞美是,它基于文本且不依赖于位置,但XML也拥有相同的特性.为什么JSON在API中大受欢迎,而不是XML大受欢迎呢?在2011年,Programmable Web报告1/5的新API选择使用JSON而不是XML,这一比例到2012年12月增长到了1/4, 而且许多既有的企业(比如 Box.net 和 YouTube)正在从XML转向JSON. 一些因素促成了这一转变. 首先JSON 更简单,它的所有操作都与对象相关. 它没有试图成为一种文档标记语言,或者是数据交换语言. 这种标记和交换语言的双重用途会使人们更难使用XML. 由于JSON的简单性,它更加紧凑,需要存储、流经网络并在移动和嵌入式设备上处理的信息更少.

鉴于此,JSON成为了NoSQL文档存储(比如MongoDB和CouchDB)所利用的主要技术,这不足为奇. 通过在数据库层中提供JSON支持,为新时代应用程序的开发人员带来了敏捷性(通过模式灵活性实现). 此外,JSON使开发人员能够更容易配合他们选择的编程语言,支持直接本机存储从移动设备流经应用程序层,再流到磁盘的数据, 这减少了数据转换和散发的开销.

4.3那么是什么是文档型数据库呢?

从60年代末开始, 数据库技术经历了层次数据库、网状数据库和关系数据库而进入数据库管理系统( DBMS)阶段至今, 数据库技术的研究也不断取得进展.  80年代关系数据库成为发展的主流, 几乎所有新推出的DBMS产品都是关系型的. 关系型数据库在计算机数据管理的发展史上是一个重要的里程碑,这种数据库具有数据结构化、最低冗余度、较高的程序与数据独立性、易于扩充、易于编制应用程序等优点,目前较大的信息系统都是建立在结构化数据库设计之上的.

然而,随着网络技术和软件技术的飞速发展,特别是Internet和Intranet技术的发展,使得非结构化数据的应用日趋扩大. 关系数据库从1970年发展至今, 虽功能日趋完善, 但对数据类型的处理只局限于数字、字符等, 对多媒体信息的处理只是停留在简单的二进制代码文件的存储. 然而随着用户应用需求的提高、硬件技术的发展和Intranet/Internet提供的多彩的多媒体交流方式, 用户对多媒体处理的要求从简单的存储上升为识别、检索和深入加工, 正是用户呼唤 出’‘通用’‘数据库服务器来处理占信息总量70%的声音、图像、时间序列信号和视频等复杂数据类型. 随着应用领域的不断拓展和多媒体技术, 人们发现关系数据库的许多限制和不足,因而数据库技术进入了’‘后关系数据库时代’‘. 文档数据库由此应运而生.

文档数据库与五、六十年代管理数据的文件系统不同,文档数据库仍属于数据库范畴. 首先,文件系统中的文件基本上对应于某个应用程序. 当不同的应用程序所需要的数据有部分相同时,也必须建立各自的文件,而不能共享数据,而文档数据库可以共享相同的数据. 因此,文件系统比文档数据库数据冗余度更大,更浪费存储空间,且更难于管理和维护. 其次,文件系统中的文件是为某一特定应用服务的,所以,要想对现有的数据再增加一些新的应用是很困难的,系统不容易扩充. 数据和程序缺乏独立性. 而文档数据库具有数据的物理独立性和逻辑独立性,数据和程序分离.

文档数据库也不同于关系数据库, 关系数据库是高度结构化的, 而文档数据库允许创建许多不同类型的非结构化的或任意格式的字段, 与关系数据库的主要不同在于, 它不提供对参数完整性和分布事务的支持, 但和关系数据库也不是相互排斥的, 它们之间可以相互交换数据, 从而相互补充、扩展.

文档数据库区别于传统的其它数据库,它是用来管理文档. 在传统的数据库中, 信息被分割成离散的数据段,而在文档数据库中,文档是处理信息的基本单位. 文档可以很长、很复杂、可以无结构,与字处理文档类似.

基于以上的认识, 简单来说, 一个文档数据库实际上是一系列文档的集合,而这些文档之间并不存在层次结构. 数据库中的文档彼此相似, 但不必完全相同,文档数据库所存放的文档, 相当于键值数据库存放的’‘值’‘. 文档数据库可视为其值可查的键值数据库.

文档数据库除了某些特定的转换外,通常都是通过HTTP为其提供数据,然后将数据存储为JSON(JavaScript ObjectNotation)格式的文档,并提供多种语言的API接口.

面向文档的非关系数据库主要解决的问题不是高性能的并发读写,而是保证海量数据存储的同时,具有良好的查询性能.

4.4有哪些文档数据库?

1 MongoDB:是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的. 他支持的数据结构非常松散,是类似JSON的BJSON格式,因此可以存储比较复杂的数据类型. Mongo最大的特点是它支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引.

它的主要特点是高性能、易部署、易使用,存储数据非常方便.

它的主要功能特性有:

2 CouchDB:是一个面向文档的数据库管理系统. 它提供以JSON作为数据格式的REST接口来对其进行操作,并可以通过视图来操纵文档的组织和呈现. CouchDB是Apache基金会的顶级开源项目. CouchDB落实到最底层的数据结构就是两类B+Tree. 与现在流行的关系数据库服务器不同,CouchDB是围绕一系列语义上自包含的文档而组织的.

3 RavenDB:是个新的.NET, 支持Linq的开源文档数据库, 旨在Windows平台下提供一个高性、结构简单、灵活、可扩展NoSQL存储.  Raven将JSON文档存在数据库中, 可以使用C#的Linq语法查询数据. 下面是一个简单的例子.

5文档数据库的一些关键特点

大多数非关系数据库都具有快速和可伸缩的特性. 通过放弃关系存储模型和架构,关系数据库便可脱离由紧密结合的架构所带来对其施加的限制. 应用程序也无需再链接数据库内表中的数据.  MongoDB和CouchDB以及RavenDB等文档数据库除了某些特定的转换外,通常都是通过HTTP为其提供数据,然后将数据存储为JSON格式的文档,并提供多种语言的API接口. 这三款开源的文档数据库都将简洁、速度和可伸缩性作为其设计的重要指标.

下面就介绍一些文档数据库通用的关键特点.

1 RESTful HTTP API

RESTful API设计就是为了消除创建松散耦合服务时的依赖关系,这也正是过去分布式体系结构的缺陷. 虽然要映射到一些协议需要依赖于元数据的可用性以及方法等,但REST API的设计目标就是不依赖于任何通信协议.

众多NoSQL数据库都可通过RESTful的方式访问. 这样可以通过URI的方式建立数据库连接,而查询和命令则通过HTTP实现. MongoDB和CouchDB都提供了特定语言的API接口,以便编写和执行查询、更新. 但MongoDB的默认设置仍然是使用TCP与数据库进行连接. 而RavenDB则具备基于.NET的客户端API,可简化与数据库的交互过程.

2单个记录中的相关数据

大多数人都错误的认为非关系数据库是一种包含没有相对关系结构的记录的文件. 而文档数据库中存储的数据包含形状数据——具有节点的树. 数据库中的每个记录都是以文档形式存在的. 并具备自我描述的功能,而不依赖于任何其他文档.

3唯一键

所有数据库都需要键. 如果不提供键, 系统则会自动在内部创建一个键. 键对于数据库的索引功能至关重要. 自身域中要求有已知键,并利用键值并允许用户定义文档间关系的方式.

4以JSON格式存储数据

1 共同点都是使用JSON存储器数据. 事实上,CouchDB和RavenDB(以及其他许多数据库)均采用JSON格式存储数据.  MongoDB对JSON使用称之为“二进制JSON”(BSON)的转换,以便能够执行二进制序列化. BSON是数据的内部表现形式,从编程的角度看开发者不会发现有任何区别.

2 JSON的简洁性使其很容易将几乎所有语言的对象结构转换为JSON. 因此,开发者可在应用程序中定义对象,然后将其直接存储在数据库中. 这使得开发人员不需要使用对象关系映射程序(ORM)不断在数据库架构和’’类/对象’’架构之间进行转换.

3 MongoDB的BSON API的数据类型和约定列表添加了一种数据类型及其他一些数据类型,以便充实JSON中的可用内容. 而在一个单元中存储和检索相关数据可提供显著的性能和可伸缩性的优势. 数据库不必四处查找常用的相关的数据,因为数据都存储在相同的位置上.

5存储灵活性

1 文档数据库对内容没有强制的结构或者是定义,任何文档都可以储存任何的信息和结构.

2 可以使用一个验证程序来检查提供给数据库文档的结构,验证可以同时针对字段以及字段的内容.

3 鉴于没有严格的数据结构类型这一事实,它可以给存储带来更高的灵活性. 举个例子,开发者不需要额外的操作就可以向recipe文档中添加新的部分’’食谱的提供人’’这个数据成员.

4 这里同样没有多重表的概念,这里只有数据库,数据库中只包含了文档. 如果开发者想让同一个数据库支持各种不同类型的信息,开发者可以向文档中加入字段, 那么type就可以作为标记在数据库其它的地方使用,用以识别或者选择开发者正在加载的数据.

6类型的集合

与数据库交互时,应用程序是如何知道哪一项代表学生,哪一项代表书,以及哪一项代表博客文章?数据库使用集合这一概念解决了这一问题.  对于与特定集合(如学生集合)关联的任何文档(无论其架构如何)都可在从该集合请求数据时对其进行检索. 使用字段来指示类型也十分常见. 这只是使搜索过程更加轻松,但哪些内容应进入集合,哪些不应进入集合,由开发者的应用程序决定.

7文档数据库和领域驱动开发

规划域类(可能成为数据库中的文档)时,开发者可查找通常最为独立的数据(例如具有其明细项的订单),并将其作为单个数据结构加以关注. 在订购系统中,可能还有客户和产品. 但或许会在不需要订单的客户信息的情况下访问该订单,并且可能会在不需要访问使用产品的订单的情况下使用该产品. 这意味着,尽管会发现许多机会来包含独立数据结构(如具有其明细项的订单),但这并不表示在某些情形下可以不必或者不通过外键联接数据.

每个数据库都提供各种可用模式的指南,并为用户指明使用哪些模式可以获得最大成功.  例如MongoDB文档讨论称为’’上级数组’’的模式,它可加快在联接文档时对相关数据的访问速度.

8查询和更新

每个数据库都附带用于查询和更新的API. 尽管它们可能不是核心API的一部分,但多语言的API是通过加载项提供的. 其他查询依赖预定义的视图和称为’’Map/Reduce’’的模式. 此过程的映射阶段使用这些视图,并且各个数据库的映射职责是不同的. 映射还使数据库能够跨多个处理器分发查询处理. 化简阶段可获取映射查询(如果已分发,则为多个查询)的结果,并将数据聚合到要返回到客户端的结果中.

尽管CouchDB要求开发者通过预定义的’’Map/Reduce’’视图进行查询,但MongoDB(也使用视图和’’Map/Reduce’’), 另外提供执行临时查询的功能. RavenDB允许使用预定义索引进行查询,但也支持临时查询,并将根据开发者的实际运行时查询自动为其创建索引. 但在大多数时候,当不采用SQL数据库的已知架构和关系本质时,开发者会丢失的一个功能是执行临时查询的功能. 通过严格控制查询,文档数据库能够实现其快速查询性能.

6 文档数据库数据模型

NoSQL的’’横向扩展’’部署方案的优点已经受到了业界的注意,但是同时很多人忽略的是NoSQL数据管理的简洁,不需要很复杂的操作模式来构建,这一点对于数据库的提升也和扩展模型一样重要. 在使用传统关系数据库时,添加数据前,需要定义操作模式. 之后每一条记录的加入都需要严格的按照定义的操作模式进行,比如固定的列数和数据类型. 因此,改变那些分区关系型数据库的操作模式,会非常的麻烦. 如果数据获取和数据管理需求经常变化,那这种严格的模式限制将会成为制约表现的屏障.

NoSQL(无论文档型、列式、键值对等等)都是水平扩展的,它们都不需要预先定义操作模式、所以也不需要在需求改变时, 改变操作模式.

尽管良好有规律的关系数据库RDBMS数据建模已经存在很多年,从逻辑到物理的映射技术已经被广泛专业人士实践使用,然后,随着最近出现的NoSQL数据库,数据库建模面临相关挑战,一般来说,NoSQL实践者关注物理数据模型设计,而不像传统的概念/逻辑数据模型,原因如下:

1以开发者为中心,使用NoSQL数据库支持的灵活的Schema(或者schema-free),应用开发者通常负责数据模型的设计,他们有认识到数据库表结构Schema是应用逻辑的最主要部分.

2运行在大规模可扩展的分布式环境中对高性能查询的考虑,与传统集中式垂直伸缩的系统包括RDBMS层,现代应用是运行在一个分布式,水平伸缩的环境,为了完成水平扩展,应用开发者通过关注物理数据模型设计能够解决可扩展性和性能问题,因此,放弃了传统概念和逻辑设计, 以及传统物理数据模型设计的过程.

3大型且非结构化数据,严格的固定的Schema(表结构)和有限的水平扩展能力,传统关系数据库因此一直被批评为却反对大型和非结构化数据的支持,相比而下,NoSQL数据库使用灵活的Schema在分布式水平扩展的环境中, 存储大量且非结构化数据是其特点.

7文档数据库数据建模技术

关系模型试图将数据库模型和数据库实现分开,让开发者可以脱离底层很好的操作数据. 但关系模型在一些应用场景下有弱点,现在已经不得不面对.

* SQL弱点一:必须支持Join.

因为数据不能够有重复. 所以使用范式的关系模型会不可避免的大量Join. 如果参与Join的是一张比内存小的表还好. 但是如果大表Join或者表分布在多台机器上的话,Join就是性能的噩梦.

*SQL弱点二:计算和存储耦合.

关系模型作为统一的数据模型既可以用于数据分析,也可以用于在线业务. 但这两者一个强调高吞吐,一个强调低延时,已经演化出完全不同的架构. 用同一套模型来抽象显然是不合适的.  Hadoop针对的就是计算的部分.  MongoDB和Redis等针对在线业务. 两者都抛弃了关系模型.

针对这两个梦魇. 文档数据库如MongoDB的的主要目的是:

提供更丰富的数据结构来抛弃Join来适应在线业务

当然也不是MongoDB完全不能用Join,不能拿来做数据分析,讨论这个只是见仁见智的问题. 所以文档数据库并不比关系数据库强大,由于对Join的弱支持,功能会弱许多. 设计关系模型的时候,通常只需要考虑好数据直接的关系,定义数据模型. 而设计文档数据库模型的时候,还需要考虑应用如何使用. 因此设计好一个的文档数据库Schema比设计关系模型更加的困难. 除此之外,由于文档数据库事务的支持也是比较弱,一般NoSQL只会提供一个行锁. 这也给设计Schema更加增加了难度. 对于文档数据库的使用有很多需要注意的地方,因此本文只关注文档数据库的模型设计的部分, 下面就介绍一些文档数据库的数据建模技术:

1反规格化 - Denormalization :

可以被认为是把相同的数据拷贝到不同的文档或是表中,以空间换时间, 这样就可以简化和优化查询,或是正好适合用户的某中特别的数据模型. 总体来说,反规格化需要权衡下面这些东西:

* 查询数据量/查询, 即IO VS总数据量. 使用反规格化,一方面可以把一条查询语句所需要的所有数据组合起来放到一个地方存储. 这意味着,其它不同查询所需要的相同的数据,需要放在别不同的地方. 因此,这产生了很多冗余的数据,从而导致了数据量的增大.

* 处理复杂度VS总数据量. 在符合范式的数据模式上进行表连接的查询,很显然会增加了查询处理的复杂度,尤其对于分布式系统来说更是. 反规格化的数据模型允许以方便查询的方式来存构造数据结构以简化查询复杂度.

2聚合 - Aggregates:

所有类型的NoSQL数据库都会提供灵活的Schema(数据结构,对数据格式的限制). 文档数据库是一种层级式的’’去Schema’’的存储,有以下特点:

* 灵活的Schema允许开发者可以用一种嵌套式的内部数据方式, 来存储一组有关联的业务实体.

* 最小化’’一对多’’关系, 即可以通过嵌套式的方式来存储实体,这样可以少一些表联结.

* 可以让内部技术上的数据存储更接近于业务实体,特别是那种混合式的业务实体. 可能存于一个文档集或是一张表中.

3应用层联结 - Application Side Joins:

表联结基本上不被NoSQL支持. 正如前面所说的,NoSQL是’’面向问题’’, 而不是’’面向答案’’的,不支持表联结就是’’面向问题’’的后果.

表的联结是在设计时被构造出来的,而不是在执行时建造出来的. 所以表联结在运行时是有很大开销的,但是在使用了Denormalization和Aggregates技术后,开发者基本不用进行表联结,如:使用嵌套式的数据实体. 当然,如果需要联结数据,只需要在应用层完成这个事. 下面是几个主要的Use Case:

* 多对多的数据实体关系, 即经常需要被连接或联结.

* 聚合Aggregates并不适用于数据字段经常被改变的情况. 对此需要把那些经常被改变的字段分到另外的表中,而在查询时只需要联结数据.

         4原子聚合-Atomic Aggregates:

很多NoSQL的数据库在事务处理上都是短板. 在某些情况下,它们可以通过分布式锁技术或是应用层管理的MVCC技术来实现其事务性, 但是通常来说, 只能使用聚合Aggregates技术来保证一些ACID原则.

这就是为什么关系型数据库需要有强大的事务处理机制, 因为关系型数据库的数据是被规格化存放在了不同的地方. 所以Aggregates聚合允许开发者把一个业务实体存成一个文档、存成一行,存成一个key-value,这样就可以原子式的更新了.

当然,原子聚合Atomic Aggregates这种数据模型并不能实现完全意义上的事务处理,但是如果支持原子性,锁,或 test-and-set 指令,那么Atomic Aggregates是可以适用的.

5降维 - Dimensionality Reduction:

Dimensionality Reduction是一种技术可以允许把一个多维的数据映射成一个Key-Value或是其它非多维的数据模型.

传统的地理位置信息系统使用一些如’’四分树QuadTree’’或’’R-Tree’’来做地理位置索引. 这些数据结构的内容需要被在适当的位置更新,并且如果数据量很大的话,操作成本会很高.

另一个方法是遍历一个二维的数据结构并把其扁平化成一个列表. 一个众所周知的例子是Geohash(地理哈希). 一个Geohash使用’’之字形’’的路线扫描一个2维的空间,而且遍历中的移动可以被简单地用0和1来表示其方向,然后在移动的过程中产生0/1串.

如上图所示, 上图展示了这一算法:先把地图分成四份,经度为第一位,纬度为第二位,于是左边的经度是0,右边的是1,纬度也一样,上面是为1,下面的为0. 这样,经纬度就可以组合成01,11,00,10这四个值,其标识了四块区域,如此不断的递归地对每个区域进行四分,然后可以得到一串1和0组成的字串,然后使用0-9,b-z去掉(去掉a, i, l, o)这32个字母进行base32编码得到一个8个长度的编码,这就是Geohash的算法.

Geohash的最强大的功能是使用简单的位操作就可以知道两个区域间的距离. Geohash把一个二维的坐标生生地变成了一个一维的数据模型,这就是降维技术.

         6树形聚合-Tree Aggregation:

树形或是任意的图(需反规格化), 可以被直接打成一条记录或文档存放.

* 当树形结构被一次性取出时这会非常有效率(如需要展示一个blog的树形评论).

* 搜索和任何存取这个实体都会存在问题.

* 对于大多数NoSQL的实现来说,更新数据都是很不经济的(相比起独立结点来说).

         7 反转搜索- InvertedSearch 和直接聚合- Direct Aggregation:

这个技术更多的是数据处理技术,而不是数据建模技术. 尽管如此,这个技术还是会影响数据模型. 这个技术最主要的想法是使用一个索引来找到满足某条件的数据,但是把数据聚合起需要使用全文搜索.

还是来说一个示例. 假设有很多的日志,其中包括互联网用户及他们的访问来源. 假定每条记录都有一个UserID,还有用户的种类 (Men, Women, Bloggers, 等),以及用户所在的城市,和访问过的站点. 要干的事是,为每个用户种类找到满足某些条件(访问源,所在城市,等)的的独立用户.

很明显,需要搜索那些满足条件的用户,如果使用反转搜索,这会把这事干得很容易,如: {Category -> [userIDs]} 或 {Site -> [user IDs]}. 使用这样的索引,可以取两个或多个UserID要的交集或并集(这个事很容易干,而且可以干得很快,如果这些UserID是排好序的). 但是,要按用户种类来生成报表会变得有点麻烦,因为查询语句可能会像下面这样:

但这样的SQL很没有效率,因为category数据太多了. 为了应对这个问题, 可以建立一个直接索引 {UserID ->[Categories]} 然后用它来生成报表.

最后需要明白,对每个UserID的随机查询是很没有效率的. 可以通过批查询处理来解决这个问题. 这意味着,对于一些用户集,可以进行预处理不同的查询条件.

8 邻接列表 - Adjacency ListsAdjacency Lists :

邻接列表是一种图, 图中的每一个结点都是一个独立的记录,其包含了所有的父结点或子结点. 这样,开发者就可以通过给定的父或子结点来进行搜索. 当然,开发者需要通过hop查询遍历图. 这个技术在广度和深度查询,以及得到某个结点的子树上, 没有效率.

9 嵌套文档扁平化:

搜索引擎基本上来说和扁平文档一同工作,如:每一个文档是一个扁平的字段和值的列表. 这种数据模型的用来把业务实体映射到一个文本文档上,如果开发者的业务实体有很复杂的内部结构,这可能会变得很有挑战. 一个典型的挑战是把一个有层级的文档映映射出来. 例如,文档中嵌套另一个文档. 看看下面的示例:

上面的每一个业务实体代码一种简历. 其包括了人名和一个技能列表. 需要把这个层级文档映射成一个文本文档,一种方法是创建 Skill 和 Level 字段. 这个模型可以通过技术或是等级来搜索一个人,而上图标注的那样的组合查询则会失败.

为每个字段都标上数字 Skill_i和Level_i,这样就可以分开搜索每一个对(下图中使用了OR来遍历查找所有可能的字段).

但是这样的方式根本没有扩展性,对于一些复杂的问题来说只会让代码复杂度和维护工作变大.

8 文档数据库的适用场景

对于哪些类型的数据来说,它的存储并不适合采用关系型数据库,而是适宜选择文档型数据库?下面将从三个方面来阐述文档数据库的适用因子、适用场景和不适用场景:

8.1文档数据库适用场景的考虑因子:

1关键是要意识到不同的应用需要不同的数据模型和产品. 选择合适的数据模型和产品.

2要了解应用需要什么样的数据模型.

3适应需求和应用场景. 依次就能找到最适合的架构的产品.

4综合考虑数据模型、产品特性和应用情景. 不同产品功能各异,只凭数据模型来决定选择谁是不可能的.

5哪个产品具有最需要的特点, 哪个就是最好的.

6这在很大程度上依赖于所开发应用的需求. 有些应用可能需要高可用性,但是对数据一致性没有那么高的要求,像日志聚合系统和内容显示系统很可能就适合这样的模型. 而其他系统可能对数据一致性要求很高,却没有高可用性需求. 因此开发者需要根据CAP理论中的选项做出决策. 在传统的关系数据库中,有些决策已经由数据库本身确定了.

7应用程序的使用情况不同,会对可用性、响应时间和一致性的需求也有所不同. 要做出正确的决策,必须理解底层业务需求.

8.2适用的场景:

1日志事件记录:

应用程序对事件记录各有所需,在企业级解决方案中, 许多不同的应用程序都需要记录事件. 文档数据库可以把所有这些不同类型的事件都存起来, 并作为事件存储的’‘中心数据库’‘使用.如果事件捕获的类型一直在变, 那么就更应该用文档数据库了. 可以按照触发事件的应用程序名’‘分片’‘, 也可以按照’‘order_processed’‘或者’‘customer_logged’‘等事件类型’‘分片’‘.

2内容管理系统级博客平台:

由于文档数据库没有’‘预设模式’‘,而且通常支持JSON文档,所以它们很适合用在’‘内容管理系统’‘及网站发布程序上,也可以用来管理用户评论、用户注册、用户配置和面向Web文档.

3网站分析与实时分析:

鉴于文档数据库的弱模式结构,不改变模式下就可以储存不同的度量方法及添加新的度量. 它可以存储实时分析数据. 由于可以更新部分文档内容,所以用它来存储’‘页面浏览量’‘或者’‘独立访客数’‘会非常方便,而且不用改变模式就可以新增度量标准.

4电子商务应用程序:

电子商务类应用通常需要较为灵活的模式,以存储产品和订单. 同时它们需要在不做高成本数据库重构及数据迁移的前提下进化其数据模型.

8.3不适用场景:

1 在不同的文档上添加事务.  文档数据库并不支持文档间的事务,如果对这方面有需求则不应该选用这个解决方案.

2 包含多项操作的复杂事务. 文档数据库也许不适合执行’‘跨文档的原子操作’‘.

3 查询持续变化的聚合结构. 灵活的模式意味着数据库对模式不施加任何限制. 数据以’‘应用程序实体’‘的形式存储. 如果要即时查询这些持续改变的实体,那么所使用的查询命令也不得不变化(用关系型数据库的术语讲,就是:用JOIN语句将数据表按查询标准连接起来时,待连接的表一直在变). 由于数据保存在聚合中,所以假如聚合的设计持续变动,那么就需要以’‘最低级别的粒度’‘来保存聚合了,这实际上等于要统一数据格式了. 在这种情况下,文档数据库也许不合适.

9 引用参考

1 Lotus文档数据库与关系数据库比较

2关系型到文档型的跨越:颠覆你对数据库数据模型的认识

3 NoSQL反模式 - 文档数据库篇

4 NoSQL数据库技术特性解析之文档数据库

5 NoSQL数据库探讨之一 - 为什么要用非关系数据库?

6一网打尽当下NoSQL类型、适用场景及使用公司

7 NoSQL数据建模

8 NoSQL数据库的35个应用场景

9 NoSQL开篇——为什么要使用NoSQL

文档数据库的学习报告相关推荐

  1. 学计算机专业英语报告范文,计算机学习报告

    计算机学习报告怎么写?本频道是免费计算机学习报告网站,为您整理了海量优秀的计算机学习报告相关论文范文和参考文献!对您的毕业论文与职称论文写作有着参考价值,涵盖大学计算机学习报告范文和格式模板以及相关的 ...

  2. Datawhale自组织学习报告!

    ↑↑↑关注后"星标"Datawhale 每日干货 & 每月组队学习,不错过 自组织学习报告 设计:吕豪杰,张帆,杨冰楠  Datawhale成员 第14期自组织学习 6月2 ...

  3. 计算机应用基础形考报告2020,放大学计算机应用基础形考本学习报告

    放大学计算机应用基础形考本学习报告Tag内容描述: 1.学 海 无 涯 模块模块 1 windows 7 操作系统操作系统客观题客观题 (答案)(答案) 1.以( )为核心组成的微型计算机属于集成电路 ...

  4. python量化投资培训清华大学深研院_GitHub - CatsJuice/quantitative-investment-learning: 使用Python进行量化投资的学习报告...

    quantitative-investment-learning 使用Python进行量化投资的学习报告 Python量化投资学习报告 CatsJuice 编辑于 2019-4-26 上一次更新: 2 ...

  5. 计算机图形学学习报告,计算机图形学学习报告.pdf

    精选公文范文 计算机图形学学习 报告 篇一:计算机图形学学习心得体会 计算机图形学学习心得体会 计算机科学与技术与技术 班 学号: 1.计算机图形学 计算机图形学(Computer Graphics, ...

  6. AI 质检学习报告——实践篇——第三步:python利用OpenCV打开摄像头截图后实现图片识字

    AI 质检学习报告--实践篇--第一步:python利用OpenCV打开摄像头并截图 AI 质检学习报告--实践篇--第二步:实现图片识字 前边两篇实践已经分别实现了利用OpenCV打开摄像头并截图和 ...

  7. AI 质检学习报告——实践篇——第二步:实现图片识字

    AI 质检学习报告--实践篇--第一步:python利用OpenCV打开摄像头并截图 上次实践已经能够实现利用OpenCV打开摄像头并截图,这次做一个图片识字. 效果 准确率还可以,主要是我手机的进网 ...

  8. 计算机组成与架构综述学习报告

    计算机组成与架构综述学习报告 计算机系统的指令集ISA的演进过程是怎样的? 第一阶段关键词:集成电路.CISC.432.8086.IBM PC 集成电路在摩尔定律的预言下快速发展,使得CPU的控制单元 ...

  9. 计算机图形学学习报告,计算机图形学学习报告.doc

    计算机图形学学习报告 篇一:计算机图形学学习心得体会 计算机图形学学习心得体会 计算机科学与技术与技术 班 学号: 1.计算机图形学 计算机图形学(Computer Graphics,简称CG),狭义 ...

  10. 2048java课程设计报告_软件工程——Java版2048游戏学习报告

    2048游戏学习报告 姓名:王浩 专业:计算机科学与技术 年级:15级4班 学号:201510411420 目录 一. 前言                                       ...

最新文章

  1. 机器人车间气管_汽车消声器生产中的焊接机器人应用与工艺流程
  2. 高性能Mysql--Schema与数据类型优化
  3. latex 分页_latex 图片跨页显示问题???
  4. Python json模块 - Python零基础入门教程
  5. java反射 Method
  6. 我写的不只是小说更是程序人生
  7. pythonwhile循环怎么修改数据类型_分级程序有while循环问题,使用不同的数据类型...
  8. zul ajax使用线程池
  9. 微软应用商店_重新安装微软应用商店,并解决无法联网的问题
  10. 「 机器人学 」机器人与控制工程基础浅谈
  11. css设置背景虚化,vue移动端登录页
  12. 小米手机访问电脑共享文件_小米随身Wifi让手机共享电脑文件教程
  13. android捕获按键广播,Android 解决监听home键的几种方法
  14. 「Hortic Res」APETALA2的同源物CaFFN可调节辣椒的开花时间
  15. pip 和conda
  16. [转]杂谈如何绕过WAF(Web应用防火墙)
  17. [极客大挑战 2019]Http
  18. 可编程渲染管线4 聚光灯阴影
  19. galerkin有限元法matlab实现,PDE的Galerkin和有限元的MATLAB程序
  20. 电力行业人员定位管理解决方案之智能巡检

热门文章

  1. 用超级鹰来识别B站图片验证
  2. java生成xps文件_Java 将 Excel 转为PDF、图片、html、XPS、XML、CSV
  3. 编译原理自顶向下语法分析
  4. 利用VS软件生成可执行的文件(.exe文件)
  5. python绘图在图中添加标记
  6. 大一c语言程序考试常考程序题,大一c语言考试试题[1]
  7. 软件设计师考试真题链接
  8. 3DMAX安装包+安装教程
  9. c的花体字_[转载]花体字~~漂亮~
  10. 微信小程序云开发实现微信小程序订阅消息服务通知教程