D9 - 走進 Laravel 的世界,從 Migration 開始

閱讀時間約 20 分鐘

哈囉,大家好!經過前面的努力,我們已經為個人財務管理系統設計了完整的資料庫結構。現在,是時候將這些設計實際落地到 Laravel 框架中了。

今天,我們要一起探索 Laravel 中非常重要的一環:Migration(資料庫遷移)。

相信我,掌握了 Migration,不僅能讓你更有效地管理資料庫,還能讓你在開發過程中更加游刃有餘。讓我們一起揭開 Migration 的神秘面紗吧!


一、什麼是 Laravel 的 Migration?

Migration 是 Laravel 提供的一種資料庫管理工具,它讓你可以用程式碼的方式定義和修改資料庫結構。簡單來說,Migration 就像是資料庫的版本控制,讓你可以方便地同步團隊之間的資料庫變更。


為什麼要使用 Migration?

  • 版本控制:像 Git 一樣,Migration 讓你可以追蹤資料庫的變化,方便團隊協作。
  • 自動化:透過指令即可執行資料庫的建立、更新,減少手動操作的錯誤風險。
  • 可移植性:輕鬆在不同的環境中同步資料庫結構,如開發、測試、正式環境。

個人經驗分享:還記得剛開始開發時,手動修改資料庫結構總是帶來各種麻煩。自從使用了 Migration,一切變得有條不紊,在開發上也更加順暢。



二、開始使用 Migration

1. 建立 Migration 檔案

Laravel 提供了 Artisan CLI(命令列介面)來幫助我們生成 Migration 檔案。讓我們來為 users 表建立一個 Migration。

在終端機中進入專案的根目錄,執行以下指令:等等……你有發現 database/migrations 目錄下,已經有一個 create_users_table.php 檔案嗎?這個檔案就是預設的 users 資料表結構:

/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});

Schema::create('password_reset_tokens', function (Blueprint $table) {
$table->string('email')->primary();
$table->string('token');
$table->timestamp('created_at')->nullable();
});

Schema::create('sessions', function (Blueprint $table) {
$table->string('id')->primary();
$table->foreignId('user_id')->nullable()->index();
$table->string('ip_address', 45)->nullable();
$table->text('user_agent')->nullable();
$table->longText('payload');
$table->integer('last_activity')->index();
});
}

/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('users');
Schema::dropIfExists('password_reset_tokens');
Schema::dropIfExists('sessions');
}

這比我們預先規劃的多了兩張表,而且 users 的結構有幾個地方不一樣。所以在我們開始編輯 Migration 檔案前,先來介紹 Schema Builder 的相關用法。

2. Schema Builder 的基本用法

Laravel 的 Schema Builder 是一個強大的工具,讓你可以使用 PHP 語法來定義資料庫的結構,而不需要直接撰寫 SQL 語句。這使得程式碼更具可讀性,也更容易維護。

以下是一些常用的 Schema Builder 方法,以及它們對應的 MySQL 資料型態:

  • $table->bigIncrements('id'):建立一個自增的 BIGINT 主鍵欄位,等同於 MySQL 的 BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY。
  • $table->string('username', 50)->unique():建立一個長度為 50 的 VARCHAR 欄位,並設定唯一索引。
  • $table->string('password'):建立一個字串欄位,用於儲存加密後的密碼,等同於 MySQL 的 VARCHAR(255)。
  • $table->timestamps():自動建立 created_at 和 updated_at 兩個時間戳記欄位。
  • $table->text('description'):建立一個 TEXT 欄位,適合儲存大量文字。
  • $table->decimal('amount', 8, 2):建立一個 DECIMAL 欄位,總長度為 8 位,包含 2 位小數。
  • $table->boolean('is_active'):建立一個 BOOLEAN 欄位,儲存布林值。
  • $table->date('transaction_date'):建立一個 DATE 欄位,用於儲存日期。
  • $table->enum('type', ['income', 'expense']):建立一個 ENUM 枚舉欄位,限定值為 'income' 或 'expense'。
  • $table->foreignId('user_id')->constrained('users'):建立一個外鍵欄位,參照 users 表的 id 欄位。
  • $table->unique('email'):為 email 欄位建立唯一索引。
    MySQL 資料型態對照
  • $table->string():VARCHAR
  • $table->text():TEXT
  • $table->integer():INT
  • $table->bigInteger():BIGINT
  • $table->decimal():DECIMAL
  • $table->boolean():TINYINT(1)
  • $table->date():DATE
  • $table->dateTime():DATETIME

