需求:訂單編號格式為「年份後兩位 + 月份 + 日期 + 三位流水號」(如 240115001)。自增 ID 無法直接滿足,因為其為單純數字遞增,不含日期資訊,且流水號需每日歸零。
方案一:日期時間 + 用戶 ID(最佳回答建議)
格式:YYMMDDHHIISS + userId。優點:全域唯一、無需額外表維護流水號、高併發下極低衝突率。缺點:長度較長、不直觀。
方案二:單獨流水號表(嚴格符合格式)
CREATE TABLE order_seq (
seq_date DATE PRIMARY KEY,
seq_no INT NOT NULL DEFAULT 0
);
-- 獲取下一個訂單號(需事務 + 行鎖)
START TRANSACTION;
SELECT seq_no FROM order_seq WHERE seq_date = CURDATE() FOR UPDATE;
UPDATE order_seq SET seq_no = seq_no + 1 WHERE seq_date = CURDATE();
-- 拼接:DATE_FORMAT(NOW(),'%y%m%d') + LPAD(seq_no, 3, '0')
COMMIT;
| 方案 | 優點 | 缺點 |
|---|---|---|
| 日期時間+用戶ID | 簡單、高效、無鎖 | 格式不符、長度長 |
| 流水號表 | 格式完全符合、可控 | 需行鎖、高併發可能成瓶頸 |
| Redis INCR | 高效能、原子操作 | 引入外部依賴、需持久化備份 |
實務中若非強制業務規範,推薦方案一;若必須符合特定格式,方案二配合 Redis 緩存流水號可平衡效能與一致性。