Laravel數(shù)據(jù)庫遷移與數(shù)據(jù)填充


如果在開發(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的形式命名甚垦。

遷移文件 create_users_table

打開剛才生成的遷移文件可以看到文件內(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)建了updown方法:
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命令來運行所有未運行過的遷移

執(zhí)行遷移

生成的數(shù)據(jù)表默認字符集為utf8mb4逞怨,排序規(guī)則utf8mb4_unicode_ci
Users數(shù)據(jù)表

回滾操作

覺得表創(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
創(chuàng)建遷移

編輯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表了

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ù)超升。

users表
user_card表

2017-12-27

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市哺徊,隨后出現(xiàn)的幾起案子室琢,更是在濱河造成了極大的恐慌,老刑警劉巖落追,帶你破解...
    沈念sama閱讀 222,590評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件盈滴,死亡現(xiàn)場離奇詭異,居然都是意外死亡淋硝,警方通過查閱死者的電腦和手機雹熬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來谣膳,“玉大人竿报,你說我怎么就攤上這事〖萄瑁” “怎么了烈菌?”我有些...
    開封第一講書人閱讀 169,301評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長花履。 經(jīng)常有香客問我芽世,道長,這世上最難降的妖魔是什么诡壁? 我笑而不...
    開封第一講書人閱讀 60,078評論 1 300
  • 正文 為了忘掉前任济瓢,我火速辦了婚禮,結果婚禮上妹卿,老公的妹妹穿的比我還像新娘旺矾。我一直安慰自己蔑鹦,他們只是感情好,可當我...
    茶點故事閱讀 69,082評論 6 398
  • 文/花漫 我一把揭開白布箕宙。 她就那樣靜靜地躺著嚎朽,像睡著了一般。 火紅的嫁衣襯著肌膚如雪柬帕。 梳的紋絲不亂的頭發(fā)上哟忍,一...
    開封第一講書人閱讀 52,682評論 1 312
  • 那天,我揣著相機與錄音陷寝,去河邊找鬼锅很。 笑死,一個胖子當著我的面吹牛凤跑,可吹牛的內(nèi)容都是我干的粗蔚。 我是一名探鬼主播,決...
    沈念sama閱讀 41,155評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼饶火,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了致扯?” 一聲冷哼從身側(cè)響起肤寝,我...
    開封第一講書人閱讀 40,098評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎抖僵,沒想到半個月后鲤看,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,638評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡耍群,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,701評論 3 342
  • 正文 我和宋清朗相戀三年义桂,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蹈垢。...
    茶點故事閱讀 40,852評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡慷吊,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出曹抬,到底是詐尸還是另有隱情溉瓶,我是刑警寧澤,帶...
    沈念sama閱讀 36,520評論 5 351
  • 正文 年R本政府宣布谤民,位于F島的核電站堰酿,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏张足。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,181評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望灭衷。 院中可真熱鬧,春花似錦岩馍、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至帽蝶,卻和暖如春赦肋,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背励稳。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評論 1 274
  • 我被黑心中介騙來泰國打工佃乘, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人驹尼。 一個月前我還...
    沈念sama閱讀 49,279評論 3 379
  • 正文 我出身青樓趣避,卻偏偏與公主長得像,于是被迫代替她去往敵國和親新翎。 傳聞我的和親對象是個殘疾皇子程帕,可洞房花燭夜當晚...
    茶點故事閱讀 45,851評論 2 361

推薦閱讀更多精彩內(nèi)容