完成 DB migration 的設定之後,今天要來新增任務清單的分類!
大家應該有聽過「 關聯式資料庫 」吧?有沒有想過為什麼會有這個詞出現呢?
在 Day 18 的時候,有提到幾個常見的類型,分別是:
資料庫的每一張表,都可以透過上面的方式互相參考(關聯),用物件的方式存取資料,而不是用手動的方式寫 JOIN(SQL 語法),透過這樣的設計,可以讓資料結構更清楚!
以 tasks
資料表來說,目前只有儲存任務的內容,但如果任務很多,要找到任務就會很花費時間,所以可以新增「 任務類別 」,將任務分類,讓資料表之間有連結。
所以我們要在 To-do List 專案中新增「 分類(Category) 」功能,讓任務可以被歸類,實現一對多的資料庫設計。
那我們就開始吧!
一開始,需要先定義 Category 資料表的結構,所以在 taskModel.go
檔案裡加上:
package model
import "gorm.io/gorm"
type Category struct {
gorm.Model
Title string `json:"name"`
}
type UpdateCategory struct {
Name *string `json:"name"`
}
我這邊只有定義編號(id)和類別名稱 (name)兩項,大家可以依照需求自行新增~
taskModel.go
:完成 Category 資料表定義之後,要記得引入 Task 資料表,新增 Category ID,這樣等一下執行 migration 時,透過 sql 語法設定,兩個資料表就會互相連結了!
package model
import "gorm.io/gorm"
type Task struct {
gorm.Model
Item string `json:"item"`
Status bool `json:"status"`
CategoryID uint // 對應 Category
}
在執行 migration 之前,先輸入以下指令,建立 .up.sql
和 .down.sql
檔案:
migrate create -ext sql -dir database/migrations -seq add_categories
然後,把剛剛在 taskModel.go
新增的 Category 資料表邏輯透過 sql 語法在 .up.sql
檔案中,寫入「 建立 categories 資料表 」、「 在 tasks 資料表新增 category_id 的欄位 」,而且這個新增的欄位必須參考 categories 資料表的 id,這樣設定兩個資料才會自動連結唷!
而在 .down.sql
檔案裡,則是寫入與 .up.sql
邏輯相反的 sql 語法,這樣當我們 rollback 資料庫版本時才能正確對應。
以下為範例:
// .up.sql
CREATE TABLE categories (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL UNIQUE
);
ALTER TABLE tasks ADD COLUMN category_id INTEGER REFERENCES categories(id);
// .down.sql
DROP TABLE IF EXISTS categories;
ALTER TABLE tasks DROP COLUMN category_id;
完成 migration 檔案內容之後,就可以執行 migrate up 了:
migrate -database "sqlite://tasks.db" -path database/migrations up
成功執行之後,就會看到資料庫已經新增了 categories
表,同時也在 tasks
新增了 category_id
欄位:
*如果在執行 migration 時,有出現 error: Dirty database
的錯誤,可以先強制修正版本,例如:先將版本強制修正為 1,就輸入以下指令:
migrate -database "sqlite3://tasks.db" force 1
修正完之後,再重新執行 migrate -database "sqlite3://tasks.db" up
指令,這樣資料庫就會成功進版到目前最新的版本了!