Laravel中用原生sql语句代替Blueprint建表

编辑于 2017-12-22 16:52:21

Laravel中数据库迁移 (migration)的设计是很好的,方便部署、管理数据库变更。
实际使用中发现,额外封装的用于建表的Blueprint类(\Illuminate\Database\Schema\Blueprint)用起来并不方便,相当于在标准的sql语句之外再学一种sql语言了。
有些情况使用Blueprint还要再安装composer包,有些仅具体数据库支持的特性并不支持,比如MySQL的表注释。
尤其是要修改某个字段的定义时,更不方便。


粘贴图片



图1 Laravel 中基于Blueprint的建表代码


考虑到一直用MySQL,几乎不会换成别的数据库,后来干脆用原生的sql语句建表了。
实现方法是在迁移文件的up/down方法中,用DB::getPd()获取PHP内置的PDO对象,然后调用其exec方法执行拼接好的建表sql语句即可。
这样建表、改表就是写sql了,不用查怎么用Blueprint怎么写了,也能跟原来一样,使用Laravel的数据库迁移功能。

另外,实际运行时发现了非常奇怪的一点。在模型、控制器中使用DB,需要在文件上面加
use DB;

不加会报错。
而在迁移文件中,却不能加,加了反而不能用,报错如下:
[ErrorException]
The use statement with non-compound name 'DB' has no effect


示例代码:
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        // 前面不需要使用use DB;
        $prefix = DB::getTablePrefix();
        $table = $prefix.'text';
        pf('create table: '.$table);

        $sql = "
CREATE TABLE `$table` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `type` char(10) NOT NULL DEFAULT '' COMMENT '内容类型,answer 回答,question 问题,note 笔记',
  `cid` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '内容ID',
  `created_at` timestamp NULL DEFAULT NULL COMMENT '内容创建时间',
  PRIMARY KEY (`id`),
  KEY `type` (`type`),
  KEY `cid` (`cid`),
  KEY `created_at` (`created_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='时间线分表:201712';
        ";

        DB::getPdo()->exec($sql);
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        $prefix  =DB::getTablePrefix();
        $table = $prefix.'text';
        $sql = "DROP TABLE $table";
        DB::getPdo()->exec($sql);
    }
}



编辑笔记



* 草稿箱未上线,请注意手动保存!!!