Отношения между двумя сущностями - PullRequest
0 голосов
/ 05 января 2012

У меня есть ситуация:

  1. У меня есть пользователь (создатель), который создает события (каждое событие принадлежит одному пользователю)
  2. Каждое событие может приглашать других пользователей (участников) (каждому пользователю принадлежит одно событие)

Итак, в основном, есть две сущности (пользователи и события), но отношения не простые. Я имею в виду, что пользователь, который создает событие, может быть не тем, кто его посещает. Пользователь может быть просто участником, но не создателем.

Ситуация похожа на это .

Я понял, что эти отношения не просто многие ко многим.

Например, я могу создать две таблицы с двумя отношениями (круговые отношения). Чтобы разорвать этот круг, мне нужно разрешить создать пользователя (участника) без события, временно назначив ему NULL или создав еще один столбец (логический), который указывает, является ли этот пользователь также создателем или нет.

Но я решил это, создав третью таблицу:

enter image description here

Диаграмма 1

В третьей таблице хранятся события и их участники.

Я также нашел другой способ решения этой проблемы. Включает 4 таблицы:

  1. Пользователь (пользователь может быть как создателем, так и участником)

  2. Создатель (Создатель - это пользователь, создающий событие)

  3. Событие (Каждое событие принадлежит одному создателю)

  4. Участник (участник - это пользователь, который принимает участие в мероприятии, в одном событии много участников)

Эти отношения будут выглядеть так:

enter image description here

Диаграмма 2

Какое решение лучше?

Мне понравился тот с двумя столами, но мне просто нужно было покопаться глубже и найти подходящий.

Ответы [ 3 ]

2 голосов
/ 05 января 2012

Я бы придерживался решения с тремя таблицами, так как событие всегда создается одним пользователем.Таблица EventMember решает соотношение n: m между User и Event и является необходимой.

Представление четвертой таблицы Creator не имеет никакого смысла, так как добавляет еще одного JOIN, чтобы получить создателя события.

1 голос
/ 05 января 2012

Правило, как было первоначально указано

Пользователь, который создает событие, может быть не тем, кто его посещает.Пользователь может быть просто участником, но не создателем.

Это указывает на то, что для каждого события данный пользователь может быть участником или создателем, но не обоими.

Однако в комментариях ОП позднее указывалось:

пользователь может быть участником, создателем или и тем, и другим.

Следующий код основан на более раннем предположении(как я пояснил в комментариях);единственная корректировка с учетом последующего разъяснения - это снять ограничение 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 голосов
/ 05 января 2012

Я бы сделал это так:

3 таблицы (как много ко многим)

Таблица 1: Пользователи

Таблица 2: Пользователи_События

Таблица 3: События

Таблица 2 будет содержать: - ФК из таблицы 1

  • FK из таблицы 3

  • Атрибут, который является природой отношения (организатор или посетитель) ... его можно превратить в таблицу отношений, а затем таблица 2 будет содержать FK для этой таблицы вместо

  • дата, когда было инициировано отношение (это обязательно понадобится в какой-то момент :))

Так что, если мы скажем, что Боб создает событие сегодня, и что Сара и Джон будут добавлены завтра как участники, у вас получится (первый столбец - PK для таблиц 1 и 2):

Таблица 1 1 - Боб 2 - Сара 3 - Джон

Таблица 2 1 - A - Организатор - 05.01.2012 2 - A - Участник - 06.01.2012 3 - A - Участник - 06.01.2012

Таблица 3 A - Супер новое событие

если вы хотите, чтобы Боб присутствовал на собрании, то в таблице 2 должна быть создана новая запись 1 - A - Участник - 06.01.2012

Тогда, если вам нужны участники на мероприятии A, вам нужно присоединиться к таблицам 1, 2 и 3 и отфильтровать в table_2 значение "Attendee"

Чтобы избежать двойной записи в случае участия организатора, вы можете просто иметь таблицу 2 следующим образом:

Таблица 2 будет содержать: - ФК из Таблицы 1 - ФК из Таблицы 3 - Посетитель (булево) - Органайзер (логическое)

Это еще более гибко, и, например, если вам позже понадобится отслеживать, кто выступит с речью на собрании, вы можете ввести новую колонку «Динамик», не разбивая свой стол. Если вы предвидите много ролей, это не будет масштабируемым, однако

...