2010-04-08 66 views
3

我有三个数据库表:数据库设计:循环引用

  • 用户
  • 电子邮件
  • 邀请

电子邮件由USER_ID字段链接到用户。

请帖也用USER_ID领域

电子邮件可以不邀请来创建链接到用户,但每个邀请必须有电子邮件。

我想链接电子邮件和邀请表,因此可以找到特定邀请的电子邮件。

但是,这会创建一个循环引用,邀请和电子邮件记录都包含同一用户的ID。

这是不好的设计,如果是这样,我怎么能改善它?

我的感觉是,使用外键和良好的业务逻辑,这是好的。

users 
----- 
id 

emails 
------ 
id 
users_id 

invitations 
----------- 
id 
users_id 
emails_id 
+0

我认为如果您向我们展示您的表格模式的裸露骨骼会更好。 – satoru 2010-04-08 08:12:53

+0

基本上它会是这样的:

users ----- id emails ------ id users_id invitations ----------- id users_id emails_id 
SlappyTheFish 2010-04-08 08:18:40

+0

更好编辑额外的信息到问题中不在评论中。并使用反引号进行格式化。 – 2010-04-08 08:20:10

回答

2

这不是circular reference

这将是如果电子邮件将有一个强烈的诚信关系邀请和邀请一个独立的强大的完整性关系回电子邮件(例如)。

编辑:关于设计

随着亨克Holterman指出的问题是,如果你的设计是normalized到需要的程度。

Assiming 表:主键

用户:ID
电子邮件:ID,users_id
邀请:ID,users_id,emails_id

,并假设上的table_id领域外键没有其他限制放置在表上(例如,只有一部分密钥是唯一的),那么你已经建模如下:

  • 为每个用户可以有多个电子邮件,你不能有电子邮件没有相应的用户记录
  • 每个电子邮件可以有几个邀请,你不能有没有相应的电子邮件,也没有用户记录邀请(注:从上面的定义,我们可以不知道,如果USER_ID指进入在电子邮件或用户)

现在只有你可以说,如果这些规则对应于从现实世界的情况的,你正在尝试模拟。

查看数据库设计的一种方法是 - 实际上没有错误的数据库设计,您几乎总是可以找到可以使某些东西看起来像错误的数据。这就是为什么不采取两个规则(以句子形式)和表格(E-R图表,表格和关系的描述),不可能说设计中是否存在问题(尽管可以从个人经验中提出建议)。

为了说明 - 上面的说明不清楚user_id引用哪个表可能看起来很容易回答。考虑到你说每个邀请都有一封邮件,常见的答案就是它应该从邮件表中引用user_id。

否则,可能存在一个邀请,其中记录的邀请user_id和邮件记录的user_id不同。

通常情况下,这应该会让红色灯标记为“标准化数据”,闪烁在您的脑海中。但是,这里通常没有提到的假设是email_id决定了user_id,而这可能不是真的(!)。

这取决于数据的语义(每个表的谓词) - 例如,如果您试图模拟可以向一个人发送邀请并从另一个人接收电子邮件答复的情况人(例如通过秘书邀请人并接受直接回复),那么红灯熄灭,一切都很好 - 这就是真正发生的事情,这就是你在设计中允许的。

+0

好的,这是有道理的 - 所以从你的观点来看,这种设计是好的? – SlappyTheFish 2010-04-08 08:25:16

+0

谢谢 - 这是真的*有用的信息。 – SlappyTheFish 2010-04-08 10:14:22

1

我认为这里的合适的标准形式是让邀请有FK关系到电子邮件和给用户。我认为这样可以很好地工作。

在您的描述中,您声明邀请属于用户,但是从约束中可以更准确地说出邀请属于电子邮件。

另一方面,你是对的,同时邀请一个UserId和一个EmailId不会是一个大问题。它也不会有多大优势。

+0

从领域模型,但用户“有一个”邀请,用户“有一个“电子邮件和邀请”有一个“电子邮件 – SlappyTheFish 2010-04-08 08:26:31

1

每个邀请都必须有一封电子邮件,但可以在没有邀请的情况下创建电子邮件。好的 - 但是可以在没有用户的情况下创建电子邮件吗?

  • 如果邀请必须有电子邮件 和电子邮件也必须属于一个 用户,然后邀请是真的 相关的用户。在这种情况下,您的 当前数据模型正常,并且您的 不需要添加任何字段 - 您只需通过 用户标识加入电子邮件邀请。

  • 如果电子邮件可以存在没有用户, 然后他们是独立于 用户和邀请。在这种情况下,您应该在链接到“电子邮件”表的“用户”和“邀请” 中有一个“电子邮件ID”字段 。然而,在 这种情况下,您最终可能会收到 的情况,即用户有一封 电子邮件,并且他的邀请中含有单独(或重复)电子邮件的 。

1

电子邮件可以不邀请被创建,但每次邀请必须有电子邮件。

可以有多于1 invitationemail?如果不是,那么你的设计已经是错误的。

我想链接电子邮件和邀请表,因此可以找到特定邀请函的电子邮件。 但是,这会创建一个循环引用,邀请和电子邮件记录都包含同一用户的ID。

目前还不清楚(我)是否invitationuser_idemail同一user_id。如果是这样,那么它是多余的,并且是一种非正规化。删除它,并使用email作为您的链接表回到user_id。如果您需要高性能等,请在email.(id, user_id)(已唯一,因为id是您的主键)和跨两列的外键上创建unique constraint。这样就可以在不牺牲数据完整性的情况下实现非规范化。

如果这是一个不同user_id,那么你可能想改善你的命名。类似于invited_user_idemail.user_id变成email.sent_by_user_id

+0

每个邀请可以有多个电子邮件,例如提醒等。邀请中的user_id与电子邮件中的user_id相同。我这样做并不是为了表现,而是因为这是领域模型是如何的,并且用户和邀请之间有明确的关系 - 此外,发送邀请的方法可能在将来发生变化,例如,短信。 – SlappyTheFish 2010-04-08 11:56:04

1

我认为你对所有的答案都很好,我只是不会使用复数形式的表名。

这是令人困惑和不必要的。

我分享了关于不属于邀请表的user_id的意见,但是如果您真的确定要在user_id和email_id之间建立强有力的关联。

如果是这样,那么只需从邀请表中删除user_id,这是没用的。