敏捷软件开发我爱编程

疾风式全栈(12)-存储之数据库(草稿)

2018-05-15  本文已影响8人  码农田伟

这一次我们来关注企业软件的核心,数据库.
之前我们看了计算机中的存储主要分两类,以内存为代表的易失性存储,和以硬盘为代表的持久化存储.我们需要长期保存数据,就要把数据写入到硬盘上进行存储.对硬盘的管理一般是要进行分区,在分区中建立文件系统.而数据库也是在文件系统之上建立一套对于大量数据的管理规范.简单的说,就是一堆和数据相关的文件.

从根本上来说,我们自己建立一些文件来存储数据也是可以的.但是当有大量的数据需要管理时,一般都会采用通用的数据库技术.这几十年来数据库的主流是关系数据库.包括oracle,sql server, mysql,db2, postgre sql等产品.非关系型的数据库近年来也大量涌现,不仅是存储格式改变,也带来了内存数据库等新理念.

我们还是先从关系数据库开始.我们不用严格的数学概念,就照最简单的理解.关系就是行和列组成的表格.跟excel表格差不多.为了规范和高密度存储,对表格的形式作了一些约束,称为范式.总的原则就是相关的数据放在一起,有些数据有一些相关性,就放在不同的表里,通过编号彼此联系起来.当然这些都会有一些术语,行的唯一编号叫主键,相关数据的编号叫外键.

对数据库的操作也有一个标准规范叫sql.上面说的这些关系数据库都支持sql,好像也只支持sql.不管是用图形界面还是软件接口去连接数据库,发送的都是sql语句.甚至非关系数据库和大数据框架都在努力支持或模仿sql.

各个数据库所支持的sql会有一些区别,但是基本是一致的.和前端技术一样,也是有标准规范和各个浏览器的不同实现.常用的操作,使用标准的语法基本都能满足.

那么sql的具体形式是什么样呢?其实sql确实是非常先进的技术,跟我们前面说的函数式编程很像.只需要声明操作,不需要关心具体的执行过程. 但是sql多数采用的是空格分隔的单词作为语句,类似英语,没有全部使用点和小括号来调用.但是思路是一致的.sql里的where类似高阶函数filter,而select类似map.

比如,一张表叫c,有两列分别叫a和b,sql的查询可能是

select b from c where a = 1

在js里对应的说法就是,有一个数组c,里面存的对象都有a和b两个属性,查询

c.filter(it => it.a == 1).map(it => it.b)

是不是很相似,一样的思路,都是先查找,再变换.只是写法上有些区别,特别是sql的查询都是把select写在最前面,其实执行的时候,也是先执行where再select的.

从这里我们也可以看到,不管是硬盘上的数据库,还是内存中的集合,本质都是存储数据,处理的思路也是一样的.所以现在大家也在探讨一种统一的方式进行处理.既可以是把数据库放在内存中,比如alasql这样的库和各种内存数据库,也可以用操作集合的方式操作数据库,比如linq和datomic.而像spark这样的分布式大数据框架,致力于对各种来源各种形式的数据提供统一的操作体验.在spark的api里,filter和where是同义词,可以自由选择.

而reduce的操作,在数据库中直接提供了最常用的实现.比如聚合函数,sum avg min max count,可以理解为相应reduce的简写.

比如
select sum(a) from c
相当于
c.reduce((it,next) => it.a + next.a)

箭头函数提供了sum(a)最基本的逻辑,而reduce自动进行了整个集合的循环,得到了总和.

另外一个常用的操作group by分组, 也可以理解成是reduce(事实上,map和filter都可以理解成reduce). 具体用法大家可以自己搜索.

join

我认为关系数据库中最麻烦的地方就在于连接.上面说了,对于有一些关联,又不是特别密切的数据,会拆开放在两个表里,但在需要使用的场合也要把他们联合起来.联合的依据是外键.一般都是外键与主键相等的作为一条数据.这叫内连接.

select a.b,c.d from a inner join c on a.fk = c.id

也有外连接,把那些没有匹配到的数据也展示出来.大家可以需要时自己搜索.

增删改

添加数据
insert into c (a,b) values (1,2)

修改数据
update c set a = 1 where b = 2

删除
delete from c where b = 2
如果没有where条件,会自动循环操作所有行.所以一定要考虑清楚,多数时候是要加上where的.

而我们一直提倡函数式的风格,建议不要进行数据的修改和删除,可以用时间戳控制和增加新的数据代替.

在sql编写时,一定要理解,关系运算的结果还是关系.不管多复杂的运算,一层一层的分解,弄清每一层产生怎样的关系,有哪些行哪些列,总是可以得到正确结果的.至于对于性能的理解和优化,就需要真正的经验积累了.

虽然并不建议编写复杂的sql,但是鉴于目前数据库领域的现状,很多时候用sql还是最直接有效的解决方式.sql毕竟是声明式的,理清思路之后,几行语句可能相当于写几十行代码.sql的问题在我看来是缺少一些关键的特性.毕竟出现于几十年前,而且基本上没有什么大的改变和进步.

所以,尽管有一些场景会用到数据库提供的存储过程,提供了对sql的一些自己的扩展.但是并没有标准化,无法在不同数据库之间通用.

高效的存储是一门重要的学问.涉及到硬件和软件的方方面面,随着计算机和网络技术的深入应用,产生了大量的电子数据需要存储,也需要高效的进行分析处理.因此产生了SSD,SAS,SATA,NAS,SAN等很多新技术,大家可以搜索了解.

上一篇下一篇

猜你喜欢

热点阅读