早就想写一篇数据库概念类的文章,奈何本人能力实在有限,难以着笔。但实在又想多多了解数据库方面知识,开拓了解更多相关理念,还是尽力收集一些资料弥合起来。我没有发现知识,我只是收集一些我想了解的知识。本文前部分主要 根据五月的仓颉的《Sql Or NoSql,看完这一篇你就懂了》此文展开,加上自己知识盲区的部分补充!仅仅作为备忘记录。
数据库,顾名思义是用来存取数据的。然而数据类型众多,比如:文本、图片、HTML、各类报表、视音频等等,不同的数据存储结构,会很大程度影响了数据库引擎的选型。没有一种事物是完美的,数据库也一样,有些数据库擅长存取结构化的数据,有些则擅长存取非结构化的数据。为什么擅长?因为需要,所以也会摈弃,做出权衡!下面了解一下数据存储结构分类:
<person>
<name>张三</name>
<age>18</age>
<phone>12345</phone>
</person>
关系数据库自不必多说了,相信各位入门第一种数据库课程就是关系型的数据库。
NoSql的全称为Not Only SQL,泛指非关系型数据库,是对关系型数据库的一种补充,特别注意补充这两个字,这意味着NoSql与关系型数据库并不是对立关系,二者各有优劣,取长补短,在合适的场景下选择合适的存储引擎才是正确的做法。
类型 | 部分代表 | 特点 |
---|---|---|
列存储 | 1.Hbase 2.Cassandra 3.Hypertable | 按列存储数据的。最大的特点是方便存储结构化和半结构化数据,方便做数据压缩,对针对某一列或者某几列的查询有非常大的IO优势。 |
文档存储 | 1.MongoDB 2.CouchDB | 文档存储一般用类似json的格式存储,存储的内容是文档型的。这样也就有机会对某些字段建立索引,实现关系数据库的某些功能。 |
key-value存储 | 1.Redis 2.MemcacheDB | 可以通过key快速查询到其value。一般来说,存储不管value的格式,照单全收。 |
搜索型 | ElasticSearch | 全文搜索能力强 |
图存储 | 1.Neo4J 2.FlockDB | 图形关系的最佳存储。使用传统关系数据库来解决的话性能低下,而且设计使用不方便。 |
对象存储 | 1.db4o 2.Versant | 通过类似面向对象语言的语法操作数据库,通过对象的方式存取数据。 |
xml数据库 | 1.Berkeley DB XML 2.BaseX | 高效的存储XML数据,并支持XML的内部查询语法,比如XQuery,Xpath。 |
Redis
Redis又是KV型NoSql中应用最广泛的NoSql。
优点:高性能(TPS 10万级别)
缺点:
适用场景:缓存
MongoDB
文档型NoSql是没有Schema的,由于没有Schema的特性,我们可以随意地存储与读取数据,因此文档型NoSql的出现是解决关系型数据库表结构扩展不方便的问题的。
优点:
缺点:
适用场景:
MongDB的使用场景很大程度上可以对标关系型数据库,但是比较适合处理那些没有join、没有强一致性要求且表Schema会常变化的数据。
ElasticSearch
传统关系型数据库主要通过索引来达到快速查询的目的,但是在全文搜索的场景下,索引是无能为力的,like查询一来无法满足所有模糊匹配需求,二来使用限制太大且使用不当容易造成慢查询,搜索型NoSql的诞生正是为了解决关系型数据库全文搜索能力较弱的问题
全文搜索的原理是倒排索引,我们看一下什么是倒排索引。要说倒排索引我们先看下什么是正排索引,传统的正排索引是文档–>关键字的映射,例如"Tom is my friend"这句话,会将其切分为"Tom"、“is”、“my”、"friend"四个单词,在搜索的时候对文档进行扫描,符合条件的查出来。这种方式原理非常简单,但是由于其检索效率太低,基本没什么实用价值。
倒排索引则完全相反,它是关键字–>文档的映射,我用张表格展示一下就比较清楚了:
意思是我现在这里有四个短句:
搜索引擎会根据一定的切分规则将这句话切成N个关键字,并以关键字的维度维护关键字在每个文本中的出现次数。这样下次搜索"Tom"的时候,由于Tom这个词语在"Tom is Tom"、“Tom is my friend”、"Tom is Betty’s husband"三句话中都有出现,因此这三条记录都会被检索出来,且由于"Tom is Tom"这句话中"Tom"出现了2次,因此这条记录对"Tom"这个单词的匹配度最高,最先展示。这就是搜索引擎倒排索引的基本原理,假设某个关键字在某个文档中出现,那么倒排索引中有两部分内容:
可以举一反三,我们搜索"Betty Tom"这两个词语也是一样,搜索引擎将"Betty Tom"切分为"Tom"、"Betty"两个单词,根据开发者指定的满足率,比如满足率=50%,那么只要记录中出现了两个单词之一的记录都会被检索出来,再按照匹配度进行展示。
优点:
缺点:
适用场景:
有条件搜索尤其是全文搜索的场景,作为关系型数据库的一种替代方案。
另外,搜索型数据库还有一种特别重要的应用场景。我们可以想,一旦对数据库做了分库分表后,原来可以在单表中做的聚合操作、统计操作是否统统失效?例如我把订单表分16个库,1024张表,那么订单数据就散落在1024张表中,我想要统计昨天浙江省单笔成交金额最高的订单是哪笔如何做?我想要把昨天的所有订单按照时间排序分页展示如何做?这就是搜索型NoSql的另一大作用了,我们可以把分表之后的数据统一打在搜索型NoSql中,利用搜索型NoSql的搜索与聚合能力完成对全量数据的查询。
HBase
列式NoSql,大数据时代最具代表性的技术之一了,以HBase为代表。
列式NoSql是基于列式存储的,那么什么是列式存储呢,列式NoSql和关系型数据库一样都有主键的概念,区别在于关系型数据库是按照行组织的数据:
看到每行有name、phone、address三个字段,这是行式存储的方式,且可以观察id = 2的这条数据,即使phone字段没有,它也是占空间的。
这么做有什么好处呢?大致有以下几点:
第二点说到了数据压缩,什么意思呢,以比较常见的字典表压缩方式举例:
优点:
缺点:
适用场景:
HBase比较适用于那种KV型的且未来无法预估数据增长量的场景
比对 | 关系型数据库 | 非关系型数据库 |
---|---|---|
定义 | 采用了关系模型来组织数据的数据库,关系模型中只包含单一的数据结构——关系,在用户看来关系模型中数据的逻辑结构是一张扁平的二维表,关系型数据库就是由二维表及其之间的联系所组成的一个数据组织。 | NoSQL的数据存储不需要固定的模式,无需多余操作就可以横向扩展。 |
特征 | 1.高度组织化结构化数据 2.结构化查询语言(SQL) 3.数据和关系都存储在单独的表中 4. 数据操纵语言,数据定义语言 5.严格的一致性 6.基础事务 |
1.代表着不仅仅是SQL 2.没有声明性查询语言 3. 没有预定义的模式 4.键 - 值对存储,列存储,文档存储,图形数据库 5. 最终一致性,而非ACID属性 6.非结构化和不可预知的数据 7.CAP定理 8. 高性能,高可用性和可伸缩性 |
优点 | 1.数据一致性,支持ACID特性,可以维护数据之间的一致性,是关系型数据库的核心。 2.易理解,支因为行 + 列的二维表逻辑是非常贴近逻辑世界的一个概念,关系模型相对网状、层次等其他模型更加容易被理解。 3.为维护数据一致性付出的代价大,SQL标准为事务定义了不同的隔离级别,从低到高依次是读未提交、读已提交、可重复度、串行化,事务隔离级别越低,可能出现的并发异常越多,但是通常而言能提供的并发能力越强。那么为了保证事务一致性,数据库就需要提供并发控制与故障恢复两种技术,前者用于减少并发异常,后者可以在系统异常的时候保证事务与数据库状态不会被破坏。对于并发控制,其核心思想就是加锁,无论是乐观锁还是悲观锁,只要提供的隔离级别越高,那么读写性能必然越差。 4.数据稳定,数据持久化到磁盘,没有丢失数据风险,支持海量数据存储。 5.服务稳定,最常用的关系型数据库产品MySql、Oracle服务器性能卓越,服务稳定,通常很少出现宕机异常。 |
1.高可扩展性,用户可以根据需要去添加的字段,不需要改变这个表的结构。 2.适用分布式 3.没有复杂的关系 4.低成本,Nosql数据库简单易部署,基本都是开源软件 5.存储数据的格式多,Nosql的存储格式是key,value形式、文档形式、图片形式等等,所以可以存储基础类型以及对象或者是集合等各种格式,而数据库则只支持基础类型。 6.查询速度快,Nosql数据库将数据存储于缓存之中,而且不需要经过SQL层的解析,关系型数据库将数据存储在硬盘中,自然查询速度远不及Nosql数据库。 |
缺点 | 1.高并发下IO压力大,数据按行存储,即使只针对其中某一列进行运算,也会将整行数据从存储设备中读入内存,导致IO较高。 2.为维护索引付出的代价大,为了提供丰富的查询能力,通常热点表都会有多个二级索引,一旦有了二级索引,数据的新增必然伴随着所有二级索引的新增,数据的更新也必然伴随着所有二级索引的更新,这不可避免地降低了关系型数据库的读写能力,且索引越多读写能力越差。有机会的话可以看一下自己公司的数据库,除了数据文件不可避免地占空间外,索引占的空间其实也并不少。 3.为维护数据一致性付出的代价大,通用的SQL语言使得操作关系型数据库非常方便,支持join等复杂查询,Sql + 二维关系是关系型数据库最无可比拟的优点。 4.水平扩展后带来的种种问题难处理,做了分库之后,数据迁移(1个库的数据按照一定规则打到2个库中)、跨库join(订单数据里有用户数据,两条数据不在同一个库中)、分布式事务处理都是需要考虑的问题,尤其是分布式事务处理,业界当前都没有特别好的解决方案。 5.表结构扩展不方便,由于数据库存储的是结构化数据,因此表结构schema是固定的,扩展不方便,如果需要修改表结构,需要执行DDL(data definition language)语句修改,修改期间会导致锁表,部分服务不可用。 6.全文搜索功能弱,例如like "%中国真伟大%",只能搜索到"2019年中国真伟大,爱祖国",无法搜索到"中国真是太伟大了"这样的文本,即不具备分词能力,且like查询在"%中国真伟大"这样的搜索条件下,无法命中索引,将会导致查询效率大大降低。 |
1.没有标准化 2.有限的查询功能(到目前为止) 3.最终一致是不直观的程序,非关系型数据库一般强调的是数据最终一致性,不像关系型数据库一样强调数据的强一致性,从非关系型数据库中读到的有可能还是处于一个中间态的数据, |
代表 | 1.Oracle,大型数据库 性能强 价格贵 支持原生内置分布式。 2.MS SQL Server,一般用于.net程序设计 3.My SQL,开源免费,体积小 PostgreSQL,DB2, Microsoft Access, SQLite等等 |
1.Redis 2.ElasticSearch 3.Mongodb 4.Hbase |
规范 | ACID 原子性(Atomicity) 一致性(Consistency) 隔离性(Isolation) 持久性 (Durable) | Base 基本可用(Basically Available) 软状态/柔性事务(Soft state) 最终一致性 (Eventual consistency) |
关系型数据库遵循ACID规则
事务在英文中是transaction,和现实世界中的交易很类似,它有如下四个特性:
1、A (Atomicity) 原子性
原子性很容易理解,也就是说事务里的所有操作要么全部做完,要么都不做,事务成功的条件是事务里的所有操作都成功,只要有一个操作失败,整个事务就失败,需要回滚。
比如银行转账,从A账户转100元至B账户,分为两个步骤:1)从A账户取100元;2)存入100元至B账户。这两步要么一起完成,要么一起不完成,如果只完成第一步,第二步失败,钱会莫名其妙少了100元。
2、C (Consistency) 一致性
一致性也比较容易理解,也就是说数据库要一直处于一致的状态,事务的运行不会改变数据库原本的一致性约束。
例如现有完整性约束a+b=10,如果一个事务改变了a,那么必须得改变b,使得事务结束后依然满足a+b=10,否则事务失败。
3、I (Isolation) 独立性
所谓的独立性是指并发的事务之间不会互相影响,如果一个事务要访问的数据正在被另外一个事务修改,只要另外一个事务未提交,它所访问的数据就不受未提交事务的影响。
比如现在有个交易是从A账户转100元至B账户,在这个交易还未完成的情况下,如果此时B查询自己的账户,是看不到新增加的100元的。
4、D (Durability) 持久性
持久性是指一旦事务提交后,它所做的修改将会永久的保存在数据库上,即使出现宕机也不会丢失。
BASE规则
CAP理论的核心是:一个分布式系统不可能同时很好的满足一致性,可用性和分区容错性这三个需求,最多只能同时较好的满足两个。
BASE是NoSQL数据库通常对可用性及一致性的弱要求原则:
数据库排名:https://db-engines.com/en/ranking
在互联网场景下,关系型数据库常见的性能瓶颈主要有两个
具体表现:
数据库占CPU高、Sql执行慢、客户端报数据库连接池不够等错误,因此例如万人秒杀这种场景,我们绝对不可能通过关系型数据库直接去扣减库存。
优化操作:
在系统初期,整体的并发了相对较小,因此一般都是将所有的数据信息存储在单库中进行读/写操作。但是随着用户规模不断提升,单库逐渐力不从心,TPS(系统吞吐量)/QPS(每秒查询次数)越来越低。因此可将数据库设置为读写分离状态(生产环境一般会采用一主一从或者一主多从),Master负责写操作,Slave作为备库,不开放写操作,但是允许读操作,主从之间保持数据同步即可。
读写分离之后,可以大大提升单库无法支撑的负载压力。
需要注意的是:如果Master存在TPS存在较高的情况,Master之前最好将同一份数据落到缓存中,以避免高并发情况下,从Slave中获取不到指定数据的情况发生。
读写分离让系统的吞吐量相对于单库来说有了一定的提升,但是只依靠读写分离并不能一劳永逸,随着用户规模攀升,系统瓶颈一定会暴露。
垂直分库就是根据自身业务垂直划分,将表拆分到不同的业务库中。实现分而治之的数据管理和读写操作。
单表数据量一大,读操作会逐渐成为瓶颈。
写操作因为是顺序写,所以基本上数据库的写入操作不会因为数据膨胀而成为瓶颈,但是读操作一定会存在上限;
读操作成为瓶颈的时候,就该做水平分库了
水平分表:将原本冗余在单库中的单个业务表拆分成为n个“逻辑相关”的业务字表(如:tab_000、tab_0001、……)
水平分库:如果Master的TPS过高,则还可以对垂直分库后的单一业务进行水平化,同水平分表类似。
分库分表操作主要是为了解决:高并发场景下单库的性能瓶颈,并充分利用分布式的威力提升数据库的读/写能力。
假设后续业务表中的数据量又一次达到存储阈值并对性能产生影响时,DBA只需要再次对现有业务库和业务表横向扩容,并迁移数据即可。
关系型数据库存储的是关系型数据,它有优点,同时也有明显的缺点,因此通常在企业规模不断扩大的情况下,不会一味指望通过增强数据库的能力来解决数据存储问题,而是会引入其他存储,也就是我们说的NoSql。
第一点,不多解释应该都理解,非关系型数据库都是通过牺牲了ACID特性来获取更高的性能的,假设两张表之间有比较强的一致性需求,那么这类数据是不适合放在非关系型数据库中的。
第二点,核心数据不走非关系型数据库,例如用户表、订单表,但是这有一个前提,就是这一类核心数据会有多种查询模式,例如用户表有ABCD四个字段,可能根据AB查,可能根据AC查,可能根据D查,假设核心数据,但是就是个KV形式,比如用户的聊天记录,那么HBase一存就完事了。
非核心数据尤其是日志、流水一类中间数据千万不要写在关系型数据库中,这一类数据通常有两个特点:
此时,一旦使用关系型数据库作为存储引擎,将大大降低关系型数据库的能力,正常读写QPS不高的核心服务会受这一类数据读写的拖累。
实际一个系统,通常是多种数据库配合使用的。
大多数的NoSql多可以通过简单的配置实现分布式部署。
1)分布式是指 多个系统协同合作完成一个特定任务的系统。
分布式是解决中心化管理的问题,把所有的任务叠加到一个节点处理,太慢了。
所以把一个大的问题拆分为多个小的问题,并分别解决,最终协同合作。分布式的主要工作是分解任务,将职能拆解。
2)集群主要的使用场景是为了分担请求的压力,也就是在几个服务器上部署相同的应用程序,来分担客户端请求。
当压力进一步增大的时候,可能在需要存储的部分,mysql 无法面对很多的写压力。因为在 mysql 做成集群之后,主要的写压力还是在 master 的机器上面,其他 slave 机器无法分担写压力,从而这个时候,也就引出来分布式。
分布式的主要应用场景是单台机器已经无法满足这种性能的要求,必须要融合多个节点,并且节点之间是相关之间有交互的。相当于在写 mysql 的时候,每个节点存储部分数据,也就是分布式存储的由来。存储一些非结构化数据:静态文件、图片、pdf、小视频 … 这些也就是分布式文件系统的由来。
3)集群主要是简单加机器解决问题,对于问题本身不做任何分解;
分布式处理里必然包含任务分解与答案归并。分布式中的某个子任务节点,可能由一个集群来代替;集群中任一节点,都是做一个完整的任务。
集群和分布式都是由多个节点组成,但是集群之间的通信协调基本不需要;而分布式各个节点的通信协调必不可少。
将一套系统拆分成不同子系统部署在不同服务器上(这叫分布式),
然后部署多个相同的子系统在不同的服务器上(这叫集群),部署在不同服务器上的同一个子系统应做负载均衡。
分布式:一个业务拆分为多个子业务,部署在多个服务器上 。
集群:同一个业务,部署在多个服务器上 。
集群master选举
1、投票制
2、借助ZK
分布式系统(distributed system)由多台计算机和通信的软件组件通过计算机网络连接(本地网络或广域网)组成。
分布式系统是建立在网络之上的软件系统。正是因为软件的特性,所以分布式系统具有高度的内聚性和透明性。
可靠性(容错) :
分布式计算系统中的一个重要的优点是可靠性。一台服务器的系统崩溃并不影响到其余的服务器。
可扩展性:
在分布式计算系统可以根据需要增加更多的机器。
资源共享:
共享数据是必不可少的应用,如银行,预订系统。
灵活性:
由于该系统是非常灵活的,它很容易安装,实施和调试新的服务。
更快的速度:
分布式计算系统可以有多台计算机的计算能力,使得它比其他系统有更快的处理速度。
开放系统:
由于它是开放的系统,本地或者远程都可以访问到该服务。
更高的性能:
相较于集中式计算机网络集群可以提供更高的性能(及更好的性价比)。
故障排除:
故障排除和诊断问题。
软件:
更少的软件支持是分布式计算系统的主要缺点。
网络:
网络基础设施的问题,包括:传输问题,高负载,信息丢失等。
安全性:
开放系统的特性让分布式计算系统存在着数据的安全性和共享的风险等问题。
在计算机科学中, CAP定理(CAP theorem), 又被称作 布鲁尔定理(Brewer’s theorem), 它指出对于一个分布式计算系统来说,不可能同时满足以下三点:
CAP理论的核心是:一个分布式系统不可能同时很好的满足一致性,可用性和分区容错性这三个需求,最多只能同时较好的满足两个。
因此,根据 CAP 原理将 NoSQL 数据库分成了满足 CA 原则、满足 CP 原则和满足 AP 原则三 大类:
CA - 单点集群,满足一致性,可用性的系统,通常在可扩展性上不太强大。
CP - 满足一致性,分区容忍性的系统,通常性能不是特别高。
AP - 满足可用性,分区容忍性的系统,通常可能对一致性要求低一些。
数据分区是一种物理数据库的设计技术,它的目的是为了在特定的SQL操作中减少数据读写的总量以缩减响应时间。
分区并不是生成新的数据表,而是将表的数据均衡分摊到不同的硬盘,系统或是服务器的其他存储介质中,实际上还是一张表。
优点:业务无感,多个物理存储,逻辑上还是一张表
1、相对于单个文件系统或是硬盘,分区可以存储更多的数据;
2、数据管理比较方便,比如要清理或废弃某年的数据,就可以直接删除该日期的分区数据即可;
3、精准定位分区查询数据,不需要全表扫描查询,大大提高数据检索效率;
4、可跨多个分区磁盘查询,来提高查询的吞吐量;
5、在涉及聚合函数查询时,可以很容易进行数据的合并;
局限:局限于单库,不能跨主机
分类:
表结构设计垂直切分。常见的一些场景包括
表结构设计水平切分。常见的一些场景包括
类似分库,且只有部分数据(redis,mysql…)库由此特性。
分片是把数据库横向扩展(Scale Out)到多个物理节点上的一种有效的方式,其主要目的是为突破单节点数据库服务器的 I/O 能力限制,解决数据库扩展性问题。Shard这个词的意思是“碎片”。如果将一个数据库当作一块大玻璃,将这块玻璃打碎,那么每一小块都称为数据库的碎片(DatabaseShard)。将整个数据库打碎的过程就叫做sharding,可以翻译为分片。
形式上,Sharding可以简单定义为将大数据库分布到多个物理节点上的一个分区方案。每一个分区包含数据库的某一部分,称为一个shard,分区方式可以是任意的,并不局限于传统的水平分区和垂直分区。一个shard可以包含多个表的内容甚至可以包含多个数据库实例中的内容。每个shard被放置在一个数据库服务器上。一个数据库服务器可以处理一个或多个shard的数据。系统中需要有服务器进行查询路由转发,负责将查询转发到包含该查询所访问数据的shard或shards节点上去执行。
优点:无限扩展,可以跨库、跨主机
局限:扩展时需要调整业务配置
分类:
垂直分片:不同的表分散到不同的数据库或主机,适用于低耦合系统;
水平分片:同一张表的数据分散到不同的数据库或主机,适用于复杂系统。
把一张表按一定的规则分解成N个具有独立存储空间的实体表。系统读写时需要根据定义好的规则得到对应的字表明,然后操作它。
分区和分表的区别与联系
分表能够解决单表数据量过大带来的查询效率下降的问题,但是,却无法给数据库的并发处理能力带来质的提升。面对高并发的读写访问,当数据库master服务器无法承载写操作压力时,不管如何扩展slave服务器,此时都没有意义了。因此,我们必须换一种思路,对数据库进行拆分,从而提高数据库写入能力,这就是所谓的分库。
单台DB的存储空间不够,随着查询量的增加单台数据库服务器已经没办法支撑
其主要目的是为突破单节点数据库服务器的 I/O 能力限制,解决数据库扩展性问题。
方式:
垂直拆分
将系统中不存在关联关系或者需要join的表可以放在不同的数据库不同的服务器中。
按照业务垂直划分。比如:可以按照业务分为资金、会员、订单三个数据库。
需要解决的问题:跨数据库的事务、jion查询等问题。
水平拆分
例如,大部分的站点。数据都是和用户有关,那么可以根据用户,将数据按照用户水平拆分。
按照规则划分,一般水平分库是在垂直分库之后的。比如每天处理的订单数量是海量的,可以按照一定的规则水平划分。需要解决的问题:数据路由、组装。
读写分离
对于时效性不高的数据,可以通过读写分离缓解数据库压力。需要解决的问题:在业务上区分哪些业务上是允许一定时间延迟的,以及数据同步问题。
思路:垂直分库–>水平分库–>读写分离
存在问题:
常用的解决方案:
对于不同的方式之间没有严格的界限,特点不同,侧重点不同。需要根据实际情况,结合每种方式的特点来进行处理。
选用第三方的数据库中间件(Atlas,Mycat,TDDL,DRDS),同时业务系统需要配合数据存储的升级。
=============================================================================================
参考文档:
Sql Or NoSql,看完这一篇你就懂了
简述关系型数据库和非关系型数据库
NoSQL 简介
大白话解说,半分钟就懂 — 分布式与集群是什么 ? 区别是什么?
关系型数据库的架构演变