【我的博客: 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写下!