其他
小李的数据库之旅(下)
接上篇《小李的数据库之旅(上)》, 上回说到小李用一个中间逻辑层解决了普通人也能查询数据的问题, 很快新的挑战就来了。
小李刚学会了C语言, 觉得这种语言更加贴近硬件,效率更高,更适合写这些“系统级”的软件, 于是决定保留之前的设计, 然后用C重写。
当然不仅仅是重构, 还包含了重要的功能增强:网络访问, 从单机软件变成了客户端-服务器结构(C/S)的软件。
好景不长, 小李很快就发现网络版软件的复杂度要远远超过单机版, 这不马上就有老师爆出了一个超级大问题。
王老师对一个学生的地址进行了更新, 张老师对另外一个学生的地址也做了更改, 后来发现王老师的修改不见了, 这是怎么回事?
小李看了代码,很快就发现在单机版的时候, 原来的操作都是基于整个文件的: 读入文件内容, 做修改, 然后写入文件, 很明显, 王老师的修改在前,张老师的修改在后, 王老师的被覆盖了。
真是个严重的问题, 恰逢周末, 小李赶紧通宵达旦的修改, 升级系统,把基于文件的操作改变成基于行的操作: 每个人的修改只影响这一行。
小李觉得这样应该没问题了, 可是很快就发生了两个人对同一行的修改:
电子系的账户有1000元, 刘老师支取了300, 金老师支取了200 , 最后账户的余额竟然是800元 ! 实际应该是500元啊。
这是个极为严重的错误, 系统被迫停止了几天专门来修复这个问题。
一个解决的办法就是给这一行加锁, 在刘老师读取了1000元, 扣除300元,并且把700 写回到数据库之前, 不允许金老师操作,这样就不会乱掉了。
可是一次非常偶然的系统故障有暴露了一个从没有想过的大问题:
当时电子系的账户有1000元, 数学系有2000元, 电子系要给数学系转账200元, 系统先扣除了电子系的账户钱的钱,变成了800 , 正要往数学系上面增加余额的时候, 系统出了故障,崩溃了。
重启以后,就发现电子系的余额是对的, 可是数学系还是2000元, 那200元丢了 !
很明显, 转账这个操作,必须得是原子的: 要么全部发生, 要么根本不发生。
小李决定把类似这样的操作叫做“事务”, 但是怎么实现呢?
小李苦思冥想, 终于放了一个大招: 记录日志 !
在做真正的操作之前,先把要做的事记录下来形成日志(Log),这个日志中包括修改的数据项标识, 数据项的旧值(修改前的值)和新值(修改后的值), 然后再进行真正的数据库修改。
刚开始的时候事务处于活动状态, 只有所有的操作都正确无误的写入了磁盘,才会进入提交状态, 否则就要回滚修改。
(码农翻身注: 除了原子性之外,事务还有持久性,隔离性,一致性,这里就不展开了)
小李心想确实是这样, 一个没有权限控制的系统是非常危险的, 尤其是随意删除, 那还了得?!
赶紧加上一个权限系统, 小李想了想, 先定义三大类权限:1. 对数据操作的, 例如SELECT, UPDATE, INSERT等2. 对结构操作的, 例如创建表,修改表,等3. 做管理的, 例如备份数据, 创建用户等
然后就可以把这些权限授予某个用户了, 很多时候,还需要把表附加上, 像这样:GRANT SELECT on 财务表 to 系主任GRANT CREATE_TABLE to 张老师
(码农翻身注: 这里模仿了mysql)
解决了如此多棘手的问题以后, 小李的信息系统已经非常复杂了,实际上,这个系统的中间层完全可以剥离出来,形成一个完整的软件了, 小李把它称为:数据库
你看到的只是冰山一角, 更多精彩文章,尽在“码农翻身” 微信公众号, 回复消息"m"或"目录" 查看更多文章
有心得想和大家分享? 欢迎投稿 ! 我的联系方式:微信:liuxinlehan QQ: 3340792577
掘金是一个高质量的技术社区,从 Swift 到 React Native,性能优化到开源类库,让你不错过互联网开发的每一个技术干货。长按图片二维码识别或者各大应用市场搜索「掘金」,技术干货尽在掌握中。