2012-01-05 3 views
0

У меня ситуация:Отношения между двумя сущностями

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

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

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

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

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

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

enter image description here

Diagram 1

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

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

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

  2. Creator (Создатель пользователь, который создает событие)

  3. события (каждое событие принадлежит одному создатель)

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

Эти отношения будут выглядеть следующим образом:

enter image description here

Diagram 2

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

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

+1

Что касается правила 2: «Каждый пользователь принадлежит к одному событию» - это дословный перевод был бы, что пользователь не может существовать в базах данных, если они связаны только с одним событием, никогда не могут ассоциироваться с более чем одним событием, и когда они отключаются от этого события, пользователь перестает существовать в базе данных. Это правильная интерпретация? – onedaywhen

+0

Сначала вы говорите: «пользователь создает события», но позже говорит: «Пользователь может быть просто участником, но не создателем». Я думаю, вам нужно разобраться в своих правилах! – onedaywhen

+0

Да, вы правы. Это мой английский, извините. Пользователь не обязательно должен принадлежать к событию. И пользователь может быть участником, создателем или обоими. – Alisher

ответ

2

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

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

+0

Вы не указали правило: «пользователь, создающий событие, может быть не тем, кто его посещает». – onedaywhen

+0

@onedaywhen, конечно, я сделал. Создатель автоматически не вставлен в таблицу «EventMember» и поэтому не посещает его по умолчанию. – Matten

+1

Игнорировать: правило было сформулировано тремя способами и противоречивыми, поэтому я не могу сказать, кто прав;) – onedaywhen

0

Я хотел бы сделать это следующим образом:

3 таблицы (например, многие ко многим)

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

Таблица 2: Users_Events

Таблица 3: Мероприятия

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

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

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

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

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

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

Таблица 2 1 - A - Организатор - 05.01.2012 2 - A - Слушатель - 06.01.2 - A - Слушатель - 06.01.2012

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

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

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

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

Таблица 2 будет содержать: - FK из таблицы 1 - FK из таблицы 3 - Слушатель (логическое) - Организатор (boolean)

Это еще более гибко, и, например, если вам нужно будет отслеживать, кто будет выступать на собрании, вы можете ввести новый столбец Speaker, не нарушая ваш стол. Если вы предвидеть много ролей, это не будет масштабируемым однако

1

Правило, как первоначально заявлено

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

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

Однако, в комментариях, ОП позже заявил:

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

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