iT邦幫忙

2026 iThome 鐵人賽

DAY 17
0
自我挑戰組

Laravel 讀碼源系列 第 17

解釋鋼琴留言版的資料表

  • 分享至 

  • xImage
  •  

鋼琴留言版
https://laihao.vaserver.com/gbook

可以實際測試
也歡迎大家一起來學習喔
https://www.pressplay.cc/project/9D489B43D08BD198FDEB03ECDEFAC161/about
這是一份由 phpMyAdmin 匯出的 MySQL 資料庫備份檔,用途是建立 gbook 資料表,並把留言資料重新匯入資料庫。整體可分成:

  1. 設定資料庫環境。
  2. 建立 gbook 資料表。
  3. 插入 29 筆留言。
  4. 設定主索引與自動編號。
  5. 完成交易並還原原本的設定。

一、檔案註解

-- phpMyAdmin SQL Dump
-- version 5.2.3

-- 開頭的是註解,不會被 MySQL 執行。

這幾行表示:

  • 匯出工具:phpMyAdmin 5.2.3。
  • MySQL 伺服器版本:5.7.44。
  • PHP 版本:8.1.34。
  • 資料庫名稱:laihao_my_gbook
-- 主機: localhost:3306

表示資料庫位於本機伺服器:

  • localhost:本機電腦。
  • 3306:MySQL 預設連接埠。

二、匯入前的環境設定

SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";

設定 MySQL 的 SQL 模式。

NO_AUTO_VALUE_ON_ZERO 允許 AUTO_INCREMENT 欄位在特殊情況下使用 0,而不一定將 0 視為要求自動產生編號。這是 phpMyAdmin 常見的匯出設定。

START TRANSACTION;

開始一個交易。

交易的概念是:一連串 SQL 指令可以視為一個完整工作。如果中間發生錯誤,可以回復;如果全部成功,最後使用 COMMIT 確認。

SET time_zone = "+00:00";

將本次資料庫操作的時區設定為 UTC,也就是協調世界時。

你資料中的時間,例如:

'2026-02-01 05:15:28'

會依照這個時區寫入或解讀。若網站實際使用台灣時間,台灣是 UTC+8,應注意 PHP、MySQL 與網站顯示時間是否一致。

/*!40101 SET NAMES utf8mb4 */;

這種:

/*!40101 ... */

是 MySQL 的條件式註解。當 MySQL 版本至少為 4.1.1 時,裡面的指令才會執行。

SET NAMES utf8mb4;

指定目前連線使用 utf8mb4 字元編碼,讓中文、日文及 Emoji 能夠正確儲存,例如:

the entertainer😅

使用 utf8mb4 是正確做法,因為它能完整支援 Unicode 與四位元組 Emoji。

三、建立資料表

