资讯专栏INFORMATION COLUMN

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

CNZPH / 905人阅读

摘要:通常使用逗号分隔的列表来避免在多对多的关系中创建交叉表,这种设计方案定义为一种反模式,暂叫乱穿马路问题这样的设计似乎可行,因为没有创建额外的表或者列,仅仅改变了一个字段的数据类型。以上内容是参考反模式于写下

【个人博客:http://www.80soho.com/?p=328】
场景

功能开发中肯定遇到过下列情况:
如下表,最初的设计产品(product_id)与联系人(account_id)是一对一关系,后期产品经理过来找到你说,产品可以对应多个联系人(我会拎砖头砸过去,违法勿学),一个似乎简单且合理的解决方案可以快速解决需求变更:account_id,由int改成使用逗号分隔的字符串(曾经这么干过的肯定不在少数...)。



通常使用逗号分隔的列表来避免在多对多的关系中创建交叉表,这种设计方案定义为一种反模式,暂叫乱穿马路

问题

这样的设计似乎可行,因为没有创建额外的表或者列,仅仅改变了一个字段的数据类型。我们来看一下这样的设计所必须承受的各方面问题:

字段类型长度不能保证不修改

当保存的长度超出varchar(100)时,肯定会出问题,varchar(100)不得不被修改,下次修改只是时间问题,少不了;

查询制定联系人的产品

查询不能再使用等号,无法享受索引带来的性能优势,变得异常困难,eg:

查询制定产品的联系人

联合两张表并使用如上的一句表达式将毁掉任何使用索引的可能,这样的查询必须扫描两张表,创建一个交叉结果集,然后使用正则表达式遍历每一行联合后的数据进行匹配。

执行聚合查询

聚合查询使用内置的聚合函数,这些函数是针对分组行而设计的,并不是为了逗号分隔的列表。下图方法看上去很高明,单不清晰,且需要很长的时间来开发和调试,何况有些聚合查询根本无法使用这些技巧来完成。

更新指定产品的联系人繁琐

无法验证产品ID

选择合适的分隔符

列表长度限制

解决方案

创建一张交叉表:将account_id存储在一张多带带的表中,而不是存储在产品表(jw_products)中,从而每个独立的account值都可以占据一行,来实现产品和联系人的多对多关系。




以上内容是tonglei参考《SQL反模式》于2017-10-10写下!

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/30622.html

相关文章

  • 设计模式遍---观察者模式

    摘要:观察者模式的别名包括发布订阅模式模型视图模式源监听器模式或从属者模式。而观察者一般也会做出对象的响应观察者模式属于行为型模式观察者模式主要解决的问题一方的状态发生了变化,依赖于这一方的观察者立即能收到通知。参考书籍设计模式版。 1 红灯车过,人停;绿灯人过,车停。每天走在马路上,到处可见红绿灯指挥着我们什么时候可以过马路,什么时候不能过马路。无论是人还是车,都时刻关注着红绿灯的状态,一...

    justCoding 评论0 收藏0
  • 为什么说ORM是模式

    摘要:什么是反模式我很高兴地发现有一个相当全面的关于反模式的列表,包括来自编程界及其之外的内容。但是要作为一个反模式,还需要存在替代的解决办法。 上周我在twitter上讨论了ORM,在那以后有人希望我澄清一下。事实上,我曾经写文章讨论过ORM, 但那是时的上下文是关于SQL的,我不应该把这将两件事情混为一谈。 showImg(http://segmentfault.com/img/bVb...

    PingCAP 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<