laravel 学习之路 数据库操作 Migrations

2019-12-18 17:41:08 浏览数 (1)

前面我们设置好了数据库,可以开始对数据库操作了但是前提是我们得有表啊,说到数据库做开发的肯定能知道其中的辛酸苦与泪。

团队合作的时候为了避免代码冲突,以及方便记录修改历史和回退我们有版本控制比如说 git svn

但是数据库怎么搞呢?

在远古时代在中小公司中在没有一套比较好用的管理表变动的方案的时候相信童鞋们多少都经历过改数据库的痛苦,每次自己在本地增加了表或者字段都要记录下来告知其他同事,其他同事也得在自己本地修改,还要胆战心惊的改生产跟测试环境的数据库这种经历贼痛苦,但是自从接触了 laravel,一口气搞定所有的环境的表结构。

laravel怎样来帮助我们的呢?

这就要说 laravel 内置了表迁移的功能,迁移就像是数据库的版本控制器,让你的团队更容易修改和共享程序的数据库结构。迁移通常配合 Laravel 的结构生成器,能更容易的生成应用程序的数据库结构。如果你曾经让一个团队成员在他本地的数据库结构中手动的添加了字段,那么你将面对解决数据库迁移的问题。

LaravelSchema 门面 提供数据库无关的支持,用于在所有 Laravel 支持的数据库系统中创建和操作表

创建迁移

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

代码语言:javascript复制
php artisan make:migration create_test_table

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

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

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

代码语言:javascript复制
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 又为我们设计好了。

代码语言:javascript复制
$table->softDeletes();

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

运行迁移

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

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

代码语言:javascript复制
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 插件

代码语言:javascript复制
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'R9s33P8,,8&BH;2';

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

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

代码语言:javascript复制
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 字段,我们如果想为 用户 也增加一个类似回收站的字段怎么办呢?

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

代码语言:javascript复制
php artisan make:migration add_deleted_at_to_users_table

在 add_deleted_at_to_users_table 文件中添加如下代码

代码语言:javascript复制
    Schema::table('users', function (Blueprint $table) {
        $table->softDeletes();
    });

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

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

回退 回滚迁移

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

代码语言:javascript复制
    Schema::table('users', function (Blueprint $table) {
        $table->dropColumn('deleted_at');
    });

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

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

代码语言:javascript复制
php artisan migrate:rollback

然后再来看 migrations 表和 users 表

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

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

代码语言:javascript复制
Schema::rename($from, $to);

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

代码语言:javascript复制
Schema::drop('users');

Schema::dropIfExists('users');
修改字段类型

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

代码语言:javascript复制
composer require doctrine/dbal

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

代码语言:javascript复制
php artisan make:migration change_category_id_in_test_table

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

代码语言:javascript复制
    Schema::table('test', function (Blueprint $table) {
        $table->tinyInteger('testId')->unsigned()->default(0)->comment('测试id')->change();
    });

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

down 里面就是相反的内容了

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

0 人点赞