前言
数据库迁移其实很好理解,传统开发中我们建表的时候是借助一些工具,比如phpMyAdmin、Navicat等。这样做有一个问题,就是在我们开发工程中或是版本迭代过程中,我们往往会对之前的表结构进行调整、更改等,修改1次或两次还好,如果修改的次数多了,容易忘记。数据库迁移是用文件操作数据表结构,每一次修改都会有记录,这样我们就可以看到每次修改的记录。另一方面直接操作线上的表结构还有一定的风险,如果操作不当或是失误很容易带来灾难性的的后果。
数据迁移的文件目录
如图所示是laravel数据库迁移的目录:
Migrations里面定义的是数据迁移的数据表
Seeds 数据内容
factories:测试数据
使用流程:创建表、添加字段、添加测试数据。具体如下:
创建自定义数据库
创建命令
php artisan make:migration create_test_table
创建成功之后如下图所示:
我们可以给test表加一个字符串类型和无符号整形的字段如下:
public function up(){
Schema::create('test', function (Blueprint $table) {
$table->increments('id');
$table->timestamps();
$table->string('email');
$table->unsignedMediumInteger('phone');
});
}
其它字段以及操作其它数据库操作命令相机laravel官方文档:
https://learnku.com/index.php/docs/laravel/5.7/migrations/2291
执行迁移
使用命令
php artisan migrate
执行迁移,执行迁移的时候出现了一个错误:
Illuminate\Database\QueryException : SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 1000 bytes (SQL: alter table `la_users` add unique `la_users_email
_unique`(`email`))
问题原因:
MySql支持的utf8编码最大字符长度为3字节,如果遇到4字节的宽字符就会出现插入异常。三个字节UTF-8最大能编码的Unicode字符是0xffff,即Unicode中的基本多文种平面(BMP)。因而包括Emoji表情(Emoji是一种特殊的Unicode编码)在内的非基本多文种平面的Unicode字符都无法使用MySql的utf8字符集存储。
这也应该就是Laravel 5.4以后改用4字节长度的utf8mb4字符编码的原因之一。不过要注意的是,只有MySql 5.5.3版本以后才开始支持utf8mb4字符编码(查看版本:selection version();)。如果MySql版本过低,需要进行版本更新。
解决方法:
1.升级mysql版本
2.在AppServiceProvider中调用Schema::defaultStringLength方法配置migrate生成的默认字符串长度:
use Illuminate\Support\Facades\Schema;
class AppServiceProvider extends ServiceProvider
{
public function boot()
{
Schema::defaultStringLength(191);
}
}
数据填充
更多工厂模型见如下laravel框架文档
https://laravelacademy.org/post/9694.html
创建填充器:
php artisan make:seeder TestTableSeeder
在填充起的run方法里面使用模型工厂批量填充数据:
public function run()
{
// 方法一
factory(App\Test::class,3)->create()->each(function($test) {
$test->posts()->save(factory(App\Test::class)->make());
});
// 方法二
// factory(App\Test::class,3)->create();
}
然后执行数据填充命令:
php artisan db:seed --class=TestTableSeeder
注意:laravel 默认 会给数据表加 s,创建表的时候是test表,但是执行数据填充文件的时候报错,说是找不到tests表。两种解决方法:
1.遵循官方的原则,把表名加s。
2.在模型里面修改表名。