当前位置: 首页 > 后端技术 > PHP

sql反模式(一)——乱穿马路

时间:2023-03-30 06:13:16 PHP

【个人博客:http://www.80soho.com/?p=328】场景功能开发中肯定遇到过以下几种情况:下表,初始设计产品(product_id)和联系人(account_id)是一对一的关系。后来产品经理来找你,说产品可以对应多个联系人(我拿砖砸,别学违规了),看似简单合理。解决方案可以快速解决需求变更:account_id,由int改为逗号分隔的字符串(之前肯定有很多人这样做过。。。)。逗号分隔的列表通常用于避免在多对多关系中创建交叉表。这种设计被定义为一种反模式,暂称为乱穿马路问题。这样的设计似乎可行,因为没有创建额外的表或列。,只改变一个字段的数据类型。我们来看看这样的设计必须承受的各种问题:字段类型的长度不能保证不被修改。当保存的长度超过varchar(100)时,肯定会出问题,必须修改varchar(100)。接下来的修改只是时间问题,缺一不可;查询指定联系人的产品查询不能再使用等号,无法享受索引带来的性能优势,变得异常困难。例如:查询指定产品的联系人合并了两个表,使用上面的语句表达式会破坏任何使用索引的可能性。这样的查询必须扫描两个表,创建一个相交的结果集,然后使用正则表达式迭代组合数据以匹配每一行。执行聚合查询聚合查询使用内置的聚合函数来对行进行分组,而不是逗号分隔的列表。下图的方法看起来很巧妙,但并不清晰,而且开发和调试都需要很长时间,更何况有些聚合查询根本无法使用这些技术来完成。更新具体产品的联系方式很麻烦无法验证产品ID选择合适的分隔符列表长度限制解决方案创建交叉表:将account_id存储在单独的表中,而不是存储在产品表(jw_products)中,这样每个单独的账户值可以占据一行来实现产品和联系人之间的多对多关系。以上内容由同雷于2017-10-10参考《SQL反模式》撰写!