huolan 2019-12-21
CouchDB服务器主机是一个存储文档的数据库。每一个文档在数据库中都有唯一的名字。CouchDB提供RESTful HTTP API用来读取和更新(添加,编辑,删除)数据库文档。
文档是CouchDB数据库中的主要单元数据由任意字段和附件组成。文档也包括由数据库系统维护的元数据信息。文档字段具有唯一的名字并且包含多种类型(文本,数字,布尔值,列表等)的值。并且文本大小或元素数量没有限制。
CouchDB文档更新模式是无锁的并且优化的。由客户端应用加载文档进行文档编辑,使用更新,最后存储回数据库。如果另一个客户端编辑了相同的文档并且首先保存了更新。那么客户端将会在存储时得到一个编辑冲突的错误。为了解决更新冲突,最新的文档版本将会打开,编辑将重新应用并再次尝试更新。
单个文档更新(添加,编辑,删除)是全有或者全没有的,要么完全成功,要么完全失败。数据库不支持并行存储或更新文档。
CouchDB文件层和系统提交特性具有全部的原子性,一致性,隔离性和持久性(ACID)属性。在硬盘中,CouchDB从不覆盖提交的数据或者被连接的结构。确保数据库文件总是保持一致性,这是一种“仅崩溃”设计,其中CouchDB服务器不执行关闭过程,而只是终止。
文档更新(添加,编辑,删除)是串行的,除了二进制字节的写操作是并行的。数据库读取者从来不会被锁住也不会写操作完成或者其他读者在读时等待。任何数量的客户端可以读取文档不需要加锁或者是被并行的更新打断即使是同一个文档。CouchDB读操作使用多版本并发控制(MVCC)模式。每一个客户端从开始读操作到结束看到的都是一致的数据库快照。这意味着CouchDB可以保证每个文档的事务语义。
文档通过他们的名字和序列号通过B-trees进行索引。每一次更新到数据库实例都会生成一个新的序列号。序列ID稍后用于在数据库中增量查找更改。文档存储或删除时B-tree索引也会同时进行更新。索引更新总是发生在文件(更新时只添加)最后。
文档数据的优势在于总是方便打包存储而不是和众多数据库系统一样分离成多个表和行。当文档提交到硬盘中,文档字段和元数据将序列化地一个文档接着一个文档(有助于稍后高效地构建视图)打包进缓冲区。
当CouchDB文档被更新后,所有的数据和相关的索引将被刷新到硬盘中总是以事务提交的方式使得数据库保持一致状态。提交通过两个步骤进行:
当在步骤一处系统崩溃或者电源被关闭,部分更新只是简单的抛弃并重新启动。如果崩溃发生在步骤二(头部信息提交时),仍保留以前相同标头的副本,以确保所有先前提交的数据的一致性。 除标题区域外,在崩溃或断电后无需进行一致性检查或修复。
通过偶尔压缩来回收浪费的空间。 按计划,或者当数据库文件超过一定数量的浪费空间时,压缩过程会将所有活动数据克隆到新文件中,然后丢弃旧文件。数据库在整个过程中始终保持完全在线,并且所有更新和读取都可以成功完成。仅当所有数据都已复制并且所有用户都已转移到新文件时,才删除旧数据库文件。
ACID属性仅处理存储和更新,但是我们还需要以有趣且有用的方式显示数据的能力,不像SQL数据库的数据必须小心地分解表,CouchDB中的数据以细小的机构存储在文档中。CouchDB文档变得更灵活并且他们拥有自己的隐含的结构。这减轻了双向复制表模式及其所包含数据的最困难的问题和陷阱。
但是,除了充当精美的文件服务器之外,用于数据存储和共享的简单文档模型太简单了,无法在其上构建真实的应用程序–它根本无法满足我们的期望和期望。 我们想要切片和切块,并以多种不同方式查看我们的数据。 现在需要一种过滤,组织和报告尚未分解为表格的数据的方法。
为了解决将结构添加回非结构化和半结构化数据的问题,CouchDB集成了视图模型。 视图是聚合和报告数据库中文档的方法,并且按需构建以聚合,联接和报告数据库文档。 由于视图是动态构建的,并且不会影响基础文档,因此您可以根据需要使用相同数据的不同视图表示。
视图定义严格是虚拟的,并且仅显示当前数据库实例中的文档,从而使其与显示的数据分离并与复制兼容。 CouchDB视图是在特殊设计文档中定义的,并且可以跨数据库实例(如常规文档)进行复制,因此不仅数据可以在CouchDB中复制,而且整个应用程序设计也可以复制。
视图是使用JavaScript功能定义的,该功能在map-reduce系统中充当map的一部分。 视图函数将CouchDB文档作为参数,然后进行所需的任何计算以确定通过视图提供的数据(如果有)。 它可以基于单个文档向视图添加多行,也可以根本不添加任何行。
视图是数据库实际文档内容的动态表示,而CouchDB可以轻松创建有用的数据视图。 但是,生成包含数十万或数百万个文档的数据库视图既浪费时间和资源,又不是系统每次都要从头做的事情。
为了保持视图的快速查询,视图引擎维护其视图的索引,并对其进行增量更新以反映数据库中的更改。 CouchDB的核心设计在很大程度上围绕着对视图及其索引的高效,增量创建的需求进行了优化。
视图及其功能在特殊的“设计”文档中定义,并且设计文档可以包含任意数量的唯一命名的视图功能。 当用户打开一个视图并自动更新其索引时,同一设计文档中的所有视图都被索引为一个组。
视图构建器使用数据库序列ID来确定视图组是否与数据库完全同步。 如果不是,则视图引擎将检查自上次刷新以来更改的所有数据库文档(以打包的顺序排列)。 按照在磁盘文件中出现的顺序读取文档,从而减少了磁盘头搜索的频率和成本。
可以同时读取和查询视图,同时也可以刷新视图。 如果客户端正在缓慢地流出大视图的内容,则可以同时为另一个客户端打开和刷新同一视图,而不会阻塞第一个客户端。 这适用于任何数量的同时进行的客户端阅读器,它们可以在同时为其他客户端刷新索引的同时读取和查询视图,而不会给阅读器造成问题。
当视图引擎通过您的“地图”和“缩小”功能处理文档时,它们的前一行值将从视图索引中删除(如果存在)。 如果通过视图功能选择了文档,则功能结果将作为新行插入到视图中。
将视图索引更改写入磁盘后,更新总是附加在文件末尾,以减少磁盘提交期间的磁盘头查找时间,并确保崩溃和电源故障不会导致索引损坏。 如果在更新视图索引时发生崩溃,则不完整的索引更新将丢失并从其先前提交的状态逐步重建。
为了保护可以读取和更新文档的人员,CouchDB具有简单的读取器访问和更新验证模型,该模型可以扩展为实现自定义安全模型。
CouchDB数据库实例具有管理员帐户。 管理员帐户可以创建其他管理员帐户并更新设计文档。 设计文档是包含视图定义和其他特殊公式以及常规字段和Blob的特殊文档。
将文档写入磁盘后,可以使用JavaScript函数动态地对其进行验证,以实现安全性和数据验证。 当文档通过所有公式验证标准时,将允许更新继续。 如果验证失败,更新将中止,用户客户端将收到错误响应。
用户凭证和更新的文档都作为验证公式的输入,可以通过验证用户的文档更新权限来实现自定义安全模型。
基本的“仅作者”更新文档模型的实现很简单,其中验证文档更新以检查用户是否在现有文档的“作者”字段中列出。 还可以使用更多的动态模型,例如检查单独的用户帐户配置文件的权限设置。
对于实时使用情况和复制的更新都执行更新验证,以确保共享的分布式系统中的安全性和数据验证。
CouchDB是基于节点的分布式数据库系统。它允许用户和服务器在断开连接时访问和更新相同的共享数据。这些更改随后可以双向复制。
CouchDB文档的存储,视图和安全模型旨在协同工作,以使真正的双向复制高效且可靠。文档和设计都可以复制,从而允许将完整的数据库应用程序(包括应用程序设计,逻辑和数据)复制到便携式计算机上以供脱机使用,或复制到远程办公室中的连接缓慢或不可靠,难以共享数据的服务器。
复制过程是增量的。在数据库级别,复制仅检查自上次复制以来已更新的文档。如果由于网络问题或崩溃等原因导致复制在任何步骤上失败,则下一个复制将在最后一个检查点重新启动。
可以创建和维护部分副本。可以通过JavaScript函数过滤复制,以便仅复制特定文档或满足特定条件的文档。这可以允许用户脱机使用大型共享数据库应用程序的子集供自己使用,同时保持与应用程序和该数据子集的正常交互。
冲突检测和管理是任何分布式编辑系统的关键问题。 CouchDB存储系统将编辑冲突视为一种常见状态,而不是例外状态。 冲突处理模型简单且“无损”,同时保留了单个文档的语义并允许分散式冲突解决。
CouchDB允许数据库中同时存在任何数量冲突的文档,每个数据库实例都确定性地确定哪个文档是“赢家”,哪些是冲突。 只有赢家文档可以显示在视图中,而“丢失”冲突仍然可以访问并保留在数据库中,直到在数据库压缩期间将其删除或清除为止。 因为冲突文档仍然是常规文档,所以它们像常规文档一样进行复制,并且要遵循相同的安全性和验证规则。
当发生分布式编辑冲突时,每个数据库副本都会看到相同的胜出版本,并且每个都有解决冲突的机会。 解决冲突可以手动完成,也可以根据数据的性质和冲突由自动代理完成。 该系统使分散式冲突解决成为可能,同时保持了单文档数据库的语义。
即使多个断开连接的用户或代理尝试解决相同的冲突,冲突管理也继续起作用。 如果解决的冲突导致更多的冲突,则系统将以相同的方式处理它们,在每台机器上确定相同的获胜者,并维护单个文档的语义。
仅使用基本复制模型,几乎无需额外的工作就可以使许多传统的单服务器数据库应用程序分布式。 CouchDB复制旨在立即用于基本数据库应用程序,同时还可以扩展以用于更详尽和功能齐全的用途。
只需很少的数据库工作,就可以构建具有精细安全性和完整修订历史记录的分布式文档管理应用程序。 可以实施文档更新以利用增量字段和Blob复制,其中复制的更新几乎与实际编辑差异(“差异”)一样高效和增量。