导图社区 七周七数据库知识汇总
下图梳理了各种关系型与非关系型数据库的概述、特性介绍、使用场景,包括关系数据库、键值数据库、列型数据库、文档数据库、图数据库等。
编辑于2021-08-01 11:03:56七周七数据库
概述
关系数据库
以集合理论为基础的系统,实现为具有行和列的二维表, 表可以联接并转化为新的、更复杂的表
庞大的特性集(触发器、存储过程、高级索引)
数据的安全性(符合ACID)
atomic:所有的操作都成功或都没有做
consistent:数据将始终处于完整的状态,没有不一致的状态
isolated:事务互相之间不干扰
durable:即使在服务器崩溃以后,提交的事务都是安全
符合大多数人的思维方式
查询灵活性
比如:
MySQL,H2,HSQLDB,SQLite,PostgreSQL...
适合:
提前知道数据的schema
非关系数据库
键值数据库
将简单的键映射到(可能)更复杂的值(将键与值配对),就像一个巨大的哈希表。对资源的要求非常少,但不适合复杂的查询和聚合。查找速度快。只能从键查询到值,值的内容对查询不可见。
比如:Redis、Riak...
适合:
数据相关性不高,数据模型高度可变
只需要基本的CRUD操作为主
列型数据库
列的添加和版本控制很容易。允许表保持稀疏(sparse),而不会产生空值的存储成本
来自一个给定的列(在二维表的意义上)的数据存放在一起 添加列是相当简易的,而且是逐行完成的。每一行可以有一组不同的列,或完全没有。值的查询通过匹配键完成。
比如:HBase、Cassandra、Hypertable...
适合:
在几十、几百或几千个节点的集群上的“大数据”问题。
一个良好的列型数据存储问题的典型例子是索引网页。网页上有大量的文本(好处来自于压缩),在某种程度上相互关联,并随着时间变化(好处来自于版本控制)。
文档型数据库
文档就像是哈希,具有一个独一无二的标识符(ID)字段和值, 值可能是任何类型,包括更多的哈希。
文档可以包含嵌套的结构,因此,它们表现出了高度的灵活性,允许有可变域。 允许数据以嵌套的状态保存,能够以任意方式查询嵌套的数据。不强制使用schema。 文档全部对查询可见,可从文档内容查询到指定文档。
不像关系数据库那样彼此相关,它们比较容易在几个服务器上实现分片和复制,这使得分布式实现相当普遍
比如:MongoDB、CouchDB...
适合:
涉及高度可变领域的问题
能很好地映射到面向对象编程模型。这意味着在数据库模型和应用模型之间移动数据时,阻抗性不匹配的情况较少。
图数据库
图数据库包含节点及节点之间的关系。节点和关系可以有一些属性(一些键-值对),用来存储数据。
善于处理高度互联的数据。
图数据库的真正实力是按照关系遍历节点。
比如:
Neo4j
适合:
为网络应用量身定做,比如社交网络
是面向对象系统的完美匹配。
由于节点之间的高度相互关联,因此图数据库一般不适合网络分区
多持久并存
即同时使用几种数据库,利用各自的长处,比其各部分的功能总和更强大、更全面、更健壮
总结
关系数据库:PostgreSQL
特性
它的扩展包括自然语言解析、多维索引、地理查询、自定义数据类型等。
它具有高级的事务处理能力,支持十几种不同语言的存储过程,能在各平台上运行。
PostgreSQL内置支持Unicode、序列、表继承、子查询,而且是市场上遵循ANSISQL标准最好的关系数据库之一。
它快速可靠,可以处理TB量级的数据,
少数几个实现了窗口函数的开源数据库之一
窗口函数的结果不折叠每个组的结果。 返回所有匹配的记录,并复制所有聚合函数的结果:
扩展模块
模糊字符串匹配、自然语言处理、通用索引搜索树GIST、全文检索、欧氏距离
相比一般开源RDBMS
提供强大的约束机制
可以写自己的语言扩展,自定义索引,创建自定义的数据类型
优缺点:
分区不是强项。如果需要水平扩展而不是垂直扩展(多个并行的数据库而不是单个强大的机器或集群),可能最好寻找别的解决方案。
严格的数据模式要求
其他
B树是个很好的标准索引,值存储为平衡的树数据结构
键值数据库:Riak
特性
灵感来自Amazon Dynamo的论文
分布式键值数据库,值可以是任何类型数据
容错性强
服务器可在任何时刻启动或者停止,而不会引起任何单点故障。不管是增加或者移除服务器,甚至有节点崩溃,集群依然可以持续忙碌地运行
提供HTTP REST(表现层状态转移)接口
可以通过URL、HTTP头和HTTP方法(如POST)查询,Riak则会返回相应的数据和HTTP状态码
REST
通过使用http协议和uri(统一资源标识符),利用client/server model对资源进行CRUD操作
URL定位资源,用HTTP动词(GET,POST,DELETE,DETC)描述操作。
为什么要用RESTful结构
RESTful可以通过一套统一的接口为 Web,iOS和Android提供服务。另外对于广大平台来说,比如Facebook platform,微博开放平台,微信公共平台等,它们不需要有显式的前端,只需要一套提供服务的接口,于是RESTful更是它们最好的选择。
链接
将一个键关联到其他键的元数据称为链接,链接是单向的
Riak链接的特别之处在于链接遍历,以及一种更强大的变形:链接mapreduce查询
什么是mapreduce
mapreduce查询
在常规查询方式中,首先从数据库抓取数据,然后客户端(或者应用服务器)获取并处理数据(数据传给算法)
mapreduce会将某种算法传给数据库节点,之后每个节点负责返回各自的查询结果。节点服务器上的每个对象都“映射”(mapped)到一些常用的键,这些键用来将数据分组,接着,所有相互匹配的键都“归约”(reduced)成某些单一的值。(算法先传给数据,再传回算法)
Riak可以单独运行map函数并储存中间结果
可通过键过滤器避免加载不需要的键
解决冲突:
通过向量时钟与同级解决方案理清写操作的发生顺序,找出最近的写入操作。
优缺点:
致力于避免单点故障,设法支持最大的正常运行时间,并且增加(或者缩小)规模以适应变化的需求。可以扩展更多的节点服务器(而非扩展规模更大的单个服务器)
作为自由定义(adhoc)的查询框架,它依然不够简单而健壮
HBase:列型数据库
特性
在HBase表中,键可以是任意字符串,每个键都映射到一行数据。行本身也是一个映射表,其中的键称为列,而值就是未解释的字节数组
列按照列族(column family)进行分组,所以列的完全名称包含两个部分:'family:qualifier'
行键和列名(包括列族和限定符)的组合,形成了定位数据的地址。在这个例子中,三元组first/color:red指向了值'#F00'
为何要多个列族?
细粒度性能调优。每个列族的性能选项是独立配置的。这些设置影响到读和写的速度,以及磁盘空间的占用
版本管理
HBase为所有数据值保存一个整数时间戳,表示自某个时间(1970年1月1日00:00:00 UTC)以来的毫秒数。如果把新的值写入同一个单元,老的值将留在附近,按它的时间戳索引。大部分数据库要求你自己专门处理历史数据,但在HBase中,版本管理已经内置支持了。
压缩和Bloom过滤器
bloom:确定对于某个行键,是否存在某列(BLOOMFILTER=>'ROWCOL'),或 者 只 是 确 定 某 个 行 键 是否 存 在(BLOOMFILTER=>'ROW')
垃圾回收(对于超期的数据),以及内存表
很强的一致性保证,容易实现从关系数据库的迁移。
所有操作在行级是原子的。对于读或写的行,不论影响到多少列,该操作都会有一致的视图。这种设计决定有助于客户对数据做出聪明的推
如果某个客户端成功地写入了一个值,其他客户端将在接下来的请求中收到这个更新的值。
优缺点
可伸缩、内置版本管理、压缩、社区回答问题积极
几乎从来不会单独部署
除了行键之外,它不提供任何索引功能
行是按行键排序来保存的,但其他字段没有这样的排序,如列名和值。所以,如果你希望不按行键来查找行,就需要扫描表,或自己维护索引。
没有数据类型的概念,所有字段的值都作为不解释的字节数组
MongoDB:文档数据库
特性
是一个JSON文档数据库,可看成是没有schema的关系表,它的值可以嵌套任意深度
高伸缩性:因为无固定schema,所以可以随着数据模型而增长和变化
可自由定义查询,通过文档内容查询到特定文档
真正的力量来自于深入挖掘文档,并返回深层嵌套子文档的结果。要查询子文档,字段名称就是以点分隔的嵌套层的字符串。
相比其他文档数据库:
能够在多台服务器上实现伸缩,对集合进行复制(复制数据到其他服务器)或分片(将一个集合分成几片),并行执行查询。复制和分片都提高了可用性。
分片sharding
Mongo存在的一个核心理由,就是安全而快速地处理非常大的数据集。实现这个目标最清楚的方法,就是按值的范围进行横向分片,或简称分片(sharding)。不同于一个服务器存放一个集合的所有值,把有些范围的值切分(或者说分片)到其他服务器上。
例如,在电话号码集合中,可以将所有小于1-500-000-0000的电话号码放到Mongo服务器A上,将大于等于1-500-000-0001的放到服务器B上。Mongo通过自动分片、自动管理这种划分,从而使这样做变得更容易。
可以用索引来增加查询的速度(不是所有NoSQL都可以)
内置地理空间查询
通过特殊形式的索引地理数据geohash,不仅能在任意的查询中快速找到具体的值或范围,而且能快速找到附近的值。
优缺点
无需schema,能够通过复制和横向伸缩,处理大量的数据
易于使用,命令与sql数据库相似
鼓励反规范化的模式
CouchDB:文档数据库
基于JSON与REST的面向文档的数据库,值可取若干类型中的任意一种,包括嵌套任意深度的其他对象。但没有自由定义的查询。所有对CouchDB的调用都运行于REST接口之上。
优缺点:
小,小到可以运行在智能手机中;大,大到足以支持企业应用。CouchDB能够胜任各种部署场景。
轻易适应流行的Web技术
易于备份、文档支持二进制附件以及CouchApps——不通过中间件,直接开发并部署Web应用的系统。
基于映射规约的视图,虽然新颖,但是不能执行关系数据库中的数据分片。
复制是全部或者全无,也就是说,所有参与复制的服务器有着一样内容。于是,在数据分布到数据中心的过程中,没有分片。
也就是说,增加CouchDB节点是无法将数据四处分散的,而只是增加读写操作的吞吐量。
Neo4j:图数据库
支持原子性、一致性、隔离性以及持久性(ACID)事务的数据库,这与PostgreSQL是类似的。这使Neo4j成为重要数据存储的一种不错选择,而对于这一领域我们往往会采用关系数据库。
Neo4j是图数据库分类(相对较少的类别)中最好的开源实现。图数据库关注数据之间的关系,而不是值之间的共同特征。
顶点是键值集合形式存放的数据,顶点之间的边是关系,关系也能存放数据(属性)
特性
很小,小到足以嵌入几乎任何应用程序。
能够存储数百亿的节点与相同数量的边
一旦有了集群支持,在多个服务器间实现主从副本,Neo4j几乎能处理任何规模的问题。
自带一个相当好用的Web管理工具以及数据浏览器
优缺点
不但没有类型与模式的概念,而且它对于数据关联的方式没有限制
支持344亿个节点以及344亿个关系,足够应对任何领域的应用(Facebook有8亿用户,Neo4j能够在单个图中为其每个用户持有42个节点)。
易用。提供若干工具,整合Lucene进行快速查找,也可以用像Gremlin以及REST接口这样易用(相对于一些晦涩的)的语言扩展
不像关系数据库中的正交操作或者其他数据库中的map-reduce(映射-规约)操作,图遍历是常量时间复杂度的。
边无法从一个顶点回指其本身。
不能划分子图,这还是会限制图的大小(不过,公平地说,目前的限制也是以百亿计的)
使用GPL牌照,并不商业友好。
提供了强大的开源API并经过多年生产应用的检验,但是用户数依然较少
Redis:键值数据库
Redis是高级数据结构服务器,此外,它也是阻塞队列(或栈)和发布-订阅系统。它支持可配置的到期策略、持久性级别,以及复制选项。所有这些使得Redis不仅是某类数据库中的一员,更是有用的数据结构算法和程序的工具包。
没有达到文档型数据库的程度,但它支持高级的数据结构。它支持基于集合的查询操作,但不支持关系数据库中同样的粒度或类型。
能存储列表、哈希表、集合和有序集合,
每个键可以包含大量的值(最多2^32个元素,即超过40亿)。所有的Facebook账户作为一个列表,放在一个键下也毫无问题。
Redis的哈希表不能嵌套(任何其他的复杂数据类型也不行,如列表)。换言之,哈希表只能存储字符串值。
它很快,为了速度而在持久性方面作出了让步,若论速度,很多数据库难出其右。它读取速度快,写入速度更快。
适合辅助实现数据填充和缓存。
协助将数据填充到CouchDB(数据转换),作为Neo4j最近变化的缓存,作为部分值搜索的快速查找。它的速度和存储多种数据格式的能力非常适合数据填充,而其内置的到期策略可以完美地处理数据缓存。
为什么不直接填到couchdb里
Redis作为中间人,为扁平的TSV数据添加了结构,这样,随后插入另一个数据库就很快。
但会受到Redis的限制,只能将整个数据集保存在内存中
优缺点
像许多同类的键值对存储库一样,Redis的明显优势是速度快
与大多数键-值对存储库不同的是,Redis提供存储复杂值的能力,如列表、哈希表和集合,并基于这些数据类型上的特定操作来获取数据。
可选持久性。Redis不只是数据结构存储库,它的持久性选项允许你为了数据安全性而牺牲速度。
内存数据库有一个固有的持久性问题,如果你在快照发生之前关闭数据库,你可能会丢失数据。
不会支持比你的可用内存更大的数据集(Redis将不支持虚拟内存),所以它的大小有实际限制。
其他
什么是mapreduce
多个节点上执行并行任务的算法框架
允许系统将任务分成更小的组件任务
第一步 :通过map()方法,将一列数据转换成另一不同类型的一列数据。
第二步:通过reduce()函数,将map()方法所生成的那列数据转换成一个或者多个标量值。
复杂的算法得以在每个节点服务器上运行,从而计算得到传输开销很小的结果,并返回给发送请求的服务器。算法先发送到数据,再将数据发送到算法,是一种更快的查询方式。
举例:
如何计算一桶电话账单的总费用,电话账单以电话号码为键,分布在3个服务器上,每个服务器存有前缀相类似的所有电话号码。
map函数输出给reduce函数再输出给其他reduce函数
CAP定理
一致性、可用性、分区容错性
一致性
写入是原子的而且所有后续请求检索出新的值
可用性
只要一台服务器在运行,数据库将始终返回值
分区容错性
即使服务器的通信暂时中断了,系统仍将运行——那就是,网络分区
可以创建一个分布式数据库,它是一致的,可用的,或者分区容错的,但是你只能同时拥有以上特性中的两个
分布式数据库必须是分区容错的
如果你选择了可用性,你就不能拥有真正的一致性,你仍然可以提供最终一致性。
最终一致性背后的思想是,每个节点始终可用于服务请求。作为一个权衡,数据修改在后台被传播到其他节点。这意味着,在任何时候,系统可能会不一致,但是大体上数据仍是准确的。
现实是,在任何时刻,不能同时保证一致性、可用性与分区容错性。 一些分区容错的数据库可以调整为对每个请求或多或少一致或可用
Riak利用这个事实,允许在每个请求的基础上,以可用性交换一致性。
不仅需要cap,低延时也是主要关注之一。