【我的博客: http://www.80soho.com/?p=328】
功能開發中確定遇到過下列狀況:
以下表,最初的設計產品(product_id)與聯繫人(account_id)是一對一關係,後期產品經理過來找到你說,產品能夠對應多個聯繫人(我會拎磚頭砸過去,違法勿學),一個彷佛簡單且合理的解決方案能夠快速解決需求變動:account_id,由int改爲使用逗號分隔的字符串(曾經這麼幹過的確定不在少數...)。
一般使用逗號分隔的列表來避免在多對多的關係中建立交叉表,這種設計方案定義爲一種反模式,暫叫亂穿馬路正則表達式
這樣的設計彷佛可行,由於沒有建立額外的表或者列,僅僅改變了一個字段的數據類型。咱們來看一下這樣的設計所必須承受的各方面問題:函數
當保存的長度超出varchar(100)時,確定會出問題,varchar(100)不得不被修改,下次修改只是時間問題,少不了;性能
查詢不能再使用等號,沒法享受索引帶來的性能優點,變得異常困難,eg:spa
聯合兩張表並使用如上的一句表達式將毀掉任何使用索引的可能,這樣的查詢必須掃描兩張表,建立一個交叉結果集,而後使用正則表達式遍歷每一行聯合後的數據進行匹配。設計
聚合查詢使用內置的聚合函數,這些函數是針對分組行而設計的,並非爲了逗號分隔的列表。下圖方法看上去很高明,單不清晰,且須要很長的時間來開發和調試,況且有些聚合查詢根本沒法使用這些技巧來完成。調試
建立一張交叉表:將account_id存儲在一張單獨的表中,而不是存儲在產品表(jw_products)中,從而每一個獨立的account值均可以佔據一行,來實現產品和聯繫人的多對多關係。索引
以上內容是tonglei參考《SQL反模式》於2017-10-10寫下!