laravel 数据库操作 Migrations, Laravel 的 Migrations 详解, laravel Schema Builder

 

Laravel 为我们提供了数据库结构操作功能 Migrations (数据库迁移),我们可以通过它创建一张数据库表,改变其中的结构,并在此基础上提供迁移回滚功能。

但是,我们公司在进行 Laravel 开发的时候没有用到这个功能,先谈谈我们是怎么做的:

  1. 通过数据库建模工具导出 SQL 到数据库
  2. 大家连接到服务器上的公共数据库进行开发
  3. 表结构因需求变化时用 Navicat for MySQL 直接更改

直到我发现 Django 和 Cake PHP、Ruby On Rails 也提供类似的功能,我觉得我需要重新认识 Migrations 了。

 

Install 安装

php artisan migrate:install

在配置好数据库以后,这条命令会在数据库中创建一个名叫 migrations 的表,包括字段:

  • id
  • migration
  • batch

这张表是 Migrations 的基础,用来标识数据库哪个迁移已经执行,哪个迁移还未执行。

 

Migration

数据库迁移文件是这套系统的重要组成部分,假如需要在现有的系统中加入博客文章功能,我们创建一个数据库迁移文件。

 

创建迁移

使用 make:migration Artisan命令来创建迁移

php artisan make:migration create_test_table

新创建的迁移会放在你的 database/migrations 目录。

你运行的时候肯定不会跟我这个文件名一样,因为我们很容易就发现这个文件加了时间前缀,也就是说我是在 2019-11-06 16:08:05 创建的这个文件。

 

--table--create 选项也可用于确定表的名称以及是否在迁移中创建新的数据表。这些选项用指定的迁移模板预先填充指定的数据表,这里就不做过多演示了

php artisan make:migration create_test_table --create=test

php artisan make:migration add_votes_to_test_table --table=test

 

迁移结构

除了我们创建的 test 表迁移文件,我们还发现了 laravel框架自带的 2014 年的 users 表和 password_resets 表,直接打开2014_10_12_000000_create_users_table.php 我们来参考下它的内容

一共有两个方法 updownup 方法是用于新增数据库的数据表、字段或者索引的,而 down 方法与 up 方法执行操作相反是用来删除表的。

在这两种方法中,你可以使用 Laravel 的结构生成器以表达式方式创建和修改表。 Schema 生成器上可用的所有方法 请查阅 官方文档

我们直接来读上图的代码,大致意思是

  • 要创建一个 user
  • 指定这个表的主键为 id
  • 指定 name 字段为字符串类型
  • 指定 email 字段为为字符串类型且限制唯一性
  • 指定 email_verified_at 字段为TIMESTAMP类型并且此字段允许写入 NULL
  • 指定 password 字段为字符串
  • rememberToken 这个字段不通用就不多讲具体看手册
  • 重点要说下 timestamps$table->timestamps() 的作用是给表增加 created_atupdated_at 它们的类型是 timestamps laravel 插入和编辑数据的时候会自动通过这两个字段记录操作的日期时间

 

这我们就发现了 laravel 的又一特点,整个项目对于各种命名的斟酌,很多时候我们即便不看文档甚至不看源代码注释只看方法名就能猜到作用了,她不只是一个框架还是我们编程的一个范本。 参考了 users 表我们回到 2019_11_06_160805_create_test_table.php 通过命令行生成文件的同时自动已经生成了下面这样的代码

很明显 laravel 默认表的主键字段名为 id 然后默认表有 created_atupdated_at 字段,增删改查不分家,增和改都默认有了个字段记录操作日期了,那删怎么能没有呢?没错 laravel 又为我们设计好了。

$table->softDeletes();

这个方法就是为表增加一个 deleted_atlaravel 会在删除数据的时候记录操作日期,具体到功能比如 回收站 的功能了,我们可能会删除某些数据,但是我们还希望能恢复删除的数据,当某条数据的 deleted_atnull 的时候表示正常,当有日期的时候就表示这条数据是在这个日期被删掉了。

 

运行迁移

现在回到 2019_11_06_160805_create_test_table.php 我们简单编辑下这个文件

我们在之前学习 artisan 的时候说过 artisan 主要2个作用 一个是创建迁移文件、一个是执行迁移任务,我们已经用 artisan 创建控制器和迁移了现在终于到了执行任务的时候了,我们上面的迁移文件定义了表的结构,执行迁移才会真正生成表

php artisan migrate

执行上面的命令的时候up遇到了这样的报错

SQLSTATE[HY000] [2054] The server requested authentication method unknown to the client 这是因为 up 本地 使用的是 MySQL 8 是由于 MySQL 8 默认使用了新的密码验证插件:caching_sha2_password,而之前的PHP版本中所带的 mysqlnd 无法支持这种验证。解决这个问题可以在MySQL 8中创建(或修改)使用caching_sha2_password 插件的账户,让其使用mysql_native_password 插件

ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'R9s33P8,,8&BH;2';

