第二章 數據庫遷移 —— 以版本控制的方式維護數據表

一.簡介

所謂遷移就像是 數據庫的版本控制

這種機制允許團隊簡單輕鬆的編輯並共享應用的數據庫表結構。如果你曾經頻繁告知團隊成員需要手動添加列到本地數據庫表結構以維護本地開發環境,那麼這正是數據庫遷移所致力於解決的問題。

遷移通常和 Laravel 的 schema 構建器結合,從而可以很容易地構建應用的數據庫表結構。

二.生成遷移文件

新的遷移位於 database/migrations 目錄下,每個遷移文件名都包含時間戳從而允許 Laravel 判斷其順序

  • 創建Model類時,附帶‘-m’參數同時創建遷移文件。
php artisan make:model UserModel -m
  • 直接生成遷移文件
php artisan make:migration create_users_table
  • 指定表名稱
php artisan make:migration add_votes_to_users_table --table=users
  • 創建一個新的數據表
php artisan make:migration create_users_table --create=users

三.遷移結構

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateFlightsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('flights', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->string('airline');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('flights');
    }
}

up 方法用於新增表,列或者索引到數據庫;down反之

四.運行遷移

php artisan migrate
php artisan migrate --force //強制

五.回滾遷移

  • 按照遷移順序回滾
php artisan migrate:rollback          //回滾最後一次遷移
php artisan migrate:rollback --step=5 //回滾最後五條遷移
php artisan migrate:reset             //回滾所有的應用遷移
  • 在單個命令中回滾 & 遷移
php artisan migrate:refresh  //命令將會先回滾所有數據庫遷移,然後運行 migrate 命令。這個命令可以有效的重建整個數據庫

php artisan migrate:refresh --seed  // 重建數據庫並填充數據...

php artisan migrate:refresh --step=5 //回滾或重建最後五條遷移
  • 刪除所有表 & 遷移
php artisan migrate:fresh  // 命令將會先從數據庫中刪除所有表然後執行 migrate 命令

php artisan migrate:fresh --seed // 填充

六.填充假數據到數據庫

詳解三.遷移結構

  • 創建表、字段
Schema::create('users', function ($table) {
    $table->increments('id');
});
  • 檢查表/列是否存在
if (Schema::hasTable('users')) {
    //
}

if (Schema::hasColumn('users', 'email')) {
    //
}
  • 數據庫連接 & 表選項
// 如果你想要在一個數據庫連接上執行表結構操作,而該數據庫連接並不是默認數據庫連接,可以使用 connection 方法:

Schema::connection('foo')->create('users', function (Blueprint $table) {
    $table->increments('id');
});
// 要設置表的存儲引擎、字符編碼等選項,可以在 Schema 構建器上使用如下命令:

$table->engine = 'InnoDB'; // 指定表的存儲引擎(MySQL)
$table->charset = 'utf8';  // 指定數據表的默認字符集(MySQL)
$table->collation = 'utf8_unicode_ci'; // 指定數據表的字符序(MySQL)
$table->temporary();   // 創建臨時表(除SQL Server)
  • 重命名/刪除表
Schema::rename($from, $to); // 重命名錶名

Schema::drop('users');  // 刪除表
Schema::dropIfExists('users');

七.數據列

