如果在開發(fā)過程中剧腻,你曾經(jīng)有過手動在數(shù)據(jù)庫結構中添加字段的經(jīng)歷,導致不同的開發(fā)者的數(shù)據(jù)庫不同步涂屁,那么數(shù)據(jù)庫遷移可以幫你解決這個問題书在。
數(shù)據(jù)庫遷移就像是數(shù)據(jù)庫的版本控制,可以讓團隊輕松修改并共享應用程序的數(shù)據(jù)庫結構拆又。遷移通常會搭配上 Laravel 的數(shù)據(jù)庫結構構造器來更方便地構建數(shù)據(jù)庫結構儒旬。
數(shù)據(jù)庫遷移
項目的創(chuàng)建,環(huán)境配置等請參考laravel官方文檔帖族,此處不再贅述栈源。
創(chuàng)建遷移
進入到項目根目錄,執(zhí)行以下命令:
php artisan make:migration create_users_table --create=users
--table 選項可用來指定數(shù)據(jù)表的名稱
--create 選項指定該遷移被執(zhí)行時會創(chuàng)建的新數(shù)據(jù)表
--path 選項會為遷移指定一個自定義路徑
新的遷移文件將會被放置在 database/migrations
目錄下竖般。每個遷移文件的名稱都包含了一個時間戳以 時間戳_XXX的形式命名甚垦。
打開剛才生成的遷移文件可以看到文件內(nèi)容如下:
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateUsersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('users');
}
}
可以看到laravel已經(jīng)幫我們自動創(chuàng)建了
up
和down
方法:
up 方法可為數(shù)據(jù)庫添加新的數(shù)據(jù)表、字段或索引涣雕。
down 方法則是用于執(zhí)行回滾操作艰亮。
Schema::create
接受兩個參數(shù)。第一個是要創(chuàng)建表的表名挣郭;第二個是一個閉包(匿名函數(shù))迄埃,獲取用于定義新表的 Blueprint 對象。
這里的Schema::dropIfExists('users');
會判斷如果存在users
表會直接刪除它兑障。
- ps: laravel會自動記錄執(zhí)行過的遷移侄非,每個遷移只會執(zhí)行一次蕉汪。
接下來我們修改up
方法,laravel的鏈式寫法很輕松就能知道要做的操作
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');//主鍵自增ID
$table->string('name',20)->comment('用戶名');//string默認是數(shù)據(jù)庫的Verchar類型,長度20,comment備注
$table->string('email',255)->unique()->comment('郵箱');//unique添加唯一索引
$table->string('password')->comment("密碼");
$table->rememberToken();
$table->timestamps();//添加created_at和updated_at字段
});
}
執(zhí)行遷移
接下來執(zhí)行php artisan migrate
命令來運行所有未運行過的遷移
生成的數(shù)據(jù)表默認字符集為
utf8mb4
逞怨,排序規(guī)則utf8mb4_unicode_ci
回滾操作
覺得表創(chuàng)建有問題是可以有后悔藥吃的者疤,運行以下命令即可
php artisan migrate:rollback
php artisan migrate:rollback
命令是對上一次執(zhí)行的「批量」遷移回滾,其中可能包括多個遷移文件骇钦,在 rollback 命令后加上step
參數(shù)宛渐,可以限制回滾遷移的個數(shù)。
比如想回滾最后的 3個遷移:
php artisan migrate:rollback --step=3
回滾應用程序中的所有遷移:
php artisan migrate:reset
檢查數(shù)據(jù)表或字段是否存在
重新創(chuàng)建users表后眯搭,突然想添加軟刪除功能,這時候可以創(chuàng)建針對users表的遷移:
php artisan make:migration change_users_table --table=users
編輯up方法:
public function up()
{
Schema::table('users', function (Blueprint $table) {
if (!Schema::hasColumn('users','deleted_at')) {
$table->softDeletes();//添加軟刪除功能,會在users表中添加deleted_at字段
}
});
}
hasColumn
方法用來檢查字段是否存业岁,第一個參數(shù)是要檢查的表鳞仙,第二個參數(shù)是要檢查的字段。
要檢查users表是否存在可以使用hasTable
方法笔时。
執(zhí)行php artisan migrate
命令棍好,從下圖的執(zhí)行結果可以看deleted_at
字段已經(jīng)添加進users表了
數(shù)據(jù)填充
我們可以使用laravel框架的seeder類來執(zhí)行數(shù)據(jù)填充允耿,所有由框架生成的 seeders 都將被放置在 database/seeds
目錄下借笙。
php artisan make:seeder UsersTableSeeder
讓我們修改UserTableSeeder
下的run
方法:
<?php
use Illuminate\Database\Seeder;
use Illuminate\Database\Eloquent\Model;
class DatabaseSeeder extends Seeder
{
/**
* 運行數(shù)據(jù)庫填充
*
* @return void
*/
public function run()
{
DB::table('users')->insert([
'name' => str_random(10),
'email' => str_random(10).'@gmail.com',
'password' => bcrypt('secret'),
]);
}
}
然后修改DatabaseSeeder
下的run
方法,在 DatabaseSeeder 類中,可以使用 call 方法執(zhí)行額外的填充類较锡,使用 call 方法允許你將數(shù)據(jù)庫填充分解成多個文件业稼。
<?php
use Illuminate\Database\Seeder;
use Illuminate\Database\Eloquent\Model;
class DatabaseSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
$this->call(UserTableSeeder::class);
}
}
執(zhí)行php artisan db:seed
后,數(shù)據(jù)庫中就生成了一條新的用戶數(shù)據(jù)蚂蕴。
模型工廠
有了users表低散,我們還可以創(chuàng)建一張user_card表,一位用戶可以擁有多張會員卡骡楼。這時候要每張表單獨填充數(shù)據(jù)就比較麻煩了,這時候就可以使用 模型工廠 來輕松地生成大量數(shù)據(jù)庫記錄熔号。
首先做好準備工作,為我們的user_card創(chuàng)建遷移:
php artisan make:migration create_user_card_table --create=user_card
修改up方法并執(zhí)行遷移:
public function up()
{
Schema::create('user_card', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id');
$table->string('number',20)->comment('卡號');
$table->timestamps();
$table->softDeletes();
});
}
為User模型添加一對多的關系:
public function userCards()
{
return $this->hasMany('App\UserCard');
}
接下來打開 database/factories/UserFactory.php
文件鸟整,該文件包含了一個工廠定義:
<?php
use Faker\Generator as Faker;
/*
|--------------------------------------------------------------------------
| Model Factories
|--------------------------------------------------------------------------
|
| This directory should contain each of the model factory definitions for
| your application. Factories provide a convenient way to generate new
| model instances for testing / seeding your application's database.
|
*/
$factory->define(App\User::class, function (Faker $faker) {
static $password;
return [
'name' => $faker->name,
'email' => $faker->unique()->safeEmail,
'password' => $password ?: $password = bcrypt('secret'),
'remember_token' => str_random(10),
];
});
Faker實例提供了很多可用的隨機數(shù)據(jù)引镊,比如我們要填充人名,使用$faker->name即可篮条,它最后會生成如Prof. Shanna Jacobs這樣的高度擬真數(shù)據(jù)弟头,不需要自己再去瞎編什么test001之類的數(shù)據(jù)。unique保證了郵箱的唯一兑燥,safeEmail是防止生成真正的郵箱亮瓷,
用了呢個保留的那啥。降瞳。嘱支。忘了蚓胸。。除师。
想要深入了解Faker的可以參考:https://github.com/fzaninotto/Faker
再為user_card定義一個工廠沛膳,在database/factories
路徑下創(chuàng)建UserCardFactory.php
文件,因為user_card中的用戶ID是關聯(lián)的users表的汛聚,所以這里只需要為卡號生成一個隨機數(shù)就可以了锹安。
<?php
use Faker\Generator as Faker;
$factory->define(App\UserCard::class, function (Faker $faker) {
return [
'number' => random_int(10000,9999999),
];
});
然后我們修改UserTableSeeder
下的run
方法:
public function run()
{
//模型工廠
factory(App\User::class, 50)
->create()
->each(function ($u) {
$u->userCards()->save(factory(App\UserCard::class)->make());
});
}
-
factory
接受兩個參數(shù):一個是Eloquent模型,另一個是批量插入的數(shù)據(jù)量。
上面run方法中的語句表示創(chuàng)建 50 個用戶,為每個用戶創(chuàng)建關聯(lián)倚舀,并將其存到數(shù)據(jù)庫中叹哭。
最后我們只需要執(zhí)行命令生成數(shù)據(jù):
php artisan db:seed
也可以指定執(zhí)行一個特定的 seeder 類:
php artisan db:seed --class=UsersTableSeeder
- PS:因為faker隨機生成的名字長度會超過20,導致插入數(shù)據(jù)庫時報錯痕貌,解決方法:創(chuàng)建一個針對users表的遷移风罩,將name的長度改為100就好了。
Schema::table('users', function (Blueprint $table) {
if (Schema::hasColumn('users','name')) {
$table->string('name', 20)->comment('用戶名')->change();
}
});
現(xiàn)在我們可以查看數(shù)據(jù)庫舵稠,會發(fā)現(xiàn)新增了50條關聯(lián)數(shù)據(jù)超升。
2017-12-27