代码改变世界

说说框架的数据库迁移功能

2017-03-07 10:20  轩脉刃  阅读(2088)  评论(2编辑  收藏  举报

laravel中有个数据库迁移功能,migration。基本用法就是在database/migrations/的文件夹下面创建迁移数据库的类,在这个类中实现两个方法:

up() 和 down()

up表示运行这个数据库迁移你要做些什么,down表示你回滚这次数据库迁移你要做些什么。

这样你就可以使用 php artisan migrate 就可以进行数据库迁移, php artisan migrate:rollback 就可以进行迁移回滚。

我一直在想,这个东西到底是鸡肋还是银弹呢?

这个功能发明出来的大致功能是为了让各个环境更好同步数据库。比如一个人A开发一个评论模块,需要做两个动作,那么A就创建一个migrate类,在里面用创造一个评论表,然后可能在文章表那里增加一个评论数的字段。当A把代码同步到主干分支的时候,B这个时候获取到了代码,那么就很简单实用php artisan migrate就能使用代码增加评论表和修改文章表字段。甚至于,在测试环境修改后到线上环境运行就可以同步表修改了。

但是总是觉得这里有几个问题:

首先是这个功能在项目上线之后很难使用。他至多只能同步各个人的开发环境,而不能同步线上环境。因为你想啊,我们平时线上修改是先改表还是先上代码?一般是先改表的。才上代码的。那么这样,我们就不大会选择在线上直接运行php artisan migrate的行为。一旦不会选择在上线后使用这个功能,就代表这个功能的使用场景大打折扣了。

其次是,这个行为安全性得不到保障。migrate的行为说到底是使用代码来控制数据库,和php里面执行alter table命令一样。一般来说,改表行为是一个非常危险的行为,越危险行为做的安全路子就是让链条变短。我们使用了php来执行一个改表命令,万一,数据量大的时候,改表非常慢,锁表,甚至于触发到php的命令耗时上限等行为?具体这个改表行为会有何后续行为?你如何回滚?这个时候,你就会懵了...用代码来管理数据库,我的结论就是一个,不纯正!!什么东西都有其专业的领域,用最专业的工具来做最专业的事情。

还有就是,migrate的rollback简直就是一个定时炸弹。我们一般往migrate的down里面写的是droptable的操作。一旦,万一,这种命令在线上被执行了。那么,就相当于是一个rm -rf的命令啊。把所有数据都给删除了。所以,安全起见,还是离这个rollback操作远一点好。

下面来说说开发阶段,在开发阶段我们会频繁修改数据库,那么这个时候,如果你想要维护一个很完善的migrate列表,你会很痛苦地发现你的migrate下的文件何其多啊。但最后,我们真的关注数据库是如何变化的么?其实,不关注。这些migrate的命令到最后确实没有多大用处。笔者的实践经历,到了一个项目准备上线的时候,我都恨不得把这些migrate的文件汇聚成一个migrate文件呢。。所以呢,在开发阶段,维护一个migrate列表,我感觉倒不如维护一个db.sql,外加laravel的初始化数据工具。每次有数据表改动,让大家source表,再初始化数据更好。

所以,综上所诉,结论是:框架的数据库迁移是个鸡肋。