命令 描述
$table->bigIncrements(‘id’); 等同於自增 UNSIGNED 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(‘level’, [‘easy’, ‘hard’]); 等同於 ENUM 類型列
$table->float(‘amount’, 8, 2); 等同於 FLOAT 類型列,帶精度和總位數
$table->geometry(‘positions’); 等同於 GEOMETRY 類型列
$table->geometryCollection(‘positions’); 等同於 GEOMETRYCOLLECTION 類型列
$table->increments(‘id’); 等同於自增 UNSIGNED INTEGER (主鍵)類型列
$table->integer(‘votes’); 等同於 INTEGER 類型列
$table->ipAddress(‘visitor’); 等同於 IP 地址類型列
$table->json(‘options’); 等同於 JSON 類型列
$table->jsonb(‘options’); 等同於 JSONB 類型列
$table->lineString(‘positions’); 等同於 LINESTRING 類型列
$table->longText(‘description’); 等同於 LONGTEXT 類型列
$table->macAddress(‘device’); 等同於 MAC 地址類型列
$table->mediumIncrements(‘id’); 等同於自增 UNSIGNED MEDIUMINT 類型列(主鍵)
$table->mediumInteger(‘numbers’); 等同於 MEDIUMINT 類型列
$table->mediumText(‘description’); 等同於 MEDIUMTEXT 類型列
$table->morphs(‘taggable’); 添加一個 UNSIGNED INTEGER 類型的 taggable_id 列和一個 VARCHAR 類型的 taggable_type 列
$table->multiLineString(‘positions’); 等同於 MULTILINESTRING 類型列
$table->multiPoint(‘positions’); 等同於 MULTIPOINT 類型列
$table->multiPolygon(‘positions’); 等同於 MULTIPOLYGON 類型列
$table->nullableMorphs(‘taggable’); morphs() 列的 nullable 版本
$table->nullableTimestamps(); timestamps() 的別名
$table->point(‘position’); 等同於 POINT 類型列
$table->polygon(‘positions’); 等同於 POLYGON 類型列
$table->rememberToken(); 等同於添加一個允許爲空的 remember_token VARCHAR(100) 列
$table->smallIncrements(‘id’); 等同於自增 UNSIGNED SMALLINT (主鍵)類型列
$table->smallInteger(‘votes’); 等同於 SMALLINT 類型列
$table->softDeletes(); 新增一個允許爲空的 deleted_at TIMESTAMP 列用於軟刪除
$table->softDeletesTz(); 新增一個允許爲空的 deleted_at TIMESTAMP (帶時區)列用於軟刪除
$table->string(‘name’, 100); 等同於 VARCHAR 類型列,帶一個可選長度參數
$table->text(‘description’); 等同於 TEXT 類型列
$table->time(‘sunrise’); 等同於 TIME 類型列
$table->timeTz(‘sunrise’); 等同於 TIME 類型(帶時區)
$table->timestamp(‘added_on’); 等同於 TIMESTAMP 類型列
$table->timestampTz(‘added_on’); 等同於 TIMESTAMP 類型(帶時區)列
$table->timestamps(); 添加允許爲空的 created_at 和 updated_at TIMESTAMP 類型列
$table->timestampsTz(); 添加允許爲空的 created_at 和 updated_at TIMESTAMP 類型列(帶時區)
$table->tinyIncrements(‘numbers’); 等同於自增的 UNSIGNED TINYINT 類型列(主鍵)
$table->tinyInteger(‘numbers’); 等同於 TINYINT 類型列
$table->unsignedBigInteger(‘votes’); 等同於無符號的 BIGINT 類型列
$table->unsignedDecimal(‘amount’, 8, 2); 等同於 UNSIGNED DECIMAL 類型列,帶有總位數和精度
$table->unsignedInteger(‘votes’); 等同於無符號的 INTEGER 類型列
$table->unsignedMediumInteger(‘votes’); 等同於無符號的 MEDIUMINT 類型列
$table->unsignedSmallInteger(‘votes’); 等同於無符號的 SMALLINT 類型列
$table->unsignedTinyInteger(‘votes’); 等同於無符號的 TINYINT 類型列
$table->uuid(‘id’); 等同於 UUID 類型列
$table->year(‘birth_year’); 等同於 YEAR 類型列

八.列修改

修改器 描述
->after(‘column’) 將該列置於另一個列之後 (MySQL)
->autoIncrement() 設置 INTEGER 列爲自增主鍵
->charset(‘utf8’) 指定數據列字符集(MySQL)
->collation(‘utf8_unicode_ci’) 指定數據列字符序(MySQL/SQL Server)
->comment(‘my comment’) 添加註釋信息
->default($value) 指定列的默認值
->first() 將該列置爲表中第一個列 (MySQL)
->nullable($value = true) 允許該列的值爲 NULL
->storedAs($expression) 創建一個存儲生成列(MySQL)
->unsigned() 設置 INTEGER 列爲 UNSIGNED(MySQL)
->useCurrent() 設置 TIMESTAMP 列使用 CURRENT_TIMESTAMP 作爲默認值
->virtualAs($expression) 創建一個虛擬生成列(MySQL)

