需求:用戶表 `member`、愛好表 `hobby`,一個用戶多愛好,查詢「某愛好下所有用戶」。
| 方案 | 結構 | 查詢「愛好=1 的用戶」 | 優點 | 缺點 |
|---|---|---|---|---|
| 字段存 CSV | `member.hobby_ids` = "1,3,5" | `WHERE FIND_IN_SET('1', hobby_ids)` | 單表、簡單 | 無索引、全表掃描、修改困難、無外鍵完整性 |
| 中間表 (推薦) | `member_hobby (member_id, hobby_id)` 雙主鍵 + 兩外鍵 | `SELECT m.* FROM member m JOIN member_hobby mh ON m.id=mh.member_id WHERE mh.hobby_id=1` | 索引高效、完整性約束、擴展屬性(創建時間/權重)、符合範式 | 多一張表、Join 開銷 |
CREATE TABLE member_hobby (
member_id INT NOT NULL,
hobby_id INT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (member_id, hobby_id),
FOREIGN KEY (member_id) REFERENCES member(id) ON DELETE CASCADE,
FOREIGN KEY (hobby_id) REFERENCES hobby(id) ON DELETE CASCADE
) ENGINE=InnoDB;
結論:**業務上「多對多」堅決用中間表**,CSV 字段僅適合極簡原型、唯讀、數據量極小 (<1000 行) 場景。