两个实体之间的关系

问题描述 投票:0回答:3

我有一个情况:

  1. 我有一个创建事件的用户(创建者)(每个事件属于一个用户)
  2. 每个事件都可以邀请其他用户(参与者)(每个用户属于一个事件)

基本上,有两个实体(用户和事件),但关系并不简单。我的意思是,创建活动的用户可能与参加活动的人不一样。用户可能只是参与者,但不是创建者。

情况类似于this

我意识到这些关系不只是多对多。

例如,我可以创建两个具有两个关系的表(循环关系)。为了打破这个圈子,我需要允许创建一个没有事件的用户(参与者),暂时为其分配NULL,或者创建一个指示该用户是否也是创建者的列(布尔值)。

但是我通过创建第三个表来解决它:

Diagram 1

第三个表存储事件及其参与者。

我还找到了解决这个问题的另一种方法。它涉及4个表:

  1. 用户(用户可以是创建者或参与者)
  2. 创建者(创建者是创建事件的用户)
  3. 事件(每个事件属于一个创建者)
  4. 参与者(参与者是参加活动的用户,一个活动有很多参与者)

这些关系看起来像这样:

Diagram 2

哪种解决方案更好?

我喜欢有两张桌子的那张,但我只需要深入挖掘并找到合适的。

sql relationships entities
3个回答
2
投票

我坚持使用三个表的解决方案,因为事件总是由一个用户创建。 EventMember表解决了UserEvent之间的n:m关系,是必要的。

介绍第四张表Creator真的没有意义,因为它只增加了一个JOIN来获得一个事件的创建者。


1
投票

规则如最初所述

创建活动的用户可能与参加活动的用户不同。用户可能只是参与者,但不是创建者。

这似乎表明,对于每个事件,给定用户可以是参与者或创建者,但不是两者。

但是,在评论中,OP后来表示:

用户可以是参与者,创建者或两者。

以下代码基于先前的假设(正如我在评论中明确指出的那样);适应后来澄清的唯一调整是放弃CHECK约束:

-- Rule: for each event, a given user may be an attendee or a creator but not both.
-- Rule: each event has zero or one creator.
-- Rule: each event has zero, one or many attendees.
-- General Rule: a table models an entity or a relationship but never both.

CREATE TABLE Users 
(
 user_name VARCHAR(20) NOT NULL, 
 UNIQUE (user_name)
);

CREATE TABLE Events 
(
 event_name VARCHAR(30) NOT NULL, 
 UNIQUE (event_name)
);

CREATE TABLE EventCreators 
(
 event_name VARCHAR(30) NOT NULL,
 creator_user_name VARCHAR(20) NOT NULL, 
 UNIQUE (event_name),  
 UNIQUE (event_name, creator_user_name),
 FOREIGN KEY (event_name) 
    REFERENCES Events (event_name), 
 FOREIGN KEY (creator_user_name) 
    REFERENCES Users (user_name)    
);

CREATE TABLE EventAttendees
(
 event_name VARCHAR(30) NOT NULL,
 creator_user_name VARCHAR(20) NOT NULL,
 attendee_user_name VARCHAR(20) NOT NULL,
 UNIQUE (event_name, attendee_user_name),  
 FOREIGN KEY (event_name, creator_user_name) 
    REFERENCES EventCreators (event_name, creator_user_name), 
 FOREIGN KEY (attendee_user_name) 
    REFERENCES Users (user_name), 
 CHECK (creator_user_name <> attendee_user_name)
);

0
投票

我这样做:

3张桌子(就像多对多)

表1:用户

表2:Users_Events

表3:事件

表2将包含: - 表1中的FK

  • 表3中的FK
  • 作为关系性质的属性(组织者或参加者)...这可以转换为关系表,然后表2将包含该表的FK
  • 关系发起的日期(在某些时候你肯定需要:))

因此,如果我们说Bob今天创建了一个活动,并且明天将Sarah和John添加为与会者,那么您将拥有(第一列是表1和2的PK):

表1 1 - Bob 2 - Sarah 3 - John

表2 1 - A - 组织者 - 05.01.2012 2 - A - 参加者 - 06.01.2012 3 - A - 参加者 - 06.01.2012

表3 A - 超级新事件

如果你想让Bob参加会议,那么必须在表2中创建一个新记录1 - A - 参加者 - 06.01.2012

然后,如果您需要参与活动A,则需要加入表1 2和3并在table_2上过滤“Attendee”

为了避免在组织者参加的情况下双重输入,您可以通过这种方式获得表2:

表2将包含: - 表1中的FK - 表3中的FK - 参加者(布尔) - 组织者(布尔)

这更加灵活,例如,如果您以后需要跟踪谁将在会议中发表演讲,您可以在不破坏表格的情况下引入新的列播放器。如果您预见到许多角色,那么这将无法扩展

© www.soinside.com 2019 - 2024. All rights reserved.