在修改列之前,確保已經將 doctrine/dbal 依賴添加到 composer.json 文件,Doctrine DBAL 庫用於判斷列的當前狀態並創建對列進行指定調整所需的 SQL 語句:
composer require doctrine/dbal

更新列屬性

// change 方法允許你修改已存在的列爲新的類型,或者修改列的屬性。例如,你可能想要增加 字符串類型列的尺寸,下面讓我們將 name 列的尺寸從 25 增加到 50:
Schema::table('users', function (Blueprint $table) {
    $table->string('name', 50)->change();
});

// 我們還可以修改該列允許 NULL 值:
Schema::table('users', function (Blueprint $table) {
    $table->string('name', 50)->nullable()->change();
});


// 重命名。注:暫不支持 enum 類型的列的修改和重命名。
Schema::table('users', function (Blueprint $table) {
    $table->renameColumn('from', 'to');
});


// 刪除數據列
Schema::table('users', function (Blueprint $table) {
    $table->dropColumn('votes');
});

Schema::table('users', function (Blueprint $table) {
    $table->dropColumn(['votes', 'avatar', 'location']);
});
命令 描述
$table->dropRememberToken(); 刪除 remember_token 列
$table->dropSoftDeletes(); 刪除 deleted_at 列
$table->dropSoftDeletesTz(); dropSoftDeletes() 方法別名
$table->dropTimestamps(); 刪除 created_at 和 updated_at 列
$table->dropTimestampsTz(); dropTimestamps() 方法別名

九.索引

命令 描述
$table->primary(‘id’); 添加主鍵索引
$table->primary([‘first’, ‘last’]); 添加組合索引
$table->unique(‘email’); 添加唯一索引
$table->index(‘state’); 添加普通索引
$table->spatialIndex(‘location’); 添加空間索引(不支持SQLite)
$table->dropPrimary(‘users_id_primary’); 從 “users” 表中刪除主鍵索引
$table->dropUnique(‘users_email_unique’); 從 “users” 表中刪除唯一索引
$table->dropIndex(‘geo_state_index’); 從 “geo” 表中刪除普通索引
$table->dropSpatialIndex(‘geo_location_spatialindex’); 從 “geo” 表中刪除空間索引(不支持SQLite)

十.索引長度 & MySQL / MariaDB

Laravel 默認使用 utf8mb4 字符集,支持在數據庫中存儲 emoji 表情。如果你現在運行的 MySQL 版本低於 5.7.7(或者低於 10.2.2 版本的 MariaDB),需要手動配置遷移命令生成的默認字符串長度,以便 MySQL 爲它們創建索引。你可以通過在 AppServiceProvider 中調用 Schema::defaultStringLength 方法來完成配置:

use Illuminate\Support\Facades\Schema;

/**
 * Bootstrap any application services.
 *
 * @return void
 * @translator laravelacademy.org
 */
public function boot()
{
    Schema::defaultStringLength(191);
}

十一.外鍵約束

Schema::table('posts', function (Blueprint $table) {
    $table->integer('user_id')->unsigned();
    $table->foreign('user_id')->references('id')->on('users');
});

// 你還可以爲約束的“on delete”和“on update”屬性指定期望的動作:
$table->foreign('user_id')
      ->references('id')->on('users')
      ->onDelete('cascade');

// 要刪除一個外鍵,可以使用 dropForeign 方法。外鍵約束和索引使用同樣的命名規則 —— 連接表名、外鍵名然後加上“_foreign”後綴:
$table->dropForeign('posts_user_id_foreign');

//或者,你還可以傳遞在刪除時會自動使用基於慣例的約束名數值數組:
$table->dropForeign(['user_id']);

//你可以在遷移時通過以下方法啓用或關閉外鍵約束:
Schema::enableForeignKeyConstraints();
Schema::disableForeignKeyConstraints();
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章