小提醒:Laravel 的 Schema Builder 提供了許多方便的方法,詳細可以參考官方文件,多加了解絕對不會吃虧!

3. 編寫 Migration 檔案

打開預設的 create_users_table.php 檔案,你會看到 up 和 down 兩個方法。

  • up 方法:定義在執行 Migration 時要做的事情,例如建立資料表。
  • down 方法:定義在回滾 Migration 時要做的事情,例如刪除資料表。
    現在,讓我們修改 up 方法,使其符合我們的需求:
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('username', 50)->unique();
$table->string('email', 100)->unique();
$table->string('password');
$table->timestamps();
});
}

在這裡,我們使用了 Laravel 的 Schema Builder 來定義資料表的結構,並移除了我們不需要的欄位。

寫下來我們所執行的指令都是在Laravel 容器內執行,如果忘記怎麼進入容器的終端環境,請回去參考D5喔

三、為其他資料表建立 Migration

接下來,按照同樣的步驟,為其他資料表建立 Migration。

1. 建立 bank_accounts 表的 Migration

執行指令:

php artisan make:migration create_bank_accounts_table --create=bank_accounts

編輯生成的 Migration 檔案:

public function up()
{
Schema::create('bank_accounts', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('user_id');
$table->string('account_name', 100);
$table->string('account_number', 50)->nullable();
$table->string('bank_name', 100)->nullable();
$table->decimal('balance', 15, 2)->default(0.00);
$table->timestamps();

// 外鍵約束
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
});
}

2. 建立 categories 表的 Migration

執行指令:

php artisan make:migration create_categories_table --create=categories

編輯生成的 Migration 檔案:

public function up()
{
Schema::create('categories', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('user_id');
$table->string('category_name', 100);
$table->enum('type', ['income', 'expense']);
$table->timestamps();

// 外鍵約束
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
});
}

3. 建立 transactions 表的 Migration

執行指令:

php artisan make:migration create_transactions_table --create=transactions

編輯生成的 Migration 檔案:

public function up()
{
Schema::create('transactions', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('user_id');
$table->unsignedBigInteger('bank_account_id');
$table->unsignedBigInteger('category_id');
$table->enum('type', ['income', 'expense']);
$table->decimal('amount', 15, 2);
$table->date('transaction_date');
$table->string('description', 255)->nullable();
$table->timestamps();

// 外鍵約束
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->foreign('bank_account_id')->references('id')->on('bank_accounts')->onDelete('cascade');
$table->foreign('category_id')->references('id')->on('categories')->onDelete('cascade');
});
}

四、執行 Migration

所有 Migration 檔案都準備好了,現在讓我們來執行它們,實際建立資料表。

在終端機中執行:

php artisan migrate

如果一切順利,終端機會顯示 Migration 已成功執行。

個人經驗分享:有時候執行 Migration 時會遇到錯誤,通常是因為資料表之間的關聯順序問題。例如,transactions 表需要 users、bank_accounts 和 categories 表已經存在。所以在編寫 Migration 時,注意資料表的建立順序很重要。

解決關聯順序問題

為了確保 Migration 按照正確的順序執行,可以在 Migration 檔案的開頭加上時間戳,使其按照時間順序排列。


例如,在 Migration 檔案名稱前面添加時間戳:


  • 2024_09_22_100000_create_users_table.php
  • 2024_09_22_101000_create_bank_accounts_table.php
  • 2024_09_22_102000_create_categories_table.php
  • 2024_09_22_103000_create_transactions_table.php
    這樣,Laravel 會按照時間順序執行 Migration,避免外鍵約束的問題。

五、Rollback 與修改 Migration

1. rollback Migration

如果發現 Migration 有錯誤,需要回滾,執行:

php artisan migrate:rollback

這會回滾最近一次的 Migration。

2. 修改 Migration

在開發階段,你可能需要修改已經建立的 Migration。常見的做法是:

  1. rollback Migration:
php artisan migrate:rollback
  1. 修改 Migration 檔案。
  2. 重新執行 Migration:
php artisan migrate

小提醒:在正式環境中,不建議直接修改已經執行的 Migration,而是應該建立新的 Migration 來修改資料表結構。

六、填充測試資料(Seeder)

為了測試,我們可以使用 Laravel 的 Seeder 來填充一些測試資料。

1. 建立 Seeder

