首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

MySQL 外鍵字段存儲逗號分隔值時的關聯查詢解決方案

     編輯:程式設計綜合問答

問題場景

表 2 的外鍵字段 表1外鍵 存儲逗號分隔的多個 ID(如 '1,2'、'2,3'),導致無法直接使用標準 INNER JOIN ... ON 表1.id = 表2.表1外鍵 進行關聯查詢。

為什麼 LIKE 不可靠?

若用 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 過渡,並規劃遷移計劃。

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