前言
前面我们讲了一些关于系统设计指标的一些基本概念,即可靠性,扩展性,易维护性。后面几篇本文将从数据库这个角度去介绍一些分布式系统的相关概念,主要介绍常用的一些数据库相关的内容,包括单机的,分布式的,介绍一些他们各自的设计特性,设计模式等等。
关于数据库
关于数据库,相信大家应该都用过,无论是研发,测试,还是运维,只要是计算机相关的肯定都知道数据库,然后目前应用最广泛的还是在关系型数据库,最常见的就是mysql,这点大家都清楚。
然后对我们来说,选择数据库的选择最为重要的就是,数据模型和存储引擎了,可以这么说,是他们决定了数据库,存储引擎相当于数据库的发动机,也可以说是内核,它决定了一个数据库的的实现,数据库特性,甚至是应用场景。然后数据模型相当于是数据库的外壳,直接和程序相关联,面对开发者,关于存储引擎下一篇在进行一个讲解,本章主要是分析不同的数据模型下的相关产品。
想象一下,如果你是一个开发者,你面对一个真实的世界,你需要做的就是将这个真实的世界结构化,如花,草,河流,大厦, 可以直接转变为数据模型,像json, xml, kv, 表格关系,然后如何去选择一个合适的数据模型呢?然后如果作为一个数据库工程师,需要去想怎么将这些数据模型在内存中,磁盘中,或则是在网络中进行呈现,而且还需要去允许这些数据用多种方式进行搜索,查询。一个复杂的应用程序可能是有多个层次组成,他们通过api, 接口,驱动进行一个各自的调用,隐藏了底层的实现的复杂性,不过他们的一个核心观点是需要一个数据模型匹配。
数据 模型
Sql vs Nosql
SQL这个数据模型第一次提出是在1970年,当时这还是一种理论观点,人们都怀疑,这种数据模型的实现是否高效,最开始应用的是一些主要是在商业化的领域(银行,航空公司),其实运用主要是应用事务。然后到了1980年中期,关系型数据库已经成为大多数人选择去存储结构化数据库的选择,到目前为止关系型数据库的优势已经持续了30-40年,目前它依旧是最广为人知的数据模型。
sql 数据模型(行数据模式):
sql数据库: 关系如下,每个关系是一个表格,由多个行构成,每行包含多个属性。
sql 在于有两个非常重要的特性,事务和索引,索引是为了减少SQL执行过程扫描的数据量,提高读取性能,数据库事务规定了各个数据库操作的ACID特性。
nsql出生
随着社会的进步,社交,电商,物联网慢慢应用到生活中,需要记录的数据也是越来越多,面对的应用场景也越趋复杂,这对我们的系统提出了更多的挑战,需要解决扩展性,并发,性能,数据模型严格等等问题,这时候大而全的关系型数据库显得有一些力不从心,我们不得不去考虑一些其他的数据模型和存储系统,终于在2010年,Nosql被提出来。
在提出来之后,开源社区已经产生了很多nosql数据库,如hbase, mongdb,redis等等,他们有比关系性数据库更好的扩展性,更容易存储大量的数据集,和更高的写入性能,以及弱化了数据库范式,当然并不是所有方面都优于关系型数据库, 例如他们在事务支持,数据可靠性方面就低于mysql,oracle等关系型数据库。
nosql数据库: 大量使用的简直模型,每行记录由主键和值组成。不支持多表连接查询,很多系统不支持二级索引。
其实,整体来说NoSql只是对SQL特性的一种取舍吧,使得SQL能更好的面对海量数据,两者的优势都是不断融合的,不存在取代的关系,对我们来说关系型数据库很通用,是业界标准,但是存在一定场景的可扩展性和性能问题,这时Nosql就有永无之地了,从学习来讲我们应该更关注关系型数据库的原理和Nosql系统的高可用。
文档型数据库
文档型数据库设计去存储,管理文档类似的半结构化数据,文档型数据库也是nosql中的一种,还有一种xml数据库,是属于用xml格式存储的文档型数据库,目前文档型数据库也越来越火,它可以去存储json, xml。
文档型数据库底层也是kv,它和其他kv不同在于,它的数据是经过处理的,然后存储引擎在存储的时候会去保存一些meta信息去优化数据的存取。所有说文档型数据库会对开发世界更友好,提供更好的数据模型。和关系型数据除了nosql相关差异,还有就是sql型数据库会将不同的数据放到不同的数据表中,而文档性会是将所有数据都保存在一个collection中,每个对象都是不同的,这对于面对对象的语言开发会比较方便,然后文档数据库最核心的就是文档,它功能是把接收到的数据进行一个编码,持久化,然后可以有多种存储方式进行编码,(感觉像是多种存储引擎) 比如xml, yaml, json,bson,甚至是pdf,像mongdb这样的更是实现了文件存储。
在关系型数据库中处理多对多关系和join连接非常容易,但是文档型数据库和nosql都重新打开了一个争论,就是如何去解决这个问题,这个问题甚至比nosql出现更早,事实上,这相当于是回到了更早的计算机系统,不过现在的一些文档性数据库已经尽力去解决这些问题了,像mongdb支持了reference, 再一个就是大数据处理方面更是支持了如map-reduce的操作,可以在操作上更好的支持OLAP(Online Analytic Processing)
文档型数据库: 例如xml和json
列型数据库
传统的行式数据库都是将完整的一个个数据保存在数据页中,如果查询需要用到大量的列,这种方式在OLTP(Online Transactions Processing )方式比较应用方便,但是在OLAP中,一个数据库查询可能需要查询几百万甚至是几十亿条数据行,而查询往往是关心少数的列,比如说我想要查询今年,销售最好的几款产品,那么你就需要时间,商品名,和销售量,而其他的像商品价格,商品分类,规格数据列就没有意义了,列数据库将通一个数据列放入一起,插入数据时,会放到不同的数据列中,然后数据查询只需要查询到需要查询的几个字段即可,其实就是走更少的数据页,因此在OLAP场景中,大大的提高的查询效率。
其实还有一些特性,像列数据库会有很多的重复字段,像性别,年龄等等,列数据库会把这些容易字段进行一个压缩,优化,这一点其实非常关键,一方面是加快查询速度,第二是节省了存储空间。(其实在关系型数据库中,对这种很多重复字段,加索引其实很多时候是无用的,还会拖慢数据库,像mysql优化器会直接走表扫描,而不是索引)
列数据库:
其实数据如果说要join,就需要行存储,如果需要进行聚合计算,就可以用列存储。以前机器很贵,所有表需要把表拆开,防止冗余,现在机器更便宜了,数据多了就可以多买机器,然后join慢了就用半结构化数据,并发慢就用异步复制,非强一致性的数据库,现在甚至还有mapreduce的框架进行大数据计算了。
cassadra和hbase都是代表性的列式存储,他们都是从google bigtable获取灵感。
总结:
这里简单的介绍一些数据库,主要从数据模型这个层次进行描述数据库,然后还有一些小众的像图数据,时序数据库这里就没有介绍,主要是阐述了一些数据库各种应用场景,优缺点,最后补充一点,还有一些新的NewSql数据库, 这里也没有介绍,我想单独花一点时间去读一下Spanner的论文在去分析,然后写出来,然后下一篇我们将会进入数据库的"发动机",存储引擎--关于如何实现存储引擎, 其中会涉及到相对底层的b+tree , lsm, hash 索引结构。
例:
关系型:
mysql , postgress, oracle, Microsoft SQL Server, db2
非关系型:
k-v : memcached, redis, memcacheDb
column-oriented: cassandra, hbase
document-oriented: mongdb, couchdb
graph-oriented: Neo4j, InForGird
NewSql :
spanner, tidb复制代码