執行指令:

php artisan make:seeder UsersTableSeeder

這會在 database/seeders 目錄下生成一個 UsersTableSeeder.php 檔案。

2. 編寫 Seeder

打開 UsersTableSeeder.php,填寫以下內容:

public function run()
{
User::factory()->create([
'username' => 'testuser',
'email' => 'test@example.com',
'password' => bcrypt('password'),
'created_at' => now(),
'updated_at' => now(),
]);
}

3. 執行 Seeder

在 DatabaseSeeder.php 中,呼叫剛剛建立的 Seeder:

public function run()
{
$this->call(UsersTableSeeder::class);
}

執行 Seeder:

php artisan db:seed

這樣,我們就為 users 表填充了一筆測試資料。

小結

今天,我們深入了解了 Laravel 的 Migration,並實際建立了我們之前設計的資料表。透過 Migration,我們可以:

  • 方便地管理資料庫結構:所有的資料表定義都在程式碼中,可追溯、可版本控制。
  • 團隊協作更順暢:團隊成員之間的資料庫變更可以透過版本控制系統同步。
  • 自動化部署:在部署到不同環境時,只需執行 Migration,就能確保資料庫結構一致。

個人經驗分享:一開始接觸 Migration 時,可能會覺得多此一舉,但當你經歷過手動修改資料庫帶來的痛苦後,你就會發現 Migration 是多麼的可靠和方便。

Next

在完成資料表的建立後,接下來我們將:建立模型(Models),與資料表進行互動!

