先有鸡还是先有蛋:数据库中的相互依赖

   本小菜在设计数据库的时候,不幸遇到这样一个问题:

   数据库中有两个表,分别是小组表和成员表。其中小组表中有一个创建者字段,成员表中有一个所属组字段。

 


 

   看着挺符合逻辑的设计,却引发了一个哲学问题:先有鸡先有蛋?两个表形成了互相依赖。在数据库刚刚建成的时候,两个表中都没有数据,那么向任何一个表中插入数据都是失败的。

   出现问题就要马上解决,于是我便到网上搜索,找到这样一句话:“如果两表互有关联,则为多对多的关系,按照第三范式规定,建立第三个中间表,用于存储两表主键,关联时使用第三表的字段进行关联.”。按照这个规则所说的,建立两个中间表,用来存储组表的主键和成员表的主键(另一个表反之),然后用这两个中间表进行关联,这样可以完美解决这个问题。

 


 

   因为这两个中间表解除了组表和成员表直接的相互依赖,转化为了两个中间表对组表和成员表的依赖。这样看上去貌似不错,可是仔细观察一下会发现,在这个问题中并不是多对多的关系:一个组只有一个创建者,一个成员只能属于一个组。

   虽然可以用多对多的方法解决,但这并不是问题的根源。那么问题出在哪里呢?试想一下,假如我们要创建一个组,必须由人来创建,人的层次要高于组,而现在的设计人和组处于一个对等的层次上,这样显然是不合理的。之所以这样,是因为当初设计的时候,把所有的成员都放在一个表中,不分普通用户、操作员、管理员,这样就导致降低了管理员的层次,从实际情况分析,管理员应该是不属于某一组的。

 


 

   所以,要真正解决这个问题,必须把具有管理功能的角色与普通角色分开,管理角色在组的层次之上,没有所属组,但是有创建组的权限;而普通角色的层次在组之下,必须属于某一组,没有创建组的权限。这样就比较切合实际的解决了这个问题。需要说明的是,AdminMember表和NormalMember表只是代表权限分级域表,并不表示成员类型,比如AdminMember 表中可以放超级管理员、管理员、操作员等用户类型,在NormalMember表中可以有组员、组长、小组长等用户类型,在MemberAll表中应该还有TypeID字段,来标识成员的类型。因此,在设计数据库的时候,一定要分析表的层次结构,划分出明确的域,避免出现互相依赖这样的错误设计。

   即便是这样,个人感觉这个设计还不是很合理。可以看出,假如我们删除了某一个属于AdminMember表域的用户,那么这个用户所创建的组也会由于外键约束不得不删除。这在实际应用中显然是非常不合理的,这样会导致系统混乱不堪。

 


 

   因此,我认为虽然AdminMember表和Group表理论上有外键约束关系,但是实际设计数据库时不能加这个约束,我们只是为了记录一下组的创建者,进而提供一些参考,并没有严格的完整性要求,如果这个创建者不存在了,组应该还在。


  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值