通俗易懂理解数据库概念
在Quora上曾经有个问题: Computer Programming: How would you explain a database in three sentences to your 8-year-old nephew被搬到了知乎上。
来自知乎的答案
中药铺说
电脑里面存了好多好多数据。数据就像各种各样中药,在没有数据库之前,中药就是一包包这样杂乱无章地堆放着(unorganized data),找也不好找(inaccessible)。如果你是药店的掌柜,你怎么来管理这些药呢?
聪明的古人就想了办法:把所有的中药都放到柜子里面(data table),柜子里面都是大小一样的小盒子(organized data model),每个盒子(a row / record)都在外面标签上写上药名,按笔划排序帮助快速查找(index / primary key),比如你要找三七,那么一定是三笔的头几个——现在找东西是不是方便多了?
如果要找一味温热的药,按名字找可就不大灵了,除了打开抽屉一个一个舔过去,还有什么办法快速找到吗?对啦,就是在抽屉上涂上颜色,比如温热的用粉红色,凉性的用蓝色(secondary key),你还可以用不同大小的抽屉代表药的其他属性(another secondary key)
如果有的药卖空了没有货怎么办?把整个抽屉拿走(delete a row)!如果新增加一种药怎么办?找一个空抽屉放上新药贴个标签呗(add a row)!如果整柜子中药都过期了怎么最快处理?把柜子搬走(drop a table),换个新柜子(create a table),再往里面添加新鲜中药。
如果有一种药量特别大,放在另外一个抽屉大一点儿的柜子里怎么办呢(splitted table)?在这个抽屉里放一张纸条,写上“此药在后堂第三个柜子第二个抽屉”(Foreign key / linked table)。
图书馆说
- 图书馆就是一个数据库:图书馆的每本书都有一个编号,编号表示了书的类别和顺序号,同类别的书放在一个书架上,然后书按顺序摆在它所属的书架上,这么做的好处是方便查找书。
- 图书馆管理员就是访问接口:你想找一本书时,他先找到这本书的类别和顺序号,然后他就到指定的书架上按顺序找到那本书,交给你。
- 你和其他人提出的借书请求就是外部程序,一本书可以借给你也可以借给别人,但是图书馆管理员知道书的状态并负责把书放回原位。
一篇通俗解释文
什么是数据库呢?
每个人家里都会有冰箱,冰箱是用来干什么的?冰箱是用来存放食物的地方。同样的,数据库是存放数据的地方。正是因为有了数据库后,我们可以直接查找数据。例如你每天使用余额宝查看自己的账户收益,就是从数据库读取数据后给你的。
你可能会问了:我的数据就存放在自己电脑的excel表里就可以了,为什么还要搞个数据库呢?这是因为数据库比excel有更多的优势。数据库可以存放大量的数据,允许很多人同时使用里面的数据。
举个例子你就明白了,excel好比是一个移动硬盘,你使用了这个移动硬盘其他人就用不了了。数据库好比是网盘,很多人可以同时访问里面里的数据。而且网盘比移动硬盘能放更多的数据。
数据库是如何存放数据的?
数据库有很多种类,这里我们重点学习使用最广泛的关系数据库。关系数据库是由多个表组成的。如果你用过Excel,就会知道Excel是一张一张的二维表。每个表都是由行和列组成的。同样的,关系数据库里存放的也是一张一张的表,只不过各个表之间是有联系的。所以,简单来说:关系数据库=多张表+各表之间的关系
对应的,学会关系数据库我们只要掌握两点就可以:
- 多张表里面,每一张表的结构
- 各表之间的关系
我们接下来分别来看看这两个知识点。
表的结构
表的结构是指要了解关系数据库中每张表长什么样。每个表由一个名字标识。表包含带有列名的列,和记录数据的行。我们举个具体的例子就一目了然了。下面图片里的表名是:学生表,记录了每个学生的信息。
表中每一列都有一个名字来标识出该列,这个表里有4列,列名分别是学号,姓名,出生日期,性别。从列名上你也可以知道这一列对应记录的是什么数据。
表的每一行里记录着数据。这里的一行表示该名学生的信息,比如第2行是学号0002学生的信息,他的姓名是猴子,出生日期是1990-12-21,性别是女。
各表之间的关系
关系数据库是由多张表组成的,图片里是存放在学校数据库里的4张表。你能发现下面这4张表之间有什么关系吗?
什么是关系呢?你是你爸爸的儿子,你是你的儿子的爸爸,这就是生活中的关系。其实,数据之间也是有关系的。关系数据库里各个表之间如何建立起关系呢?我们来看图中“学生表”,“成绩表”这两个表之前的关系。
这两张表通过“学号”关联起来,为了更清楚的看到这两个表的关系,PPT里我用相同颜色代表同一个学生的信息。例如我想知道学生表里学号“0001” 的成绩是多少?那么我就可以在成绩表里去查找“学号”值是0001的行,最后在成绩表里发现有3行数据的学号都是“0001” ,对应的就找到了该学生的三门课程的成绩。
通过这个例子你应该对表之间的关系有了大概的了解。关系就是数据能够对应的匹配,在关系数据库中正式名称叫联结,对应的英文名称叫做join。联结是关系型数据库中的核心概念,务必记住这个概念,后面会在多表查询中具体学到。
什么是数据库管理系统?
前面讲的都是关系数据库原理方面的基本理论。理论有了,当然的就的有对应的软件实现才能用起来,不然再强大的理论都是一堆无用的东东。这就好比,建筑师如果只有设计草图是无法盖起楼房的,得有具体的建筑人员才能盖起楼房。
所以,上面讲的关系数据库原理就是“设计草图”,那么对应的“建筑人员”是谁呢?实现数据库原理的“建筑人员”就是数据库管理系统,用来管理数据库的计算机软件。
关系数据库管理系统有很多种,比如MySQL、Oracle、SQL Server等都是实现上面理论的关系数据库。
什么是SQL?
建筑施工人员通过使铲子,拉土机等工具来盖房子。那么,我们通过什么工具来操作数据库里的数据呢?这个工具就是SQL。
SQL是为操作数据库而开发的一种语言,它可以对数据库里的表进行操作,比如修改数据,查找数据。把数据库比如一碗米饭,里面放的米是数据。现在我们要吃碗里的米饭,怎么取出碗里的米饭呢?这时候我们拿一双筷子,用筷子操作碗里的米饭。这里的筷子就是SQL,用来操作数据库里的数据。
一篇来自老外的数据库简明教程
什么是数据库?
数据库是文件柜。数据库不一定要那么复杂。如果你去掉所有花哨的语义,你最终会得到一些简单而熟悉的东西。
字典、日历和文件柜特别有用,因为它们以排序的方式来表示信息,使得我们可以使用一种叫做二进制搜索(二分搜索)的过程来快速有效地检索信息。数据库也不例外,它们也是分类存放信息的容器。
什么是排序信息?
最简单的排序方式是按字母顺序排序(也就是按词法排序),这就是字典中单词的排序方式。但是,我们经常发现自己要按多个属性进行排序。例如,一个联系人列表通常是按姓,然后是名来排序的。这就是所谓的复合排序。
我们到处都在做这种复式排序,尤其是日期,是按年、月、日复合排序的。请注意,这种排序并不完全是按字母顺序排列的。数字排序与字母排序不同,因为字母排序是逐个字母进行比较的。例如,如果我们按字母顺序对数字进行排序,那么10将排在2之前,因为第一个数字 “1 “在 “2 “之前。用一种简单的方式来表示数字,可以按字母顺序排序,就是在数字的开头加上0。这对于有已知最大值的数,如一年中的月份,效果很好。而事实上,我们可以用ISO 8601日期格式来表示日期,可以按字母顺序排序。用这种方式表示日期是很方便的,因为它不需要领域知识来理解如何排序。
一般来说,词法编码很重要,因为它们允许数据库以正确的顺序存储任意信息,而不需要额外的关于被排序信息类型的知识。
数据库案例:警察部门
你可以用思考系统文件柜的方式来思考数据库。为了进一步探讨这个类比,让我们想象一下,你负责管理一个警察部门,你要跟踪你所在地区的每一个警察的各种信息: 姓名、警徽号、地址和辖区等细节。作为这些信息的管理员,你有责任确保所有信息都是最新的,并且易于访问。为了使事情简单化,你首先要把所有警察的信息放在一个文件柜里,按警徽号码分类。这样就可以很容易地根据警徽号码检索到任何官员的信息,例如,当一个警察晋升或搬到新的地址时。
读/写平衡
有一天,局长要求你提供第60分局中,每个警官的地址。所有这些信息都在一个档案柜里,按警徽号码分类,这是个很痛苦的要求,因为你必须扫描每一个档案,检查每个警官是否在第60分局。也许这只是一个一次性的要求,所以你可以劳而无功,但警察局长说,每个月他都要给辖区内逮捕人数最多的每个警员邮寄一张奖金支票。如果你每个月都要这样做,也许值得让这项工作快一点。
为了解决这个问题,你建立了另一个档案柜,在那里你按辖区对所有人员进行分类。为了简单起见,你把 “警徽#”柜里的所有信息都复印到 “辖区”柜里。现在,当局长要求你获取一个辖区内每一位警员的地址时,你可以使用这个新的文件柜来快速检索信息。这个新的档案柜让你更容易获得信息,但是每次你要更新信息的时候都会产生一个新的问题。如果一个新的官员加入一个辖区,或者从一个辖区搬到另一个辖区,你现在必须确保信息的正确性,并在两个不同的地方更新。
更糟糕的是,我们最终会浪费时间来更新不必要的信息。例如,也许我们不需要出生日期,也不需要我们制作的新分局档案柜里的官员照片,但我们还是会把它复制过来,这样信息就不会不同步。
另一方面,也许我们决定在辖区柜中存储的唯一信息就是警徽号。这样一来,更改和管理官员的信息所需的工作就少了很多 —— 我们只需要在原来的警徽号柜中进行更新。这也意味着,辖区柜的体积要小得多,因为我们没有那么多信息挤在里面。
但是有一个问题。现在如果你需要得到一个辖区内每个官员的地址,你就得先用你做的新档案柜来得到辖区内的官员名单,然后你就得用原来的警徽#档案柜来得到每个官员的地址。这样做还是比没有辖区柜要快,但没有之前扫描每个警察档案的方法快。
从根本上说,没有 “最好 “的方法 —— 这都是你在读取与写入信息时要做多少工作之间的权衡。
在这两种方法之间有一个中间地带,我们将地址和徽章号码都记录在我们创建的新辖区文件柜中。这就达到了一个很好的平衡,我们不必在辖区柜中更新我们不关心的信息。
然而,这确实带来了一些后勤方面的开销 —— 现在我们有了一份更新徽章号柜时必须遵循的程序清单。
查询规划
现在我们假设,每当有人对某位警官提出投诉时,我们都想在该警官的档案中记录下这一投诉。通常情况下,当有人提出投诉时,他们没有该官员的警徽号码,但他们有该官员的名字。
为了更方便地按姓名查找警员,我们建立了另一个档案柜,将所有警员按姓名分类。现在我们的档案系统是这样的。
三个文件柜。徽章号、辖区和姓名还有保持所有东西更新的程序表。现在,让我们想象一下,这个警察局从1万名警察发展到1千万名警察。你收到一个投诉,投诉人是121分局的史密斯警官,棕色头发,蓝眼睛。你正在考虑用两种不同的方式来查找这位警官 —— 你可以扫描121分局的每一位警官寻找史密斯警官,也可以扫描121分局的每一位姓史密斯的警官寻找这位警官。你做了一个假设,同名同姓的人可能比同一分局的人少,所以你决定先按名字查找警官。
在数据库中,这个过程被称为查询规划:你有一个问题(一些你想检索的信息)和一个现有的档案柜设置,你需要确定收集所有这些信息的最快方法。所以你查看了你创建姓名的数据库,结果发现121分局里居然有上百名叫史密斯的警官。再次,你决定值得想出一个更快的方法来做这件事。你想要的是类似于你创建的辖区柜的东西,并按警官姓名进行二级排序。但辖区柜不包括官员姓名,所以你必须在其中创建一个新的文件柜来包括他们。您决定将官员姓名复制到现有的辖区柜中,然后按姓名排序以节省空间,这样可能更有效率。
正如我们前面所讨论的那样,这是一个复合排序,因为我们要对多个属性进行排序:辖区,然后是姓名。
文件柜的流程
为了回应公众对警员投诉飙升的强烈抗议,警察局已经聘请了当地的审计公司对每个辖区进行审计。现在,每当增加或修改一名警员的信息时,我们都需要通知分配到该警员所在辖区的审计小组,告知他们这些变化。
我们开始把这些程序写在和以前一样的清单上,但我们开始意识到,这将是一个非常长的程序清单。
每当我们对警徽号码柜进行更改时,我们现在都需要扫描这个庞大的程序列表,这需要花费太多时间。所以我们要做的很简单,我们把所有的审计师地址移到一个新的档案柜里,然后在我们的程序列表中增加一个步骤,告诉职员在哪里查找审计师的地址。
一个名为 “辖区审计员 “的档案柜,里面有每个审计员的地址,并有一个单一的程序来查找相应的地址。这就容易管理多了,但你可以想象,随着组织复杂性的发展,程序清单会不断增加;人力资源部门每当地址发生变化或有人投诉时,都想知道;财务部每当某位官员晋升时,都需要知道,这样他们就可以适当调整工资单 —— 程序清单还在继续。
通知人力资源和财务部门的程序。不难看出,这个程序列表本身可以变成一个按属性分类的文件柜。这样一来,当我们只是更新一个地址的时候,就不需要把每一个属性的过程都读一遍。因此,每当我们对警徽号码柜进行更改时,我们就会在这个程序柜中查找每一个更改的属性,看看我们需要做什么。
一个程序档案柜,展示了随时向人力资源部门邮寄最新资料和地址变化的程序。
到目前为止,我们只为警徽号码柜维护了一个程序列表,但其他机构的文件柜也需要同样的程序列表。而事实上,这样做真的很有用,因为它可以让我们将程序列表划分为更有效的程序排序方式。
例如,假设有一个正在进行的调查,FBI想知道第50分局中姓科伦坡的官员是否有任何变化。
我们可以为警徽号码柜创建一个程序,每当一个名字或一个辖区发生变化时,就会检查,然后检查是否是第50辖区和姓科伦坡。
辖区属性发生变化时触发的存储过程,该过程说:”如果名字是科伦坡,辖区是50,那么邮寄给FBI”。
但是,每次更换辖区时,检查这个程序会浪费很多精力。例如,假设史密斯警官从60号分局调到61号分局 —— 当你查找程序时,你会看到这个程序,需要检查50号分局的科伦坡。
有一个更好的解决方案 —— 我们可以为辖区柜创建一个程序。回想一下,辖区柜是一个复合排序,先按辖区,再按姓名。因此,我们可以通过对程序使用复合排序来使我们的程序柜变得非常精细。
现在,当我把史密斯警官从60号辖区移到61号辖区时(下图中的第一个柜子),我会看到一个程序告诉我更新辖区柜子,更新辖区柜子后,我会查找辖区柜子的程序,看看是否有61号辖区和名字史密斯的程序。注意,我们能够跳过检查50号选区和名字Colombo的程序。这真是太有效率了!
将史密斯警官的辖区更新为61,更新辖区内的柜子,在辖区程序柜中没有看到相关程序。
程序列表,在更新柜子的时候,能够有效地查询到需要做哪些程序,这对于信息系统的自动化来说,是一个非常强大的抽象。甚至于,这种抽象超越了现有数据库系统的能力。
审计日志
当经过一段时间后,有这么多的人和这么多的信息变化,它变得重要的是要跟踪所有的细节,围绕着谁改变了什么,什么时候。例如,也许你打开琼斯警官的档案,上面写着他是一名侦探。而也许你以为他只是一个副手,所以你可能会倾向于问一些问题,比如 “他什么时候晋升的?”、”谁晋升的?”、”今年有多少人晋升?”。这些问题在我们目前的设置下是不可能回答的,你可以想象,如果你管理的是一家银行,你会经常问这类关于账户之间资金流动的问题。
在银行里,每一笔账户之间的转账都会被记录下来,并附上某种收据,永远保存下来。而在我们的警察局,改变任何信息都可能用某种表格来记录。例如,当警察局长想把琼斯警官提升为警探时,他就会填写一份 “提升表”,然后把它交给行政办公室的档案员。
档案员可能会把这张表格放在一个档案柜里,用来存放晋升表格,按级别和日期分类。然后我们查到一套这次晋升的程序,其中有一条就是简单地更新警徽号码柜里的警员等级。
这个过程肯定比简单地更新警徽号码柜中的官员等级需要更多的工作,但它允许我们审计变化,并回答一系列更广泛的问题,即事情如何随着时间的推移而变化。例如,我们可以从 “晋升表格 “柜中查看一段时间内所有级别的晋升情况。如果我们想确定一个官员何时晋升,我们可以创建一个单独的柜子,将这些晋升表格按徽章号,然后按日期分类。
当为了审计目的而保存历史变化列表时,通常必须建立机制以确保信息不被篡改。例如,假设一个不良行为人想秘密添加一个记录,显示琼斯警官在12月11日被降职,而在12月12日被提升(也许是为了制造一个欺诈性的丑闻,他们可以在新闻中写出来,在选举前诋毁警察局长)。
签名是这里的第一道防线。如果签名很难复制,那么就很难制造出一份欺诈性的降级表(注:我们在降级时也使用同样的晋升表)。另外,我们可以做的是在晋升表格中备注之前的级别。也就是说,如果不良行为人想要创建这个欺诈性的降级表格,他们还需要欺诈性地更新12月12日的晋升表格,以参考之前的降级等级。
在物理世界中,防范这种欺诈是相当困难的,不可避免地需要对系统的某种信任。但在现代世界,通过加密和单向哈希,我们可以为记录创建无法篡改的签名。这正是区块链防止比特币欺诈性交易的工作方式。
超越文件柜
到此为止,我们已经几乎涵盖了关于文件柜的所有有趣的东西,以及我们如何利用它们来管理大量的信息与操作程序。但对于任何一个现实的行政管理部门来说,还需要几个重要的系统。
- 第一个是管理权限。谁有权限提拔一个警员?谁有权限读取某个警员的投诉?谁又有权限更改某位警员的地址?有很多方法来管理这个问题,大多数组织使用某种权限等级制度来保持简单。我将把回答这些问题作为读者的练习,但如果你有技术上的倾向,我会推荐你阅读 Google如何用他们的桑给巴尔数据库解决这个问题
- 系统中另一个需要仔细管理的部分,是如何将信息邮寄给不同部门。邮寄东西需要时间,这在一个复杂的组织中会引起各种问题。例如,也许一个官员在12月12日获得晋升,而当财务部门在12月13日发送工资支票时,他们仍然没有收到邮件中的晋升信息,因此他们根据他们之前的级别发送了一份工资支票。如果涉及到协调问题,事情就更有难度了。例如,也许人力资源部门认定某位官员有太多的投诉,必须降级。人力资源部门将降级的邮件发给行政部门以及财务部门。同时,主管认为该官员应该得到晋升,于是将晋升邮件寄给行政部门和财务部门。
现在会发生什么呢?不管结果如何,最重要的是行政部门、人力资源部门和财务部门最终的结果是一致的(也就是所谓的最终一致性)。例如,如果财务部门决定处理晋升,而行政部门决定处理降级,那么他们的记录就会有所不同,该官员将获得比行政部门预期更大的薪水。
这些都是很难解决的问题,我会让读者去思考如何管理这类协调问题。但如果你有技术上的能力,我建议你阅读一下【 Automerge如何处理点对点软件的这些问题】
认识数据库:简明数据库史
在工业时代,煤炭和钢铁的使用量是一个国家发达程度的指标。而到了信息时代,数据量将是新的发达程度指标,几乎所有行业竞争本质上都是数据的竞争。支撑数据增长的背后,是一代又一代不断演化的数据库引擎。
整个数据库大致经历了四个发展阶段。
第一阶段:非关系型数据库
在现代意义的数据库出来之前(20 世纪 60 年代),文件系统(File system)可以说是最早的数据库,程序员们读取文本文件,并通过代码提取文件中的关键数据,在脑海中尝试构造数据与数据之间的关系。当年能流行起来的编程语言,往往都有很强的文件和数据处理能力(比如 Perl 语言)。随着数据量的增长,数据维度的多元化,以及对于数据可信和数据安全的要求不断提升,简单的将数据存储在 txt 文本中,成为极其具有挑战的事情。
随后,人们开始提出数据库管理系统(Database Management System, DBMS)的概念。数据库的演进抽象来看是人们对 数据结构 和 数据关系 这两个维度展开的思考和优化。
层次模型 和网络模型(1960)
第一阶段的数据库模型(Database model) 是层次模型(Hierarchical Databases)。
层次模型是最早的数据库模型。随着早期 IBM 大型机逐渐推广开来。这个模型相对于文本文件管理数据,是个巨大的提升,但也有很多问题。
层次模型的问题:
- 尽管能比较好的表达 一对一 ( one to one) 结构,但在 多对多(many to many) 结构上难以表达。如:图中能较好的表达一个系有多个老师,但很难表达一个老师可能属于多个系。
- 层次结构不够灵活。如:添加一个新的数据库关系有可能对整个数据库结构带来巨大变化,以至于在真正的开发中带来巨大的工作量
- 查询数据需要脑海中随时有最新的结构图,且需要遍历树状结构做推导
而后在层次模型的基础之上,人们提出了优化方案,即:网络模型(Network Model)。
网络模型是关系型数据库出来之前最为流行的数据库模型。很好的解决了数据的多对多的问题。但依然存在以下问题:
- 难以从代码层面实现和维护
- 查询数据需要脑海中随时有最新的结构图
第二阶段:关系型数据库
模型初期(1970)
关系模型( Relational Model) 是相对网络模型的巨大飞跃。在网络模型中,不同类型的数据总是会依赖另一类数据,如图 1 中,Teachers 从属于 Departments,这是层次模型和网络模型在真实设计和开发中痛苦的根源(因为你总是要在脑海中记录当前的网络结构,想象一下一个拥有几千张表的复杂系统)
关系模型一大创新就是拆掉了表和表之间的链接,将关系只存储在当前表中的某一个字段中(fields),从而实现不同的表之间的相对独立。如下表:当你只看 Table2 的时候,你就知道 Product_code 会指向一个 产品的具体细节,Table2 和 Table1 在保持相对独立的同时,又自然而然的连接了起来。
Table2 中的 Product_code 列指向了 Table1 中对应的数据,从而建立 Table2 和 Table1 的关系
1970年,当 E.F.Codd 开发出这个模型时,人们认为是难以实现的,正如上面的例子一般,当你检索 Table2 时,遇到 Product_code 列,就需要再去 Table1 遍历一遍。受限于当时的硬件条件,这种检索方法总是会让机器难以负载。但很快,大家质疑的问题,在摩尔定律加持下,已经不再是问题。大家如今所听说的 IBM DB2, Ingres, Sybase, Oracle, Informix, MySQL 就是诞生在这个时代。
至此数据库领域诞生了一个大的分类:联机事务处理 OLTP(on-line transaction processing),代指一类专门用于日常事务的数据库,如银行交易用的增删改查数据库。后面还会提到另一类数据库,专门用于从大量数据中发现决策的辅助数据库 On-Line Analytical Processing – OLAP(联机分析处理)数据库。
数据仓库(1980s)
随着关系型数据库的发展,不同业务场景数据化,人们开始有了汇集不同业务场景数据,并尝试进行数据分析并辅助业务决策的想法(Decision Support System)。在此需求之上,诞生了数据仓库( Data warehouse)的概念。
如下图:一个企业往往把不同的业务场景数据存在不同的数据库中,在没有成熟的数据仓库产品之前,数据分析师往往需要自己做大量的前期准备工作来汇集自己所需的数据。而数据仓库本质上就是解决数据分析和挖掘的业务场景。
解释:ETL 是 Extract(提取),Transform(转换),Load(加载)的缩写。因为数据在不同的数据库或者系统中,可能存在格式不统一,单位不统一等等情况。需要做一次数据的预处理。
数据仓库是一个面向主题的、集成的、非易失的、随时间变化的用来支持管理人员决策数据集合。
OLAP(联机分析处理)
1980 年代有了数据仓库的概念和实现后,人们尝试在此基础上做数据分析。但分析的过程出现一些新的问题。最明显的是效率问题。因为之前的关系型数据库并不是为数据分析而打造。数据分析师想要的是一个支持多维的数据视图和多维数据操作的引擎。
如下面的数据魔方一般,相比于上面提到的关系型数据库中的二维数据展示和二维数据操作而言。OLAP 数据库对多个维度的数据可以快速的组建和操作。
数据魔方:将多个维度的数据组织和展示
1993 年,关系型数据库创始人Edgar F. Codd提出联机分析处理(OLAP)的概念。本质上是多维数据库和多维分析能力的概念。目标是满足决策支持或多维环境特定的查询和报表需求。
第三阶段:NoSQL
时间继续推进,互联网时代到来以后,数据量的暴增给关系型数据库也带来的新的挑战。最为明显的挑战有以下两点:
挑战一:数据列的扩展成本巨高
关系型数据库因为提前定义了 Table 的字段(Fields),当数据库已经拥有数以亿计条的数据之后,业务场景需要一列新的数据,你惊讶的发现,在关系型数据库的规则限制下,你必须要同时操作这数以亿计的数据爱完成新的一列的添加(不然数据库会有报错出现),对生产环境的服务器性能挑战极大。
可以想象一下 Facebook,Twitter, Weibo 这样的社交网站,每天字段都在不断的变化,来添加各种新的功能。
比如需要添加 status 列,你必须要在某一时刻同时为数以亿计的行,添加 Active 或者 In-Active 内容,否则数据库会无法满足合规约束
挑战二:数据库性能的挑战
业务规模不断上升之后,关系型数据库的性能问题开始浮出水面,虽然数据库供应商都提出了各种解决方案,但底层关系绑定式的设计依然是性能天花板的根本原因。开发人员开始尝试分库、分表、加缓存等极限操作来挤出性能。
在此挑战之上,人们提出了新的数据库模型 – NoSQL。
针对扩展数据列的问题,NoSQL 提出了新的数据存储格式,去掉了关系模型的关系性。数据之间无关联,这样就换回了架构上的扩展性。
新的数据结构,将相关性数据都放在一起
NoSQL 更底层的创新源自于天生为集群可扩展场景所打造。
而在 NoSQL 理论基础之上,根据企业应用场景又拓展出了四大类型的数据库:
- 文档型数据库(Document-Oriented):如大名鼎鼎的 MongoDB、CouchDB。文档泛指一种数据的存储结构,如 XML、JSON、JSONB 等。
- 键值数据库(Key-Value Database) :大家所听说的 Redis、Memcached、Riak 都是键值对数据库
- 列式存储数据库(Column-Family):如 Cassandra、HBase
- 图数据库(Graph-oriented):如 Neo4j、OrientDB 等。聚焦在数据间关系链的数据组织方式。
随着企业数据的不断变大,对数据处理能力也提出了新的要求。日常所听到的大数据(Big Data)一词,代表一个庞大的技术体系结构。包括了数据的采集,整理,计算,存储,分析等环节。数据库只是其中一环。如下图,饿了么2017 年大数据架构,文中所提到的数据库,基本上只代表了图中存储环节。大家日常所听到的 Hadoop、Kafka、Hive、Spark、Materialize等都是大数据引擎,千万不要搞混了。
数据库只是大数据概念中的一部分。
第四阶段:云原生数据库
随着云时代的到来,基于云环境所打造的云原生数据库不断地开始占了数据库市场份额。
云原生数据库和托管/自建数据库最大的区别就是:云原生数据库是面向独立资源的云化,其CPU、内存、存储等均可实现独立的弹性,利用大型云厂商的海量资源池,最大化其资源利用率,降低成本,同时支持独立扩展特定资源,满足多种用户不断变化的业务需求,实现完全的Serverless; 而托管数据库还是局限于传统的服务器架构,各项资源等比率的限制在一个范围内,其弹性范围,资源利用率都受到较大的限制,无法充分利用云的红利。
基于云原生数据库技术,未来创业团队无需花费巨大精力来应对海量数据来袭,只需聚焦在业务即可。
云原生数据库的代表如:阿里云的 PolarDB、腾讯云的 CynosDB、华为云的 TaurusDB、亚马逊云的 Aurora。
最后,以阿里 CIO 学院的一个数据库分布图结束这篇文章,图示中的数据库产品和分布图很好的代表了当前数据库产业的格局。
小结
数据库看起来相当复杂,但每个数据库的基本工作原理就像一个文件柜和存储程序的系统。当我们需要在许多地方保持信息的更新,并且我们希望对数据库的所有变化进行审计跟踪时,事情就开始变得更加复杂。但这种复杂性对于解决我们所解决的问题是必要的。
当谈到未来的计算机知识时,我知道并不是每个人都会成为程序员,但了解如何构建文件柜系统的细节,将使普通人能够从计算机中获得最大的好处。
参考链接: