表 2 的外鍵字段 表1外鍵 存儲逗號分隔的多個 ID(如 '1,2'、'2,3'),導致無法直接使用標準 INNER JOIN ... ON 表1.id = 表2.表1外鍵 進行關聯查詢。
若用 WHERE 表2.外鍵 LIKE '%1%',ID 為 11、21、31 的記錄也會被誤匹配,產生嚴重數據錯誤。
建立中間關聯表,將多對多關係拆解為兩個一對多:
CREATE TABLE rel_table1_table2 (
table1_id BIGINT NOT NULL,
table2_id BIGINT NOT NULL,
PRIMARY KEY (table1_id, table2_id),
FOREIGN KEY (table1_id) REFERENCES table1(id),
FOREIGN KEY (table2_id) REFERENCES table2(id)
);
查詢時:
SELECT t1.*, t2.*
FROM table1 t1
JOIN rel_table1_table2 r ON t1.id = r.table1_id
JOIN table2 t2 ON t2.id = r.table2_id;
若無法修改表結構,可使用 FIND_IN_SET() 函數(MySQL 專用):
SELECT t1.*, t2.*
FROM table1 t1
JOIN table2 t2 ON FIND_IN_SET(t1.id, t2.表1外鍵) > 0;
缺點:無法使用索引,全表掃描,數據量大時性能極差;FIND_IN_SET 不支援參數化預編譯,存在注入風險。
「逗號分隔存外鍵」屬於嚴重的反模式(違反第一範式)。務必在設計階段建立關聯表;若接手舊系統,優先重構數據模型,實在不行再用 FIND_IN_SET 過渡,並規劃遷移計劃。