首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL 資料型別與欄位約束完整指南:數值、字串、時間、空間型別選型、主鍵/外鍵/索引/自增/非空/唯一約束實戰

     編輯:MySQL 資料庫相關知識

前言

正確選擇資料型別與約束,是資料庫設計的基石,直接影響儲存空間、查詢效能、資料完整性與應用層開發體驗。本文系統整理 MySQL 8.0 主流型別分類、儲存範圍、適用場景、常見誤區,並詳細說明主鍵、外鍵、索引、自增、非空、唯一、預設值、CHECK 約束的語法與最佳實踐。

一、數值型別

型別儲存位元組有號範圍無號範圍適用場景
TINYINT1-128 ~ 1270 ~ 255布爾旗標、狀態碼、極小計數
SMALLINT2-32,768 ~ 32,7670 ~ 65,535小範圍計數、年齡、郵遞區號
MEDIUMINT3-8,388,608 ~ 8,388,6070 ~ 16,777,215中等計數、IPv4 整數存儲
INT / INTEGER4-2,147,483,648 ~ 2,147,483,6470 ~ 4,294,967,295**主鍵首選**、通用計數、外鍵
BIGINT8-9.22e18 ~ 9.22e180 ~ 1.84e19極大主鍵 (分散式 ID)、毫秒時間戳
DECIMAL(M,D)M+2 近似精確定點數-**金額、價格、匯率** (不可用 FLOAT/DOUBLE)
FLOAT4單精度浮點-科學計算、不需精確的測量值
DOUBLE8雙精度浮點-同上,精度更高
BIT(M)~M/8位元向量-權限位圖、特徵向量

關鍵提醒

  • INT(11) 中的 11 僅為**顯示寬度**,不影響儲存範圍,**請忽略**。
  • **主鍵建議 BIGINT UNSIGNED AUTO_INCREMENT** (配合雪花演算法或自增)。
  • 金額**嚴禁**用 FLOAT/DOUBLE,務必 DECIMAL(19,4) 或 DECIMAL(27,8) (加密貨幣)。

二、字串型別

型別最大長度儲存方式適用場景
CHAR(N)255 字元定長,右補空格固定長度代碼 (ISO 國別碼、MD5、UUID 去連字號)
VARCHAR(N)65,535 字元 (共享 64KB 行上限)變長,1-2 字節長度前綴 + 內容**通用變長字串** (姓名、郵件、地址、JSON 片段)
TINYTEXT255 字元溢位頁極短文本
TEXT64 KB溢位頁文章內容、日誌
MEDIUMTEXT16 MB溢位頁長文本
LONGTEXT4 GB溢位頁超長文本、完整 JSON 文檔
BINARY/VARBINARY同 CHAR/VARCHAR位元組串加密資料、檔案雜湊、二進制協議
BLOB 系列同 TEXT 系列二進制大物件圖片、檔案 (建議存物件儲存,DB 存路徑)
ENUM65,535 成員1-2 字節索引固定值集合 (狀態: 'pending','paid','cancelled')
SET64 成員位元組位圖多選標籤 (tags: 'tech','life','sport')

CHAR vs VARCHAR 選型原則

  • 長度固定、頻繁更新 → CHAR (避免行遷移)。
  • 長度變動、平均長度遠小於最大 → VARCHAR (節省空間)。
  • VARCHAR(255) 仍用 1 字節長度前綴;VARCHAR(256+) 用 2 字節。

三、時間日期型別

型別儲存位元組範圍精度時區感知適用場景
DATE31000-01-01 ~ 9999-12-31天否生日、發文日期、報表維度
TIME3-838:59:59 ~ 838:59:59秒否每日排程、工時
DATETIME5-81000-01-01 00:00:00 ~ 9999-12-31 23:59:59.999999微秒否 (儲存本地時間)**業務時間、訂單建立時間** (不隨時區變)
TIMESTAMP4-71970-01-01 00:00:01 UTC ~ 2038-01-19 03:14:07 UTC微秒**是** (儲存 UTC,讀取轉 session 時區)**修改時間戳 updated_at**、跨時區系統
YEAR11901 ~ 2155年否年份維度

DATETIME vs TIMESTAMP 選型決策