CREATE TABLE `gbook` (

建立名稱為 gbook 的資料表。

反引號:

`gbook`

用來包住資料表或欄位名稱,避免名稱與 MySQL 保留字衝突。

1. gid

`gid` int(11) NOT NULL COMMENT '主索引',

這是留言的編號。

  • int(11):整數型態。
  • NOT NULL:不可為空值。
  • COMMENT '主索引':欄位說明,僅供閱讀,不影響資料運作。

後面會設定為主鍵和自動遞增欄位。

2. gbook_poser

`gbook_poser` varchar(20)
NOT NULL
COMMENT '發表人',

儲存留言發表人的身分。

  • varchar(20):最多 20 個字元。
  • 目前資料都是:
學生

3. gbook_kind

`gbook_kind` varchar(20)
NOT NULL
COMMENT '發表類型',

儲存留言分類,例如:

初級

4. gbook_title

`gbook_title` varchar(30)
NOT NULL
COMMENT '發表標題',

儲存留言標題或分類,例如:

點歌
許願
兒歌
德國兒歌
歐美歌

欄位最多可以儲存 30 個字元。

5. gbook_msg

`gbook_msg` varchar(200)
NOT NULL
COMMENT '發表內容',

儲存留言的主要內容,例如:

德布西 月光
綠袖子
小蜜蜂的兒歌
奇異恩典

最多可以儲存 200 個字元。

6. gbook_date

`gbook_date` timestamp
NOT NULL
DEFAULT CURRENT_TIMESTAMP
ON UPDATE CURRENT_TIMESTAMP
COMMENT '發表日期'

這是日期時間欄位。

它有兩個自動功能:

DEFAULT CURRENT_TIMESTAMP

新增資料時,如果沒有指定日期,就自動使用目前時間。

ON UPDATE CURRENT_TIMESTAMP

只要該筆資料被更新,這個欄位就會自動改成更新當下的時間。MySQL 5.7 支援這種 TIMESTAMP 自動初始化與自動更新設定。 dev.mysql

因此,這個欄位實際上比較接近:

最後修改時間

而不一定是單純的「建立時間」。

例如:

UPDATE gbook
SET gbook_msg = '德布西:月光'
WHERE gid = 2;

執行後,gid = 2gbook_date 也會自動更新。

7. 儲存引擎與編碼

) ENGINE=InnoDB
DEFAULT CHARSET=utf8mb4
COLLATE=utf8mb4_unicode_ci;

ENGINE=InnoDB

使用 InnoDB 儲存引擎,支援:

  • 交易。
  • COMMITROLLBACK
  • 主鍵。
  • 外鍵。
  • 較好的資料一致性。

DEFAULT CHARSET=utf8mb4

指定資料表預設使用 utf8mb4,適合繁體中文、日文與 Emoji。

COLLATE=utf8mb4_unicode_ci

指定文字比較與排序規則。

其中:

  • unicode:按照 Unicode 規則比較文字。
  • ci:case-insensitive,不區分英文字母大小寫。

四、插入留言資料

INSERT INTO `gbook`
(`gid`, `gbook_poser`, `gbook_kind`,
 `gbook_title`, `gbook_msg`, `gbook_date`)
VALUES
(...);

這段將資料加入 gbook 資料表。

例如第一筆:

(1, '學生', '初級', '點歌', '韋瓦第 春',
 '2026-02-01 05:15:28')

對應關係如下:

欄位
gid 1
gbook_poser 學生
gbook_kind 初級
gbook_title 點歌
gbook_msg 韋瓦第 春
gbook_date 2026-02-01 05:15:28

這份檔案共有 29 筆資料,gid129

例如:

(2, '學生', '初級', '許願', '德布西 月光', ...)

表示一位初級學生許願演奏德布西的〈月光〉。

(4, '學生', '初級', '許願', 'the entertainer😅', ...)

其中的 Emoji 能夠正常儲存,是因為資料庫與連線都使用 utf8mb4

五、設定主鍵

ALTER TABLE `gbook`
  ADD PRIMARY KEY (`gid`);

gid 設定為主鍵。

主鍵具有幾個特性:

  • 每筆資料必須有唯一的 gid
  • 不允許重複。
  • 不允許為 NULL
  • MySQL 可利用主鍵快速搜尋資料。

例如:

SELECT *
FROM gbook
WHERE gid = 2;

可以根據主鍵快速找到第二筆留言。

六、設定自動遞增

ALTER TABLE `gbook`
  MODIFY `gid` int(11)
  NOT NULL
  AUTO_INCREMENT
  COMMENT '主索引',
  AUTO_INCREMENT=30;

這段做兩件事。

1. 啟用 AUTO_INCREMENT

AUTO_INCREMENT

表示新增留言時,可以不必手動輸入 gid,MySQL 會自動產生編號。

例如:

INSERT INTO gbook
(gbook_poser, gbook_kind, gbook_title, gbook_msg)
VALUES
('學生', '初級', '許願', '卡農');

MySQL 會自動產生新的 gid

2. 設定下一個編號

