# Migration 版本控制 (Laravel 7)
## 利用 Migration 檔案生成資料表
1. Terminal輸入`composer create-project laravel/laravel=7.* XXX`
安裝Larave7最後版本 `Laravel_websocket`
2. Terminal輸入`php-82 artisan make:migration create_table_name `
創建 Migration 檔案,這會在 database/migrations 目錄中創建一個新的 Migration 檔案。
3. 定義 Migration 的資料表結構:
開啟剛創建的 Migration 檔案,然後在 up 方法中使用 Schema 類來定義表格的結構,
設置型態、索引、外鍵 ,詳細請看<a href="#type">資料表屬性設置</a>。
#### 下為範例:
預設初始:
```php=
public function up(){
Schema::create('abilities', function (Blueprint $table) {
$table->id();
$table->timestamps();
});
}
```
>簡易說明上段程式內容:
>create//第二行 新建名為'abilities'的資料表內容為function內
>//$table為此資料表
>$table->id(); //設置此資料表的一個欄位名稱為`id`
>並且屬性:索引(index)為主鍵(primary),型態為==bigint==,自動編碼
>
>$table->timestamps(); //設置此資料表的一個欄位名稱為()內文字
>並且屬性:型態為`timestamp`
依照需求重新編寫:

```php=
public function up(){
Schema::create('abilities', function (Blueprint $table) {
$table->increments('id');
$table->string('name',255)->nullable();
$table->string('title',255)->nullable();
});
}
```
4. 建立資料庫並更改 ==.env檔== 中的`DB_DATABASE`

5. Terminal輸入`php-82 artisan migrate`能把目錄 database/migrations 中所有未執行過的 Migration 檔案生成資料表
如果只想單獨 migrate 一個 Migration 檔案 Terminal 輸入
`php-82 artisan migrate --path=/database/migrations/{ Migration 檔案名稱 }.php`
6. Terminal 輸入 `php-82 artisan migrate:rollback` 可以把上次 migrate 的資料表還原
>執行`php-82 artisan migrate` 是執行資料夾中所有 Migration 檔案的 function up()
>執行`php-82 artisan migrate:rollback` 是執行function down()

| Terminal 指令 | 作用 |
| ----- | ----- |
| `php-82 artisan make:migration` |創建新的 Migration 檔案。 |
| `php-82 artisan migrate:status` | 顯示所有 Migration 檔案的狀態。 |
| `php-82 artisan migrate --pretend` | 顯示創建所使用的 SQL 語句 |
| `php-82 artisan migrate:refresh` | 重置並重新運行所有 migrate。 |
| `php-82 artisan migrate:reset` | rollback 所有 migrate。 |
| `php-82 artisan migrate:rollback` | rollback 最近的一次 migrate。 |
| `php-82 artisan migrate:rollback --step=5` | rollback 最近的五次 migrate |
7. 移除Migrations
刪除不要的migration file
`rm -f my_migration_file_name.php`
重置 composer autoload
`composer dump-autoload`
最後再進去資料庫drop要捨棄的table
***
## 利用 Migration 檔案更新資料表
1. 要進行DB修改需先安裝Laravel套件 doctrine/dbal
並且因為最新版本的doctrine/dbal已到3.7與Laravel7部分不相容,
所以不能安裝最新版本的doctrine/dbal要安裝2版本的,
此時有2種做法:
I.Terminal輸入`composer require doctrine/dbal:2.*`
II.Terminal輸入`composer require doctrine/dbal`後,

要在project裡的檔案composer.json中手動更改為2.13,