修改后我们重新执行 php artisan migrate 我们可以看到这样的提示

 

这意思就是我们的迁移已经完成了,那我们再执行一遍命令呢?我们会看到这样的的提示

Nothing to migrate.

嗯哼?也就是说已经成功的迁移并不会重复执行,这是在哪控制的呢?让我们 连接上 mysql show tables 一下

 

除了 laravel 自带的 users 表和 password_resets 表,除了我们创建的 test 表,我们还发现了个 migrations 表,我们看下这个表的内容

 

我们的3个迁移文件名都在里面记录着了,说明这个表里面存的是已经执行过的迁移的文件名,再查看下 test 表的结构.

完美跟我们迁移文件中写的是一样的表就这么轻松的创建了,但是再认真看会发现并没有 string 类型,肯定的喽,因为 mysql 压根就没 stringstring 就是 varchar 了,再但是再认真看还会发现除了 timestamp ,其他的字段都多了个 NOT NULL ,这个我们并没有在迁移中指定,这里就需要解释下了,这个 NOT NULLlaravel 为我们默认添加的,那如果确实有字段想让它允许为 NULL 怎么办呢?别担心 laravel 还有个 ->nullable() 我们这里学习了最常用的 int 、 varchar 、 text 那更多的类型呢?这时候就是 laravel 官方手册真正的作用了,laravel 官方手册更适合作为一本工具书,我们去像查字典一样去查工具书就可以了。

 

修改字段

创建表的方式我们已经学会了,除了创建表,我们还经常需要改变表结构,默认的 users 并没有 deleted_at 字段,我们如果想为 用户 也增加一个类似回收站的字段怎么办呢?

我们再来创建一个表迁移文件

php artisan make:migration add_deleted_at_to_users_table

在 add_deleted_at_to_users_table 文件中添加如下代码

 Schema::table('users', function (Blueprint $table) {
        $table->softDeletes();
    });

 

up 中就是我们迁移的内容,创建表的时候我们使用的是 Schema::create ,编辑表的时候我们使用的是 Schema::table,然后回调函数中的内容跟创建表的时候的格式是一样的,现在我们执行 php artisan migrate 迁移命令。

 

我们在来看看 users 表的结构 deleted_at 就这么加上了

 

回退 回滚迁移

down 方法中就是回退的内容了,创建表的时候 down 中是 drop 表,添加字段的时候 down 中的自然就是 drop 字段了

    Schema::table('users', function (Blueprint $table) {
        $table->dropColumn('deleted_at');
    });

我们一直在说回退说 laravel 的迁移功能可以让我们回退到某个状态,那到底是怎么回退呢?其实也很简单同样是运行命令,为了更深刻的理解 migrations 表的作用,在运行回退命令前我们先看下 migrations 表的内容

 

一共有5条记录 4条创建表的,1条添加字段的好我们来运行回退命令

php artisan migrate:rollback

 

然后再来看 migrations 表和 users 表

migrations 表的第4条添加字段的记录没有了,users 表的 deleted_at 字段也没了,再回退一次就把第一次运行迁移的时候的3张表就全删了,如果再运行迁移命令一切就又有了。

重命名一个存在的数据库表,请使用 rename 方法:

Schema::rename($from, $to);

 

删除一个存在的数据表,你可以使用 drop 或者 dropIfExists 方法:

Schema::drop('users');

Schema::dropIfExists('users');

 

修改字段类型

到这里创建表、删除表、添加字段、删除字段我们都学习了,最后再来学习下修改字段的,修改字段需要借助 dbal扩展包 ,先来执行下列命令安装扩展包

composer require doctrine/dbal

 

剩下的工作也很简单我这里举个栗子,比如 test表没有几条数据,用 int 类型太奢侈了,我们改成 tinyint 就足够了。 那么我们先创建一个迁移文件

php artisan make:migration change_category_id_in_test_table

 

然后在 up 中写上修改的内容即可

    Schema::table('test', function (Blueprint $table) {
        $table->tinyInteger('testId')->unsigned()->default(0)->comment('测试id')->change();
    });

 

但是这里要讲一个坑,如果直接运行上面这个迁移文件是会报错的因为 dbal 并不支持修改成 tinyInteger ,为了兼容更多类型的数据库需要使用替代方案使用 boolean 类型

 

down 里面就是相反的内容了

总结下就是 up 中写需要迁移的内容 down 中写回退的内容。

 

 

本文:laravel 数据库操作 Migrations, Laravel 的 Migrations 详解, laravel Schema Builder

 

 

 

Loading

Add a Comment

Your email address will not be published. Required fields are marked *

Time limit is exhausted. Please reload CAPTCHA.