从传统关系型数据库到NoSQL非关系型数据库(《分布式数据库HBase》导论)

传统关系数据库到NoSQL⾮关系型数据库(《分布式数
据库HBase》导论)
⼀ 什么是数据库
数据库顾名思义保存数据的仓库,其本质是⼀个具有数据存储功能的复杂系统软件,数据库最终把数据保存在计算机硬盘,但数据库
并不是直接读写数据在硬盘,⽽是中间隔了⼀层操作系统,通过⽂件系统把数据保存为本地⽂件系统的数据⽂件;我们讲过Hadoop,分布式⽂件系统HDFS的数据块本质上也是本地⽂件系统的普通数据⽂件。
⼆传统关系型数据库为什么⾏,⼜为什么不⾏了?
讲HBase之前,我们先从关系数据库讲起,再从逻辑上⼀步步推导出为什么要使⽤HBase
1 关系数据库为什么⾏?
从⼀个关系数据库的例⼦开始:我们学的过MySQL数据库,就是⼀个典型的关系数据库
⼀个关系数据表的典型例⼦:学⽣-课程-成绩表
⼀共三张关系表:
学⽣表(学号<string>,姓名<string>,年龄<int>)
学号(Prime Key)姓名年龄
S1张⼀20
S2王⼆18
S3李三19
S4赵四19
课程表(课程号<string>,课程名<string>,课时量<int>)
课程号(Prime Key)课程名课时量
C1语⽂108
C2数学72
C3英语72
成绩表(学号<string>,课程号<string>,成绩<float>)
学号(Prime Key)课程号(Prime Key)成绩
S1C195.5
S1C288.8
S1C370.0
S2C178.5
S2C288.6
S3C377.7
以上是在MySQL关系数据库中学过的,最常见的实体E-关系R表(2实体,1关系)的实例
但是马克思主义哲学认为,世界上所有的事物都是普遍联系的(离散数学中的对关系的定义)万事万物在本质上都处于同⼀张巨⼤
的“关系表”中,能够⽤⼀张⼤表来表⽰,
学⽣、课程、成绩也不例外,在没有进⾏关系模式分解之前,它们三者实质上也是出于同⼀张⼤表中(在离散数学⾥,这张⼤表实质上是学⽣、课程、成绩三个集合的笛卡尔积的⼀个⼦集,笛卡尔积全集总共应该是4*3=12条记录,我们取是⼀个7条记录的⼦集),学⽣课程成绩⼤表如下:
学号(Prime Key)姓名年龄课程号(Prime
Key)
课程名课时量成绩
S1张⼀20C1语⽂NULL95.5
S1张⼀20C2数学7288.8
S1张⼀C3英语7270.0
S2王⼆18C1语⽂10878.5
S2王⼆18C2数学7288.6
S3李三19C3英语7277.7
S4赵四19NULL NULL NULL NULL
NULL代表空值,说明没有实际意义的数据,但是每个NULL仍然占存储空间(1个字节)
那么问题来了,既然这样⼀张⼤表就可以表⽰学⽣、课程以及成绩三者之间的关系,并能完备的保存所有数据,那么为什么关系数据库要很⿇烦地把这张⼤表分解成三张⼩表呢?
⼀张同时保存学⽣,课程和成绩的⼀张⼤的关系表有什么问题(缺点)呢?
问题1:
数据冗余(很容易看出,学⽣,课程名等信息都保存了很多次,浪费了很多存储空间)
问题2:
数据丢失(学⽣赵四因为没有学习任何门课程,没有成绩,导致基本信息姓名年龄也没法保存)
问题3:
更新⿇烦(修改语⽂的课时量,要修改多次,更新多个存储单元,浪费算⼒)
问题4:
插⼊异常(假如插⼊⼀个学⽣马五,却未学习任何课程,课程是主键,没有任何成绩,则⽆法插⼊学⽣)
问题5:
删除异常(假如删除英语课程,会导致学⽣李三的信息也被删除了)
总之,采⽤⼀张⼤的关系表,不但会导致数据冗余,⽽且数据记录的增加、删除、修改都会出现异常问题!
经过关系模式分解,把⼀张⼤表拆分成学⽣、课程和成绩三张⼩表后,以上问题就都可以解决了;因此,关系数据库⼀般都有存在主外键关联的多张表,⽽不会⼀股脑的把所有数据⽤⼀张⼤表来存储;
但是⼀张⼤表是不是⼀⽆是处呢,会不会也有优点呢?
答案:⼀张⼤表的优点是查询⽐较⽅便,速度快;⽆论是查学⽣、查课程、查成绩都在同⼀张表操作即可,如果加上索引机制,速度会更快
那么新的问题⼜来了,既然传统关系数据库模型已经完美解决了数据存储和数据查询的问题,也不会有插⼊删除更新等异常,为什么还会出现⾮关系型数据库(NoSQL)呢?HBase就是⼀种典型的⾮关系型数据库!!⼀张⼤表⾃⼰跟⾃⼰何来关系?多张表之间才存在“关系”!
2 关系数据库⼜为什么不⾏了?
⼤家别忘了,我们现在处于⼤数据时代,所要存储和处理的数据量是PB/EB/ZB级别,⽽传统关系型数据库(如Oracle),能保存1亿条记录(每条记录⼏百个列),能达到TB级别基本就绝对是达到极限了,⽽⼤数据级别规模的数据库,需要保存的可能是上百亿条记录,每条记录⼏百万个列!!
⼤数据时代,数据规模⼤得不可想象、宏⼤⾄极、如浩瀚星宇!!
如此巨⼤的数据规模,传统关系数据库就⼒不从⼼了,原因如下:
1)数据存储
关系数据库的服务器存储容量不能横向扩展,⽆法存储海量数据,纵向扩展的程度有限,存储能⼒不
够;关系数据库是⾯向⾏的存储,某⾏的⼀个列字段即使是Null,也会占⽤⼀些(⼀个字节)存储空间,造成存储空间的巨⼤浪费
2)数据操作
查询操作:关系数据库⼀般都有多张表,select操作多会涉及到多张表,存在⼤量的多表关联查询,数据量不⼤还好,⽐如简单的联机事务处理OLTP,还可以应付;如果数据量⾮常⼤,⽐如是复杂的联机分析处理OLAP,需要对⼤量数据进⾏复杂的多表关联查询,多表关联查询⾮常⾮常慢,效率会⾮常⾮常低,导致传统关系数据库的失能。
那么有⼈会问,既然数据量很⼤时,会导致多表关联查询变慢,那么就不搞多张表了,还把⼏张⼩表合并成⼀张⼤表不就可以了吗?
答案:是个好主意,但是搞成⼀张⼤表,⼜退回到问题原点了,⼜会出现数据冗余、增删改的异常!!
因此,⼤数据时代的来临,⾯对不可想象的超⼤规模数据量,传统关系数据库⾯临进退两难的境地,进会导致复杂关联查询变慢,退会导致最基本的OLTP(增删查改操作)出错异常,进退维⾕,彻底歇菜!
除此之外,关系数据库还有⼀个问题,只能存储结构化数据(关系表的每个列字段的数据类型都是固定的事先定义好的);互联⽹⼤数据产⽣的数据⼀般多是半结构和⾮结构化的,关系数据库⽆法存储半结构⾮结构化数据
三 ⼤数据时代,HBase分布式数据库为什么⾏?
互联⽹公司最关⼼两个业务指标是什么?⼀是流量,⼆是⽤户量;流量⼤说明要存储处理的数据量⼤(⼤数据),⽤户量⼤说明需要处理⾼并发的⽤户请求(⾼并发);
⼤数据有个4V特征是什么:1)数据规模庞⼤(Volume): 数据量⼤关系数据库容不了;2)数据更新频繁(Velocity):⾼并发访问⼤关系数据库受不了;3)数据类型多样(Variety):类型多变关系数据库存不了;4)数据价值⼤密度低(Value):⾼价值数据密度低关系数据库算不了
我们上⾯⼀直只是在论述“传统关系型数据库在⼤数据和⾼并发场景下为什么不⾏?”,那么为什么“⾮关系型数据库HBase在⼤数据和⾼并发场景下为什么⾏?
NoSQL⾮关系型数据库在⼤数据时代横空出世,就是为了解决传统数据库⾯临的问题,就是为了存储处理的⼤数据,以及响应⾼并发的⽤户请求,适应数据类型多变得半结构⾮结构化存储!
HBase(Hadoop DataBase)就⼀种典型的NoSql⾮关系型数据库HBase诞⽣在⼤数据的新时代,是
专门⽤于保存⼤数据规模的数据库,传统关系数据库诞⽣在⼩数据的旧时代,是⽤于保存中⼩规模数据的数据库;
数据量⾮常⼤时,传统关系数据库处理复杂关联查询统计分析显得⼒不从⼼,⽐如执⾏group by聚合操作语句时,关系数据库是按⾏
存储的,需要读取⼀整⾏的所有列的数据,效率低,⽽HBase是按列存储的,执⾏聚合操作时只需读取单列数据,效率⾼;
传统关系数据库既不能适应超⼤规模数据量,也不能适应⾼并发的读写请求(了解⼀下阿⾥的去ioe),即使是⾮常擅长联机事务处理OLTP的Oracle数据库,遇到千万上亿好并发请求估计也会歇菜,⽽HBase等⾮关系型数据库天然为了互联⽹和⼤数据时代⽽产⽣的,其数据模型和架构设计使其不但能存储海量数据,还能胜任⾼并发随机读写请求;
HBase在⼤数据和⾼并发场景下为什么⾏?主要原因如下:
1)HBase保留了传统关系数据的部分优点(保留了⽼优点)
存储⽆冗余(值的存储⽆冗余,但是⾏键、列族和列是有冗余的,表设计⾏键不要太长),简单查询快,没有插⼊、删除、更新异常  2)HBase克服了传统关系数据的部分缺点(改正了⽼缺点)
⾼并发访问,⼤数据量存储,单列快速查询,单列数据超快速插⼊,⾯向单列的复杂查询统计效率⾼(例如执⾏group by聚合语句)
3)HBase独有的功能特性(增加了新优缺点)
HBase 是⾯向列的存储,列的本质上是从上到下紧密连续紧密存储的多个键值对,因此逻辑视图中的空⽩单元格值并不占⽤实际存储空间;只有主列是固定的,⼦列是动态插⼊的,能动态增加⼦列;每个存储单元,也就是每个列的值有多个时间版本;没有数据类型,所有数据都存储为字节数组,适应半结构⾮结构化类型多变的数据
4)然⽽,HBase也有⽐不上传统关系数据库的缺点(丢失了⽼优点,但是⽼优点在新的业务场景下也是可有可⽆)
不擅长OLTP联机事务处理,只能对单⾏的数据的操作加事务transaction;不擅长跨越多个主列的复杂关联查询,只能对单个主列进⾏过滤查询;⼤数据存储处理和⾼并发场景下的HBase分布式系统,并不需要严格的事务和复杂关联查询;HBase在CAP定理中选择了C(最终⼀致性)和P(分区容错性),放弃了A(可⽤性),因此事务不太重要(放弃ACID选择BASE)
四 HBase的数据存储⽅式
HBase和传统关系型数据库⾯向⾏的存储不同,⽽是采⽤⾯向列的存储⽅式!
HBase没有采⽤关系数据库的关系模式分解成多张⼩表,它很简单粗暴,就是⼀张⼤表搞定!
所以HBase没有学⽣表,没有课程表,没有成绩表,就是只有⼀张⾯向列存储的⼤表,HBase表是⼀张⼤表,把学⽣信息、课程和成绩放在⼀张表中,把原来的三张表当做主列(列族),把原来的表中列当做⼦列
什么叫逻辑上,什么是物理上?举个例⼦,我们机房的⽹络的主机之间在逻辑上是两两相连的⽹状连接,⽽在物理上所有主机都直接连接到中⼼交换机,物理上是星形连接。
HBase的数据表的逻辑视图(头脑中的存储⽅式),像⼀张(只有⼀张)含有⼦列的多维表;有三个主列,每个主列有多个并列显⽰的⼦列,如下表所⽰(HBASE的逻辑视图1):
⾏键
(学号)
学⽣信息(主列)成绩(主列)
姓名(⼦列)年龄
(⼦列)
语⽂
(⼦列)
数学
(⼦列)
英语
(⼦列)
S1张⼀2095.588.870.0
S2王⼆1878.588.6
S3李三1977.7
S4赵四19
上表不是传统的关系表,因为关系表不允许列包含有⼦列;上表中的空⽩单元格不是NULL,不占⽤实际物理存储空间,这和传统关系表也不相同;
上表的描述⽅式,各个⼦列是从左到右横向排列的,仍然像是“⾯向⾏”特征,仍然⽆法清晰的体现出HBase“⾯向列”的存储特征,我们把上⾯的HBase逻辑视图再变化⼀下,把各个⼦列由上到下纵向排列,更像是⼀列,更能体现HBase“⾯向列”的存储特征,从逻辑视图上看,学⽣课程成绩表如下表所⽰(HBASE的逻辑视图2),:
⾏键(学号)学⽣信息(主列名)成绩(主列名)
⼦列名单元格值⼦列名单元格值
S1姓名张⼀语⽂(语⽂-108)95.5
S1年龄20数学88.8
S1英语70.0
S2姓名王⼆语⽂78.5
S2年龄18数学88.6
S3姓名李三
S3年龄19
S3英语77.7
S4姓名赵四
S4年龄19
说明:
1)空⽩单元格不是NULL, 不占⽤实际的物理存储空间;关系表中才有NULL,占⼀个字节;
2)课程的课时量视为课程的其他次要属性,不⽤保存;或可以另表保存,或可作为⼦列名的后缀(语⽂-108)
HBase的数据表的物理视图(真实的存储形式)中可以看出,HBase是⾯向列存储的,主列中的⼦列只保存为从上到下纵向的⼀列,本质上是单列的存储格式是⼀个键值对(Key,Value);学⽣课程成绩表实际存储为两列,每列都是由(⾏键,主列名,⼦列名,单元格值)组成的连续存储的存储单元,其中前三个元素(⾏键,主列名,⼦列名) 构成键Key,最后⼀个元素单元格值构成值Value:
第⼀列:学⽣信息列
⾏键主列名⼦列名单元格
S1学⽣信
姓名张三
S1学⽣信
年龄20
S2学⽣信
姓名王⼆
S2学⽣信
年龄18
S3学⽣信
姓名李三
S3学⽣信
年龄19
S4学⽣信
姓名赵四
S4学⽣信
年龄19
第⼆列:成绩列
⾏键主列
名⼦列名单元格
S1成绩语⽂95.5

本文发布于:2024-09-20 19:50:23,感谢您对本站的认可!

本文链接:https://www.17tex.com/tex/4/96541.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议