AUTO_INCREMENT=30

表示下一筆自動新增的資料,預計使用 gid = 30

這是因為目前已有 129 的資料。MySQL 官方文件也使用 ALTER TABLE ... AUTO_INCREMENT = n 的方式設定下一個自動編號值。 dev.mysql

七、完成交易

COMMIT;

確認前面所有操作,正式寫入資料庫。

如果在 COMMIT 前執行:

ROLLBACK;

通常可以取消這次交易中的變更。

八、最後的設定還原

/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;

這幾行會將匯入前儲存的字元集與排序設定還原。

前面如果有:

SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT;

意思是先把原本的設定保存到變數中,最後再恢復。

九、這份資料表的功能

這張 gbook 表可以視為一個簡單的「留言、點歌或許願」資料表:

學生 → 發表分類 → 標題 → 內容 → 日期

例如:

學生身分 程度 類型 內容
學生 初級 點歌 奇異恩典
學生 初級 許願 綠袖子
學生 初級 兒歌 小毛驢

可以用以下 SQL 查詢所有留言:

SELECT *
FROM gbook
ORDER BY gid ASC;

查詢最新留言:

SELECT *
FROM gbook
ORDER BY gbook_date DESC;

查詢所有「許願」:

SELECT *
FROM gbook
WHERE gbook_title = '許願'
ORDER BY gbook_date DESC;

查詢「兒歌」相關內容:

SELECT *
FROM gbook
WHERE gbook_title LIKE '%兒歌%';

十、值得改進的地方

1. gbook_date 建議改名

目前它設定為:

DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

因此新增時是發表時間,但編輯留言後會變成修改時間。

如果你希望同時保存「建立時間」和「修改時間」,建議拆成兩個欄位:

`created_at` TIMESTAMP NOT NULL
  DEFAULT CURRENT_TIMESTAMP,

`updated_at` TIMESTAMP NOT NULL
  DEFAULT CURRENT_TIMESTAMP
  ON UPDATE CURRENT_TIMESTAMP

如此可以分別知道:

  • created_at:留言建立時間。
  • updated_at:留言最後修改時間。

2. gbook_poser 拼字可能需要確認

欄位名稱是:

gbook_poser

如果原本想表達「發表人」,英文通常會使用:

poster

因此較清楚的名稱可以是:

gbook_poster

但如果網站程式已經使用 gbook_poser,不建議直接改名,否則 PHP 或 Laravel 程式中的查詢可能會失效。

3. varchar(20) 是字元數,不是位元組數

utf8mb4 下,中文、日文與 Emoji 可能各佔用不同位元組,但 varchar(20) 主要表示最多 20 個字元,而不是只能放 20 bytes。

4. 時區要統一

SQL 檔案指定:

SET time_zone = "+00:00";

這是 UTC 時區。台灣時間是 UTC+8,所以在網站上顯示留言時間時,可能需要確認是否要轉換成台灣時間。

在 PHP 中常見設定方式是:

date_default_timezone_set('Asia/Taipei');

在 Laravel 中則通常於設定檔指定:

'timezone' => 'Asia/Taipei',

總結

這份 SQL 的核心作用是:

建立留言資料表
→ 匯入 29 筆學生點歌與許願資料
→ 將 gid 設為主鍵
→ 讓 gid 自動遞增
→ 設定中文、日文和 Emoji 編碼
→ 完成資料庫交易

其中最重要的設計是:

gid AUTO_INCREMENT PRIMARY KEY

以及:

gbook_date TIMESTAMP
DEFAULT CURRENT_TIMESTAMP
ON UPDATE CURRENT_TIMESTAMP

前者負責自動產生唯一編號,後者負責自動記錄新增與修改時間。

明天就是~MVC的程式碼嘍~


上一篇
鋼琴留言版的資料表
下一篇
鋼琴留言版的MODEL
系列文
Laravel 讀碼源22
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言