需要 2038 年後支援? → DATETIME
需要自動時區轉換? → TIMESTAMP
業務語意為「本地牆鐘時間」? → DATETIME
業務語意為「絕對時間點」? → TIMESTAMP
索引範圍查詢頻繁? → 兩者皆可,DATETIME 範圍更大

四、空間與 JSON 型別 (MySQL 5.7+)

  • GEOMETRY、POINT、LINESTRING、POLYGON 等空間型別,支援 SPATIAL INDEX (R-tree),適用 LBS、GIS。
  • JSON 型別:二進制儲存、支援路徑查詢 (->, ->>)、虛擬欄位索引、JSON_TABLE (8.0) 關聯查詢。

五、欄位約束

5.1 主鍵

CREATE TABLE t (
    id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
    PRIMARY KEY (id)
);
  • 隱含 NOT NULL + UNIQUE。
  • InnoDB 聚簇索引即主鍵,**務必單調遞增** (自增或雪花)。

5.2 外鍵

ALTER TABLE orders
ADD CONSTRAINT fk_orders_user
FOREIGN KEY (user_id) REFERENCES user(id)
ON DELETE RESTRICT ON UPDATE CASCADE;
  • ON DELETE: RESTRICT (預設阻止)、CASCADE (級聯刪除)、SET NULL (需欄位可空)。
  • **高併發核心業務建議應用層維護關聯**,關閉外鍵 (減少鎖爭用、死鎖、備份恢復複雜度)。

5.3 索引

-- 普通索引
KEY idx_status (status)
-- 唯一索引
UNIQUE KEY uk_email (email)
-- 複合索引 (最左前綴)
KEY idx_status_created (status, created_at)
-- 全文索引 (中文需 ngram parser)
FULLTEXT KEY ft_content (content) WITH PARSER ngram

5.4 自增

  • AUTO_INCREMENT 僅限整數型別,每表一個。
  • innodb_autoinc_lock_mode=2 (interleaved, 8.0 預設) 高併發插入效能最佳。
  • 手動指定值會重置計數器:INSERT ... VALUES (100, ...) → 下次自增 101。

5.5 非空與預設值

status TINYINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '0:草稿 1:發布 2:下架',
email VARCHAR(128) NOT NULL DEFAULT '' COMMENT '空字串而非 NULL',
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

5.6 唯一約束

  • UNIQUE KEY uk_xxx (col) 允許一個 NULL (多個 NULL 不視為重複)。
  • 業務主鍵 (如 email、手機) 必須加唯一索引。

5.7 CHECK 約束 (MySQL 8.0.16+)

price DECIMAL(19,4) NOT NULL CHECK (price >= 0),
status TINYINT NOT NULL CHECK (status IN (0,1,2)),
CHECK (end_at > start_at)

六、完整建表範例:訂單表

CREATE TABLE `order` (
    `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '訂單ID',
    `order_no` CHAR(32) NOT NULL COMMENT '訂單號 (UUID無連字號)',
    `user_id` BIGINT UNSIGNED NOT NULL COMMENT '下單用戶',
    `total_amount` DECIMAL(19,4) NOT NULL DEFAULT 0.0000 CHECK (`total_amount` >= 0) COMMENT '訂單金額',
    `status` TINYINT UNSIGNED NOT NULL DEFAULT 0 CHECK (`status` IN (0,1,2,3,4)) COMMENT '0待付款 1已付款 2已發貨 3已完成 4已取消',
    `pay_at` DATETIME NULL COMMENT '支付時間',
    `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '建立時間',
    `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新時間',
    `deleted_at` DATETIME NULL COMMENT '軟刪除時間',
    PRIMARY KEY (`id`),
    UNIQUE KEY `uk_order_no` (`order_no`),
    KEY `idx_user_status` (`user_id`, `status`),
    KEY `idx_created_at` (`created_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='訂單表';

結語: 型別選型原則:**「夠用就好、越小越好、語意精確」**。約束設計原則:**「資料完整性由資料庫守護、業務邏輯由應用層守護」**。定期用 pt-table-checksum 驗證主從一致性,用 EXPLAIN 驗證索引覆蓋,讓 Schema 成為系統穩健演進的基石。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved