前面我们设置好了数据库,可以开始对数据库操作了但是前提是我们得有表啊,说到数据库做开发的肯定能知道其中的辛酸苦与泪。
团队合作的时候为了避免代码冲突,以及方便记录修改历史和回退我们有版本控制比如说 git
svn
但是数据库怎么搞呢?
在远古时代在中小公司中在没有一套比较好用的管理表变动的方案的时候相信童鞋们多少都经历过改数据库的痛苦,每次自己在本地增加了表或者字段都要记录下来告知其他同事,其他同事也得在自己本地修改,还要胆战心惊的改生产跟测试环境的数据库这种经历贼痛苦,但是自从接触了
laravel
,一口气搞定所有的环境的表结构。
那laravel
怎样来帮助我们的呢?
这就要说 laravel
内置了表迁移的功能,迁移就像是数据库的版本控制器,让你的团队更容易修改和共享程序的数据库结构。迁移通常配合 Laravel
的结构生成器,能更容易的生成应用程序的数据库结构。如果你曾经让一个团队成员在他本地的数据库结构中手动的添加了字段,那么你将面对解决数据库迁移的问题。
Laravel
的 Schema
门面 提供数据库无关的支持,用于在所有 Laravel
支持的数据库系统中创建和操作表
创建迁移
使用 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
我们来参考下它的内容
一共有两个方法 up
和 down
,up
方法是用于新增数据库的数据表、字段或者索引的,而 down
方法与 up
方法执行操作相反是用来删除表的。
在这两种方法中,你可以使用 Laravel
的结构生成器以表达式方式创建和修改表。 Schema
生成器上可用的所有方法 请查阅 官方文档
我们直接来读上图的代码,大致意思是
- 要创建一个
user
表 - 指定这个表的主键为
id
- 指定
name
字段为字符串类型 - 指定
email
字段为为字符串类型且限制唯一性 - 指定
email_verified_at
字段为TIMESTAMP类型并且此字段允许写入NULL
值 - 指定
password
字段为字符串 rememberToken
这个字段不通用就不多讲具体看手册- 重点要说下
timestamps
,$table->timestamps()
的作用是给表增加created_at
和updated_at
它们的类型是timestamps
laravel
插入和编辑数据的时候会自动通过这两个字段记录操作的日期时间
这我们就发现了 laravel 的又一特点,整个项目对于各种命名的斟酌,很多时候我们即便不看文档甚至不看源代码注释只看方法名就能猜到作用了,她不只是一个框架还是我们编程的一个范本。
参考了 users
表我们回到 2019_11_06_160805_create_test_table.php
通过命令行生成文件的同时自动已经生成了下面这样的代码
很明显 laravel
默认表的主键字段名为 id
然后默认表有 created_at
和 updated_at
字段,增删改查不分家,增和改都默认有了个字段记录操作日期了,那删怎么能没有呢?没错 laravel
又为我们设计好了。
$table->softDeletes();
这个方法就是为表增加一个 deleted_at
,laravel
会在删除数据的时候记录操作日期,具体到功能比如 回收站
的功能了,我们可能会删除某些数据,但是我们还希望能恢复删除的数据,当某条数据的 deleted_at
为 null
的时候表示正常,当有日期的时候就表示这条数据是在这个日期被删掉了。
运行迁移
现在回到 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
我们可以看到这样的提示
这意思就是我们的迁移已经完成了,那我们再执行一遍命令呢?我们会看到这样的的提示
代码语言:javascript复制Nothing to migrate.
嗯哼?也就是说已经成功的迁移并不会重复执行,这是在哪控制的呢?让我们 连接上 mysql
show tables
一下
除了 laravel
自带的 users
表和 password_resets
表,除了我们创建的 test
表,我们还发现了个 migrations
表,我们看下这个表的内容
我们的3个迁移文件名都在里面记录着了,说明这个表里面存的是已经执行过的迁移的文件名,再查看下 test
表的结构.
完美跟我们迁移文件中写的是一样的表就这么轻松的创建了,但是再认真看会发现并没有 string 类型
,肯定的喽,因为 mysql
压根就没 string
,string
就是 varchar
了,再但是再认真看还会发现除了 timestamp
,其他的字段都多了个 NOT NULL
,这个我们并没有在迁移中指定,这里就需要解释下了,这个 NOT NULL
是 laravel
为我们默认添加的,那如果确实有字段想让它允许为 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
就这么加上了
回退 回滚迁移
代码语言:javascript复制
down
方法中就是回退的内容了,创建表的时候down
中是drop
表,添加字段的时候down
中的自然就是drop
字段了
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扩展包
,先来执行下列命令安装扩展包
composer require doctrine/dbal
剩下的工作也很简单我这里举个栗子,比如 test
表没有几条数据,用 int
类型太奢侈了,我们改成 tinyint
就足够了。
那么我们先创建一个迁移文件
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
中写回退的内容。