Вопрос разработки схемы SQL, касающийся связи двух разных типов идентификаторов с одним фрагментом информации - PullRequest
3 голосов
/ 18 августа 2011

Я работаю над редизайном некоторых частей нашей схемы и сталкиваюсь с проблемой, когда просто не знаю, как правильно что-то сделать.У меня есть таблица событий, например:

Events
--------
event_id

для каждого события, с ним может быть связано n групп или пользователей.Таким образом, есть таблица, относящаяся к событиям для пользователей, чтобы отразить это отношение один ко многим, например:

EventUsers
----------
event_id
user_id

Проблема в том, что у нас также есть концепция групп.Мы хотим связать n групп с событием в дополнение к пользователям.Таким образом, этого столбца user_id недостаточно, потому что нам нужно хранить потенциально либо user_id, либо group_id.

Я думал о множестве способов справиться с этим, но все они кажутся большим взломом,Например, я мог бы сделать это member_id и вставить в столбец member_type, например:

EventUsers
----------
event_id
participant_id
participant_type

, и если бы я хотел получить события, частью которых является user_id 10, это могло бы быть что-то вроде:

select event_id
from EventUsers 
where participant_id = 10 
and participant_type = 1

(при условии, что где-то участник_Тип 1 был определен как Пользователь).Но мне не нравится это с философской точки зрения, потому что, когда я смотрю на данные, я не знаю, что означает число в member_id, если только я не смотрю на значение вpartpant_type.

Я мог бытакже измените EventUsers на что-то вроде:

EventParticipants
-----------------
event_id
user_id
group_id

и разрешите значениям user_id и group_id быть NULL, если эта запись имеет дело с другим типом информации.

Конечно, яможно просто разбить EventUsers, и мы назовем его EventGroups на 2 разные таблицы, но я хотел бы сохранить, кто связан с событием, хранящимся в одном месте, если есть хороший логический способ сделать это.

Итакя пропускаю хороший способ сделать это?

Ответы [ 3 ]

4 голосов
/ 18 августа 2011

Таблицы События, Пользователи и Группы представляют основные объекты.Они связаны с EventUsers, GroupUsers и EventGroups.Вам нужно объединить результаты вместе, например, участники события:

select user_id
  from EventUsers
  where event_id = @event_id
union
select GU.user_id
  from EventGroups as EG inner join
    GroupUsers as GU on GU.group_id = EG.group_id
  where EG.event_id = @event_id

Не стесняйтесь создавать дополнительные таблицы для представления разных типов вещей.Часто их проще объединить, например, с объединением, чем пытаться разобраться в беспорядке расплывчатых данных.

3 голосов
/ 18 августа 2011

Конечно, я мог бы просто разбить EventUsers, и мы назовем его EventGroups на 2 разные таблицы

Это хороший логический способ сделать это . Создайте таблицу соединений для каждого отношения многие ко многим ; один для событий и пользователей, другой для событий и групп.

1 голос
/ 18 августа 2011

Там нет правильного ответа на этот вопрос (хотя я уверен, что если вы посмотрите достаточно внимательно, вы найдете несколько пуристов, которые считают, что их подход правильный).

Лично яПоклонник второго подхода, поскольку он позволяет задавать имена столбцов, которые точно отражают содержащиеся в них данные.Это делает ваши SELECT заявления (особенно когда речь идет о присоединении) немного легче для понимания.Да, в итоге вы получите кучу NULL значений в столбце, которые не используются, но это не имеет большого значения.

Однако, если вы будете много присоединяться к этой таблице,возможно, было бы разумно использовать первый подход, чтобы столбец, к которому вы присоединяетесь, был одинаковым.Кроме того, если вы ожидаете, что в будущем будут добавлены новые типы participant, что приведет к появлению третьего столбца в EventParticipants, то вы, возможно, захотите использовать первый подход, чтобы сузить таблицу.

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