《SQL 反模式》阅读笔记一

1:乱穿马路

 
反模式:
一对多、多对多的表 一列里存储多个外键ID,以','隔开。如 
|id     |  content      |     tag_ids |
|1      |    abcaeag   |     id1,id2,id3|
 
缺点:
     1:不好查询。比如:查询该记录是否引用某个外键ID
     2:不好更新,由于不好查,所以不好更新
 
解决方案:
     使用关联表,通过外键来建立一对多关系。
 
 
2:树结构
 
反模式:使用parent_id来构建一个树或森林
 
缺点:
     *无法知道树的深度
     *查询某个树的所有的子树相当的费劲
 
解决方案:
     1:路径枚举,也可以叫做前缀编码。如#1#11#112#1124。
     2:闭包:建立关联结构:1>1,1>11,1>112,1>1124;11>11,11>112,11>1124;112>112,112>1124>1124>1124.  
 
个人理解:
第一种方法比较容易接受、推广、实现。
 
 
3:表的主键
反模式:很多开发人员会根据“传统”给表建立名为id,类型为int 或者 bigint的 自增ID
缺点:可能存在更加合理的业务主键
 
 
个人理解:
     1:核心的几个表一定要有业务主键,比如订单相关的表,用订单号order_no关联
     2:mysql由于btree索引的问题;如果能保证业务主键基本是递增的,不会引起bree频繁的“平衡”,则只需业务主键。
否则还是需要传统意义上的ID主键,当然这个ID主键只是为了保证btree的稳定,业务关联还是使用业务主键。
大多数情况下,传统意义的ID还是需要的。
     3:传统ID主键的另外一个问题:在做数据迁移的时候,很容易导致id错误。 业务主键能完全避免掉。
 
 
4:外键约束
反模式:不是关联的表建立外键,不使用强约束。
解决:
     1:对数据列使用强类型约束
     2:对关联表使用外键约束,使用on update cascade or on delete cascade 来级联删除对应的记录
 
个人理解
     1:对数据列必须要强类型约束
     2:可以使用外键约束,也可以不实用。统一即可。最好能使用约束。
 
5:泛化类型
反模式:存在拓展列而使用行表。即 key-value的方式,key作为属性类型,value做为属性的具体值。
缺点:
     1:列没有强类型限制,只能设置为varchar. 完全违反了关系。
     2:表关联查询效率低下
 
 
解决:
     一般出现这些情况,是因为有不同的子类型,完全可以按以下的方式解决
     1: 单表继承:所有的子类型都使用同一个张表
          缺点:无法从数据库区分哪列是属于哪个子类型
          好处:可以通过同一个DAO将数据全部取出来,编程相对简单
 
     2:单独表:每个子类型都使用单独的一张表
          缺点:无法将通用属性和子类特有属性区分,且以来公共属性来查询所有子类型时,比较复杂。
          好处:各表各业务隔离开,只考虑子类型特有的业务场景
     
     3:父子表:类似于类继承。将公共属性抽取成父表,子类特殊的业务属性放在子表中
          缺点:实现相对复杂了点。 当子类型特定属性 升级 为 公共属性 或者 公共数据要区分子类型时要对表和代码进行迁移
          好处:查询非常方便,效率也比较高。
 
个人理解:建议使用父子表。当前接手的系统使用的单独表;往往有需求要根据公共属性进行查询所有的表。
 
6: 多态关联
反模式:一个实体E可能属于A实体,也可能属于B实体。 这个实体用一个表存储
缺点:这个实体的引用ID,无法明确,因为它既可能是A的也可能是B的
好处:可以支持多个类型
 
解决方式:
     1:如果A和B是 单独表,则分别对A和B 建立交叉表
     2:如果A和B 是继承于某个父表,则建立父表和T之间的关系即可
 
个人理解:
     这里需要和5一起理解。 
     实际上遇到:
               两种业务的订单,大部分字段一样,使用两个表存储订单数据,即5中的“单独表”设计。而这两个订单都有相同的第三方接口通讯(比如;支付,退款)等。
               这样的话,这两个订单通过“父子表‘建模,再建立父表和 第三方接口之间的关联是比较合理的。
 
 
                    
 
 

posted on 2013-03-29 01:20  NanguoCoffee  阅读(284)  评论(0编辑  收藏  举报

导航