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

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

本小菜在设计数据库的时候,不幸遇到这样一个问题:51Testing软件测试网't KzH3i J.uc

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

2A-d;K3{ ]1D0

51Testing软件测试网{6gXt|R2V `"O|&R

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

5P I+h"K2wbm9^0

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

h/Hzu1ZT@H Xy0

;a^&P"a$]8K0

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

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

X[.k j7\ SW;j:l0

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

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

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

TAG:

 

评分:0

我来说两句

Open Toolbar