並且在Terminal輸入`composer update`,更新至版本2最後更新2.13.9
>查詢doctrine/dbal使用版本方法:
>在composer.lock檔 搜尋`doctrine/dbal`在有安裝doctrine/dbal的情境下,
>通常會有9個結果 第1個就是現在的版本
>
2. 以下為範例,詳細屬性設定請看<a href="#type">資料表屬性設置</a>,
```php=
//新增欄位
Schema::table('abilities', function (Blueprint $table) {
$table->integer('votes');
});
//修改欄位屬性
Schema::table('users', function ($table) {
$table->string('name', 50)->change();
});
//重新命名欄位
Schema::table('users', function (Blueprint $table) {
$table->renameColumn('from', 'to');
});
//移除欄位:
Schema::table('users', function ($table) {
$table->dropColumn('votes');
});
//移除多個欄位
Schema::table('users', function ($table) {
$table->dropColumn(['votes', 'avatar', 'location']);
});
```
>在要進行drop[delete]或者change[update]
>可以斟酌使用
>Schema::hasTable('')
>Schema::hasColumn('', '')
>使用範例:
>```php=
>if (Schema::hasTable('users')) {
> // The "users" table exists...
>}
>
>if (Schema::hasColumn('users', 'email')) {
> // The "users" table exists and has an "email" column...
>}
>```
***
<div id="type"></div>
## 資料表屬性設置:
#### 常用型態介紹
| SQL型態 | migration function |SQL型態|migration function|
| -------- | ------------------ |---|---|
| bigint | bigInteger() | varchar | string() |
| int | integer() | char | char() |
| tinyint | tinyInteger() | text | text() |
| double | double() | date | date() |
| float | float() | datetime | dateTime() |
| boolean | boolean () | time | time() |
| id()大致相同但可設定欄位名稱,型別為int | increments() | timestamp | timestamp() |
#### 索引(index)[鍵]設定
| 索引(index)[鍵] | migration語法 |
| -------- | -------- |
| 設置主鍵 | primary() |
| 設置複合鍵 | primary([,]) |
| 設置唯一索引(值不允許重複) | unique() |
| 設置索引 | index() |
| 刪除索引 | dropIndex() |
| 重新命名索引 | renameIndex() |
| 設置外鍵 | foreign() |
| 刪除外鍵 | dropForeign() |
| 設置外鍵(在另一個資料表) | references() |
| 資料表 | on() |
```php=
//外鍵設置實際運用
Schema::table('posts', function (Blueprint $table) {
$table->unsignedBigInteger('user_id'); //設置主鍵
$table->foreign('user_id')->references('id')->on('users'); //設置外鍵
//
});
// 更簡潔的寫法
Schema::table('posts', function (Blueprint $table) {
$table->foreignId('user_id')->constrained('users');
});
//外鍵刪除實際運用
Schema::table('posts', function (Blueprint $table) {
$table->dropForeign('chips_branch_id_foreign');
$table->dropIndex('chips_branch_id_foreign');
});
```
#### 常用屬性設定
| 屬性 | migration語法 |
| ---- | ----------- |
| 預設值 | default() |
| 空值 | nullable() |
| 註解 | comment() |
| 編碼與排序| collation() ex: "utf8mb4_unicode_ci" |
| 將 int 欄位設定自動增量,主鍵 | autoIncrement() |
| 將 timestamp 欄位設定為使用 CURRENT_TIMESTAMP 作為預設值。 | useCurrent() |
| 刪除欄位 | dropColumn() |
| 新增在欄位()後 | after() |
| 資料表第一個欄位 | first() |
| 更新欄位屬性 | change() |
| 將 int 欄位設定為 UNSIGNED(只為正數) | unsigned() |
| 刪除資料表 (外鍵索引的表名稱會引用舊的表名稱。) |Schema::drop() Schema::dropIfExists(); |
>參考資料
>[Laravel官方網站Migrations頁面](https://laravel.com/docs/7.x/migrations)
>[Laravel 5.2版本中文翻譯區](https://laravel.tw/docs/5.2/migrations)
P.S. 在Laravel 10中有新增功能`php-82 artisan schema:dump`,功能簡易說明:可以讓越來越多的資料庫 Migration 檔「壓縮」進單一 SQL 檔。
# 此文件最後撰寫時間 2023/10/23