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

上一篇 / 下一篇  2012-05-22 09:41:10 / 个人分类:数据库

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

%D2ed@z$ps:G0  数据库中有两个表,分别是小组表和成员表。其中小组表中有一个创建者字段,成员表中有一个所属组字段。51Testing软件测试网)^1au[V+mOcm

Gv+R{_0

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

,Gi@@a7E0

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

J+o_5n;PTC+iM#?0

z3z8rZ;q:f0

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

T7qk;U3E0

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

[%?'N Gu(^v+TB7k0

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

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

B[ \;Pv A-}7t3|0

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

TAG:

 

评分:0

我来说两句

Open Toolbar