Laravel里面对数据库设计了一套版本控制方式——数据库迁移,以下是个人学习入门的实践过程。
一、生成迁移文件
1. windows进入进入计算机dos系统,跳转到项目根目录,执行以下命令:
(1)第一次生成迁移文件时,需要先安装迁移(以后操作不需要执行这一步了)
php artisan migrate:install
(2)生成goods迁移文件
// 指定添加一个goods表的迁移文件
php artisan make:migration create_goods_table --create=goods
执行后如下:
2. 此时在/database/migrations/下生成了迁移文件:
3. 迁移文件内容结构
increments('id');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('goods');
}
}
说明:
(1)up方法是用于新增表、列及索引到数据库;
(2)down方法是up的反方法。
二、设计表结构
目标是建一个goods表,包含字段有:id(主键、自增)、goods_name(varchar类型,长度60)、goods_price(decimal类型,长度10,精确到小数点后2位)、num(库存数量,Int类型)、descr(商品描述,text类型),编辑up方法,代码如下:
public function up()
{
Schema::create('goods', function (Blueprint $table) {
$table->increments('id'); // 数据库主键自增ID
$table->string('goods_name',60); // 商品名称,varchar,长度限制为60
$table->decimal('goods_price',10,2); // 商品价格,decimal,长度10,精度2
$table->integer('num'); // 商品数量,int
$table->text('descr'); // 商品描述,text
// $table->timestamps(); // 自动增加一个create_at、update_at时间字段,此处不要
});
}
注意:
1. 迁移文件生成的数据表引擎默认为“MYISAM”,如果要生成“INNODB”引擎,需要在迁移文件总加入:
$table->engine = 'InnoDB';
2. 如果要指定表字符集为utf8,需要加入:
$table->charset = 'utf8';
数据类型对应的设置字段函数参考下表,拷贝自Laravel5.5手册:
命令 | 描述 |
---|---|
$table->bigIncrements('id'); |
自增ID,类型为bigint |
$table->bigInteger('votes'); |
等同于数据库中的 BIGINT 类型 |
$table->binary('data'); |
等同于数据库中的 BLOB 类型 |
$table->boolean('confirmed'); |
等同于数据库中的 BOOLEAN 类型 |
$table->char('name', 4); |
等同于数据库中的 CHAR 类型 |
$table->date('created_at'); |
等同于数据库中的 DATE 类型 |
$table->dateTime('created_at'); |
等同于数据库中的 DATETIME 类型 |
$table->dateTimeTz('created_at'); |
等同于数据库中的 DATETIME 类型(带时区) |
$table->decimal('amount', 5, 2); |
等同于数据库中的 DECIMAL 类型,带一个精度和范围 |
$table->double('column', 15, 8); |
等同于数据库中的 DOUBLE 类型,带精度, 总共15位数字,小数点后8位 |
$table->enum('choices', ['foo', 'bar']); |
等同于数据库中的 ENUM 类型 |
$table->float('amount'); |
等同于数据库中的 FLOAT 类型 |
$table->increments('id'); |
数据库主键自增ID |
$table->integer('votes'); |
等同于数据库中的 INTEGER 类型 |
$table->ipAddress('visitor'); |
等同于数据库中的 IP 地址 |
$table->json('options'); |
等同于数据库中的 JSON 类型 |
$table->jsonb('options'); |
等同于数据库中的 JSONB 类型 |
$table->longText('description'); |
等同于数据库中的 LONGTEXT 类型 |
$table->macAddress('device'); |
等同于数据库中的 MAC 地址 |
$table->mediumIncrements('id'); |
自增ID,类型为无符号的 mediumint |
$table->mediumInteger('numbers'); |
等同于数据库中的 MEDIUMINT 类型 |
$table->mediumText('description'); |
等同于数据库中的 MEDIUMTEXT 类型 |
$table->morphs('taggable'); |
添加一个 INTEGER 类型的 taggable_id 列和一个 STRING 类型的 taggable_type 列 |
$table->nullableTimestamps(); |
和 timestamps() 一样但允许 NULL 值 |
$table->rememberToken(); |
添加一个 remember_token 列: VARCHAR(100) NULL |
$table->smallIncrements('id'); |
自增ID,类型为无符号的 smallint |
$table->smallInteger('votes'); |
等同于数据库中的 SMALLINT 类型 |
$table->softDeletes(); |
新增一个 deleted_at 列用于软删除 |
$table->string('email'); |
等同于数据库中的 VARCHAR 列 |
$table->string('name', 100); |
等同于数据库中的 VARCHAR,带一个长度 |
$table->text('description'); |
等同于数据库中的 TEXT 类型 |
$table->time('sunrise'); |
等同于数据库中的 TIME 类型 |
$table->timeTz('sunrise'); |
等同于数据库中的 TIME 类型(带时区) |
$table->tinyInteger('numbers'); |
等同于数据库中的 TINYINT 类型 |
$table->timestamp('added_on'); |
等同于数据库中的 TIMESTAMP 类型 |
$table->timestampTz('added_on'); |
等同于数据库中的 TIMESTAMP 类型(带时区) |
$table->timestamps(); |
添加 created_at 和 updated_at 列 |
$table->timestampsTz(); |
添加 created_at 和 updated_at 列(带时区) |
$table->unsignedBigInteger('votes'); |
等同于数据库中无符号的 BIGINT 类型 |
$table->unsignedInteger('votes'); |
等同于数据库中无符号的 INT 类型 |
$table->unsignedMediumInteger('votes'); |
等同于数据库中无符号的 MEDIUMINT 类型 |
$table->unsignedSmallInteger('votes'); |
等同于数据库中无符号的 SMALLINT 类型 |
$table->unsignedTinyInteger('votes'); |
等同于数据库中无符号的 TINYINT 类型 |
$table->uuid('id'); |
等同于数据库的UUID |
每一个字段都可以进行注释和增加默认值,需要使用“列修改器”:
修改器 | 描述 |
---|---|
->after('column') |
将该列置于另一个列之后 (仅适用于MySQL) |
->comment('my comment') |
添加注释信息 |
->default($value) |
指定列的默认值 |
->first() |
将该列置为表中第一个列 (仅适用于MySQL) |
->nullable() |
允许该列的值为NULL |
->storedAs($expression) |
创建一个存储生成列(只支持MySQL) |
->unsigned() |
设置 integer 列为 UNSIGNED |
->virtualAs($expression) |
创建一个虚拟生成列(只支持MySQL) |
列修改器使用举例:
Schema::table('goods', function ($table) {
$table->string('goods_name',60)->nullable(); // 允许商品名称为空
$table->integer('num')->comment('商品数量'); //添加注释“商品数量”
});
三、运行迁移
运行迁移前,我啰嗦一句,先到.env把数据库连接配置好!!!遇到某些同学,真的是哭笑不得。
进入dos系统,跳转到项目根目录,执行以下代码:
php artisan migrate
执行后如下:
到数据库查看,此处是用的navicat for mysql:
四、回滚迁移(练习操作)
如果要回滚刚才的迁移操作,可以在dos系统下使用如下命令:
php artisan migrate:rollback
如果要回滚之前多步迁移操作的话,可以在执行如下命令:
php artisan migrate:rollback --step=5 //此处5代表回滚5步迁移操作
五、全部回滚
php artisan migrate:refresh
注意:全部回滚后,数据库所有已有数据全部清除。
六、修改数据列(字段及其属性,练习操作)
1. 在执行修改前,在dos下执行以下命令确保将 doctrine/dbal 依赖添加到 composer.json 中,Doctrine DBAL 库用于判断列的当前状态并创建对列进行指定调整所需的 SQL 语句:
composer require doctrine/dbal
2. 创建修改迁移文件
php artisan make:migration alter_goods_table --table=goods
3. 更新列(字段)的属性,使用 change() 方法:
Schema::table('goods', function ($table) {
$table->string('goods_name', 40)->change(); // 将商品名称修改为长度限制为40
});
Schema::table('goods', function ($table) {
$table->string('goods_name', 40)->nullable()->change(); // 将商品名称修改为允许NULL
});
注意以下数据类型是不能修改:char、double、enum、mediumInteger、timestamp、tinyInteger、ipAddress、json、jsonb、macAddress、mediumIncrements、morphs、nullableMorphs、nullableTimestamps、softDeletes、timeTz、timestampTz、timestamps、timestampsTz、unsignedMediumInteger、unsignedTinyInteger、uuid。
4. 重命令数据列,使用 renameColumn() 方法:
Schema::table('goods', function ($table) {
$table->renameColumn('num', 'number'); //修改num字段为number
});
注意:暂时不支持 enum
类型 的列的修改和重命名
5. 添加数据列
Schema::table('goods', function ($table) {
$table->string('look_num'); // 添加一个look_num字段
});
6. 删除数据列 ,使用 dropColumn() 方法:
Schema::table('goods', function ($table) {
$table->dropColumn('goods_name'); //删除一个数据列
$table->dropColumn(['goods_name', 'goods_price', 'num']); //删除多个数据列
});
7. 创建索引
创建索引可以有两种方式,一种方式是在创建数据列的同时就创建索引,另一种方法是先创建数据列,然后再创建索引,如下:
Schema::create('goods', function (Blueprint $table) {
// 1. 创建数据列的同时创建唯一索引
$table->string('goods_name',60)->unique();
// 2.先创建数据列,再创建索引
$table->string('goods_name',60);
$table->unique('goods_name');
});
可用索引类型如下:
命令 | 描述 |
---|---|
$table->primary('id'); |
添加主键索引 |
$table->primary(['first', 'last']); |
添加混合索引 |
$table->unique('email'); |
添加唯一索引 |
$table->unique('state', 'my_index_name'); |
指定自定义索引名称 |
$table->unique(['first', 'last']); |
添加组合唯一索引 |
$table->index('state'); |
添加普通索引 |
8. 执行迁移文件完成修改
php artisan migrate
结语: 数据库迁移文件可以做数据库结构版本控制,但是一旦有了数据,仍然还是只进行数据库结构版本控制,对于实际应用来说,也不能算是真正的版本控制,数据库里面的数据能做到版本控制,那对于利用git进行版本控制的公司和开发团队来讲,才真正算是对数据库也进行了版本控制,数据填充参考:laravel5.5数据库之数据填充(实践)
参考文档:Laravel5.5数据库迁移