這是一系列以軟體開發為主題的輕鬆分享,內容涵蓋了技術選擇、開發經驗、實戰應用等多方面的議題。無論是如何在眾多框架中做出選擇,還是如何應對技術轉移的挑戰,作者都用幽默、有趣的對話風格,將複雜的技術問題轉化為易懂的故事。
留言0
查看全部
發表第一個留言支持創作者!
這篇文章介紹了個人財務管理系統的資料庫設計,涵蓋使用者管理、銀行帳戶管理、財務紀錄和分類管理的核心功能。系統需求包括註冊登入、帳戶管理、財務記錄分類和報表生成。設計了四個資料表,並詳細說明其欄位設計和建表語法。透過清晰的表關聯,確保資料一致性和系統擴展性,為後續的 Laravel 開發打下基礎。
好了,經過前幾篇的努力,我們的開發環境已經搭建完成,並進行了初步的測試。一切看起來都很順利,但在正式進入開發之前,我們還有一件重要的事情要做:加入版本控制。 你可能會想:「現在還早吧?我一個人開發,有必要嗎?」但相信我,版本控制就像是遊戲中的存檔點,或者電影裡的多重宇宙時間線,在你需要的時候,
本文指導如何驗收基於 Docker 的開發環境,檢查 Laravel 後端、Nuxt 前端、Nginx 反向代理和 MariaDB 資料庫是否正常運行。透過啟動容器、修改 hosts 檔案、測試各服務的運作,確保整個開發環境穩定。並且提供了常見問題的解決方案,幫助開發者順利驗收環境。
本文詳細介紹了如何使用 Docker 環境構建 Laravel 後端和 Nuxt 前端,並通過 Nginx 進行反向代理來協調它們的互動。從 docker-compose.yml 配置到各個服務的設定,讓開發環境穩定運行,並提供了常用的 Docker 指令以便於操作。
好了,到了這個階段,我們終於要進入 Docker 的世界了!前幾篇文章我們討論了系統規劃與需求,現在來到實作的部分,要為整個開發環境打好基礎。這篇文章將帶你一步步打造出一個基於 Docker 的開發環境,裡面包含了 Laravel(後端)、Nuxt(前端)、Nginx(伺服器),以及 MariaDB
這篇文章深入探討了開發個人財務管理系統的規劃過程,包括需求確認、環境建置及技術選型等關鍵步驟。作者強調在開發前進行充分的規劃與設計是成功的基礎,並提供了具體的工具與技術選擇,如PHP、Laravel和Docker。通過清晰的步驟指引,文章幫助讀者掌握系統開發的核心要素,確保順利推進專案。
這篇文章介紹了個人財務管理系統的資料庫設計,涵蓋使用者管理、銀行帳戶管理、財務紀錄和分類管理的核心功能。系統需求包括註冊登入、帳戶管理、財務記錄分類和報表生成。設計了四個資料表,並詳細說明其欄位設計和建表語法。透過清晰的表關聯,確保資料一致性和系統擴展性,為後續的 Laravel 開發打下基礎。
好了,經過前幾篇的努力,我們的開發環境已經搭建完成,並進行了初步的測試。一切看起來都很順利,但在正式進入開發之前,我們還有一件重要的事情要做:加入版本控制。 你可能會想:「現在還早吧?我一個人開發,有必要嗎?」但相信我,版本控制就像是遊戲中的存檔點,或者電影裡的多重宇宙時間線,在你需要的時候,
本文指導如何驗收基於 Docker 的開發環境,檢查 Laravel 後端、Nuxt 前端、Nginx 反向代理和 MariaDB 資料庫是否正常運行。透過啟動容器、修改 hosts 檔案、測試各服務的運作,確保整個開發環境穩定。並且提供了常見問題的解決方案,幫助開發者順利驗收環境。
本文詳細介紹了如何使用 Docker 環境構建 Laravel 後端和 Nuxt 前端,並通過 Nginx 進行反向代理來協調它們的互動。從 docker-compose.yml 配置到各個服務的設定,讓開發環境穩定運行,並提供了常用的 Docker 指令以便於操作。
好了,到了這個階段,我們終於要進入 Docker 的世界了!前幾篇文章我們討論了系統規劃與需求,現在來到實作的部分,要為整個開發環境打好基礎。這篇文章將帶你一步步打造出一個基於 Docker 的開發環境,裡面包含了 Laravel(後端)、Nuxt(前端)、Nginx(伺服器),以及 MariaDB
這篇文章深入探討了開發個人財務管理系統的規劃過程,包括需求確認、環境建置及技術選型等關鍵步驟。作者強調在開發前進行充分的規劃與設計是成功的基礎,並提供了具體的工具與技術選擇,如PHP、Laravel和Docker。通過清晰的步驟指引,文章幫助讀者掌握系統開發的核心要素,確保順利推進專案。
你可能也想看
Google News 追蹤
Thumbnail
本專欄將提供給您最新的市場資訊、產業研究、交易心法、優質公司介紹,以上內容並非個股分析,還請各位依據自身狀況作出交易決策。歡迎訂閱支持我,獲得相關內容,也祝您的投資之路順遂! 每年 $990 訂閱方案👉 https://reurl.cc/VNYVxZ 每月 $99 訂閱方案👉https://re
Thumbnail
CodeIgniter 3 和 Laravel 是兩種不同的 PHP 框架,各有其特點和適用場景。CodeIgniter 3 是一個輕量級框架,Laravel 是一個功能強大的現代 PHP 框架,同樣都有Models的它們有什麼樣的差別呢?
Thumbnail
在過去兩年中,我持續運用 Notion 進行個人管理,個人管理的模板也逐漸定型,藉此分享個人管理模板的使用心得。
Thumbnail
※ 視圖模板 視圖模板(View Templates) 是在 MVC 架構中負責展示數據的 HTML 文件,包含模板語法,用於在渲染時插入實際數據。它們的主要目的是分離數據與展示邏輯,讓代碼更加模塊化和易於維護。 視圖模板設計和使用的核心理念,就是「重複的事情不要重複做、效益最大化、有效利用資源
Thumbnail
在前一篇我們已經成功地建立簽核表單及簽核節點並關聯回請假表單,而本篇會接著介紹如何管理簽核節點狀態並同步更新簽核表單狀態。
今天學習Git 的第一步: 取得與建立項目 Getting and Creating Projects [1]。 之前提到「儲存庫 Repository」就是儲存所有「檔案 File」的地方。 在Git 的邏輯裡,儲存庫是要儲存所有的「快照 Snapshots」。 什麼是快照
儲存庫 (Repository) 是檔案(File)的儲存區域。 在版本控制中,儲存庫是包含所有檔案的資料夾[1]。 每次改動檔案,你都可以選擇要不要儲存。 而那些有被處存的改動,就被稱為「提交 Commit」[2]。 而當一個儲存庫有多個開發者(Developer)在貢獻,
Thumbnail
工具功能 (1) 彈性任意查詢檔案,如對來源目錄設定,檔案修改日期 設定,檔名特定字串或副檔名設定後,自動查出明細,並可展開至各階子目錄處理     (2) 依查詢後結果,可產出 LIST ,提供查詢結果之確認,再依此對檔案作複 (3) 可對檔案作移動,複製至別處,刪除處理,使電腦可騰出硬碟空間
Thumbnail
第一份正職工作 在iot公司擔任後端工程師,一上工就使用先前沒用過的php/laravel,也馬上負責公司產品的架構規劃,先前資料庫只有簡單記載使用者跟使用者的一些設定,很多地方有資料不一致的問題,產品內容還有很多實體的關係沒有被定義進資料庫都是這次改版我要做的事情。 改版納入公司、機器
Thumbnail
※ 基本操作:SQL 語法,SELECT, WHERE, CREATE, UPDATE, DELETE。 SELECT:從資料庫中或資料表中指定要選擇的欄位中取得資料,稱之為查詢 (query)。 ※ 語法:要由兩部分構成,第一部分是要 "拿什麼" 資料 (若有多項用逗號隔開);第二部分則為
Migration在 Laravel 中是一種用來管理資料庫結構變更的機制。它的主要目的是使開發者能夠在應用程序的不同環境中保持資料庫結構的一致性,並輕鬆地進行結構變更
Thumbnail
本專欄將提供給您最新的市場資訊、產業研究、交易心法、優質公司介紹,以上內容並非個股分析,還請各位依據自身狀況作出交易決策。歡迎訂閱支持我,獲得相關內容,也祝您的投資之路順遂! 每年 $990 訂閱方案👉 https://reurl.cc/VNYVxZ 每月 $99 訂閱方案👉https://re
Thumbnail
CodeIgniter 3 和 Laravel 是兩種不同的 PHP 框架,各有其特點和適用場景。CodeIgniter 3 是一個輕量級框架,Laravel 是一個功能強大的現代 PHP 框架,同樣都有Models的它們有什麼樣的差別呢?
Thumbnail
在過去兩年中,我持續運用 Notion 進行個人管理,個人管理的模板也逐漸定型,藉此分享個人管理模板的使用心得。
Thumbnail
※ 視圖模板 視圖模板(View Templates) 是在 MVC 架構中負責展示數據的 HTML 文件,包含模板語法,用於在渲染時插入實際數據。它們的主要目的是分離數據與展示邏輯,讓代碼更加模塊化和易於維護。 視圖模板設計和使用的核心理念,就是「重複的事情不要重複做、效益最大化、有效利用資源
Thumbnail
在前一篇我們已經成功地建立簽核表單及簽核節點並關聯回請假表單,而本篇會接著介紹如何管理簽核節點狀態並同步更新簽核表單狀態。
今天學習Git 的第一步: 取得與建立項目 Getting and Creating Projects [1]。 之前提到「儲存庫 Repository」就是儲存所有「檔案 File」的地方。 在Git 的邏輯裡,儲存庫是要儲存所有的「快照 Snapshots」。 什麼是快照
儲存庫 (Repository) 是檔案(File)的儲存區域。 在版本控制中,儲存庫是包含所有檔案的資料夾[1]。 每次改動檔案,你都可以選擇要不要儲存。 而那些有被處存的改動,就被稱為「提交 Commit」[2]。 而當一個儲存庫有多個開發者(Developer)在貢獻,
Thumbnail
工具功能 (1) 彈性任意查詢檔案,如對來源目錄設定,檔案修改日期 設定,檔名特定字串或副檔名設定後,自動查出明細,並可展開至各階子目錄處理     (2) 依查詢後結果,可產出 LIST ,提供查詢結果之確認,再依此對檔案作複 (3) 可對檔案作移動,複製至別處,刪除處理,使電腦可騰出硬碟空間
Thumbnail
第一份正職工作 在iot公司擔任後端工程師,一上工就使用先前沒用過的php/laravel,也馬上負責公司產品的架構規劃,先前資料庫只有簡單記載使用者跟使用者的一些設定,很多地方有資料不一致的問題,產品內容還有很多實體的關係沒有被定義進資料庫都是這次改版我要做的事情。 改版納入公司、機器
Thumbnail
※ 基本操作:SQL 語法,SELECT, WHERE, CREATE, UPDATE, DELETE。 SELECT:從資料庫中或資料表中指定要選擇的欄位中取得資料,稱之為查詢 (query)。 ※ 語法:要由兩部分構成,第一部分是要 "拿什麼" 資料 (若有多項用逗號隔開);第二部分則為
Migration在 Laravel 中是一種用來管理資料庫結構變更的機制。它的主要目的是使開發者能夠在應用程序的不同環境中保持資料庫結構的一致性,並輕鬆地進行結構變更