首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MySQL 建表實戰:從 CREATE TABLE 到索引設計、字符集、引擎選型的完整決策指南

     編輯:MySQL 綜合教學

前言:建表即架構,一行 DDL 決定十年維護成本

CREATE TABLE 不只是定義欄位,更是資料型別、約束、索引、分區、字符集、引擎、壓縮、統計資訊的綜合決策。本文從實戰角度,構建「建表決策清單」,覆蓋 12 個關鍵決策點,附標準範本與反模式對照。

建表決策清單 12 項

#決策點核心原則推薦配置
1引擎預設 InnoDB,特殊場景才考慮其他ENGINE=InnoDB
2字符集全鏈路 utf8mb4,支援 Emoji/生僻字DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci
3主鍵業務無關、單調遞增、盡量小BIGINT UNSIGNED AUTO_INCREMENT / UUID v7 / 雪花算法
4欄位型別剛好夠用、拒絕 TEXT/BLOB 入主表參考「最小型別對照表」
5NOT NULL預設 NOT NULL,業務可空才允許 NULLNOT NULL DEFAULT '' / 0 / '1970-01-01'
6預設值業務預設值下推到資料庫層DEFAULT CURRENT_TIMESTAMP / DEFAULT 0
7索引策略查詢驅動建索引、複合索引最左前綴、覆蓋索引EXPLAIN 驗證每個慢查詢
8外鍵核心主檔硬約束、高併發明細軟約束參考「外鍵實戰」文章
9分區億級資料、時間序列、歸檔刪除RANGE BY YEAR/MONTH / LIST BY REGION
10壓縮歷史/唯讀/大字段表啟用ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8
11註釋每表每欄必寫,Data Dictionary 基石COMMENT='業務含義/單位/來源/範例'
12命名規範snake_case、單數名詞、無保留字、前綴隔離t_user, t_order_item, idx_user_phone

最小型別對照表(省空間=省 I/O=快)

業務場景推薦型別範圍/長度位元組
布林/開關TINYINT UNSIGNED0/11
狀態碼/枚舉(<256)TINYINT UNSIGNED0-2551
年齡/小整數SMALLINT UNSIGNED0-655352
ID/自增主鍵(<40億)INT UNSIGNED0-42億4
分散式 ID/大量資料BIGINT UNSIGNED0-1800京8
金額/精確小數DECIMAL(12,2)±999億.996
時間戳(秒級)TIMESTAMP1970-20384
日期時間(年-秒)DATETIME1000-99998
短字串(<255)VARCHAR(N)N+1/2 位元組變長
長文本/JSONTEXT/JSON64KB/4GB溢位頁

標準建表範本(電商訂單表)

CREATE TABLE `t_order` (
  `id`           BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '訂單ID,雪花算法生成',
  `order_no`     CHAR(32)        NOT NULL COMMENT '業務訂單號,唯一',
  `user_id`      BIGINT UNSIGNED NOT NULL COMMENT '下單用戶ID',
  `shop_id`      INT UNSIGNED    NOT NULL COMMENT '店鋪ID',
  `status`       TINYINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '狀態:0待付款 1已付款 2已發貨 3已完成 4已退款 5已取消',
  `total_amount` DECIMAL(12,2)   NOT NULL DEFAULT 0.00 COMMENT '訂單總金額(元)',
  `pay_amount`   DECIMAL(12,2)   NOT NULL DEFAULT 0.00 COMMENT '實付金額(元)',
  `pay_time`     DATETIME        NULL     COMMENT '支付時間',
  `created_at`   TIMESTAMP       NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '建立時間',
  `updated_at`   TIMESTAMP       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_shop_created` (`shop_id`, `created_at`),
  KEY `idx_deleted_at` (`deleted_at`)
) ENGINE=InnoDB 
  DEFAULT CHARSET=utf8mb4 
  COLLATE=utf8mb4_general_ci 
  COMMENT='訂單主表,支援軟刪除、多維查詢、分區擴展'
  ROW_FORMAT=DYNAMIC;  -- 8.0 預設,支援長欄位溢位

反模式對照:別這樣寫

反模式危害正確範例
用 INT 存手機號截斷前導 0、無法存 +86、數學運算無意義CHAR(11) / VARCHAR(20)
用 FLOAT 存金額精度丟失、對帳永遠不平DECIMAL(12,2)
主鍵用 UUID v4 (CHAR(36))隨機寫入導致 B+ 樹分裂、主鍵 36 字節、二級索引膨脹BIGINT 雪花 / UUID v7 (BINARY(16))
大字段放主表緩衝池污染、掃描慢、備份大拆分到獨立表 1:1 關聯
無 NOT NULL、無 DEFAULTNULL 語義模糊、應用層判斷不一、索引失效NOT NULL DEFAULT 业务默认值
索引建在低選擇性欄位性別/狀態/布林值索引幾乎不生效複合索引包含高選擇性欄位

驗證清單:建表後必跑

-- 1. 結構確認
SHOW CREATE TABLE t_order\G

-- 2. 索引確認
SHOW INDEX FROM t_order;

-- 3. 插入測試
INSERT INTO t_order (order_no, user_id, shop_id, status, total_amount, pay_amount) 
VALUES ('ORD202401010001', 1001, 2001, 1, 299.00, 299.00);

-- 4. 查詢計畫驗證
EXPLAIN SELECT * FROM t_order WHERE user_id=1001 AND status=1;
-- type=ref, key=idx_user_status, rows=1 → 完美

-- 5. 空間佔用
SELECT TABLE_NAME, DATA_LENGTH, INDEX_LENGTH, DATA_FREE 
FROM information_schema.TABLES WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='t_order';

結語

建表是一次性投資、長期收益的高杠桿動作。用「決策清單」強迫思考、「最小型別」省資源、「標準範本」落地規範、「反模式」避免踩坑、「驗證清單」確保品質。將建表標準化為團隊共識文檔、Code Review 必檢項、CI/CD 自動檢查規則,才能在規模增長時保持架構健康。

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