Проектирование реляционных баз данных (MySQL) - PullRequest
2 голосов
/ 01 декабря 2010

Я запускаю новый проект для веб-сайта на основе «Талантов» - например:

  • Модель
  • Актёры
  • Singers
  • Танцоры
  • Музыканты

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

Любой пользователь, зарегистрировавшийся на сайте, может создать профиль для одного или нескольких из этих талантов. Талант может иметь суб-таланты, например, актер может быть актером телевидения или актером театра или актером закадрового комментария.

Так, например, у меня есть пользователь А - он модель (модель подиума) и актер (телевизионный актер, театральный актер, актер закадровый).

Мои вопросы:

  1. Нужно ли создавать отдельные таблицы для хранения суб-талантов этого пользователя?

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

  3. Что-нибудь еще, что я должен знать?

Ответы [ 4 ]

3 голосов
/ 01 декабря 2010

прежде чем отвечать на ваши вопросы ... я думаю, что user_id не должен быть в таблице Talents ... основная идея здесь заключается в том, что "для одного таланта у вас много пользователей, а для одного пользователя - несколько талантов" ..поэтому отношение должно быть NxN, вам понадобится промежуточная таблица

см .: много ко многим

сейчас

Нужно ли мнесоздать отдельные таблицы для хранения субталантов этого пользователя?

Если вы хотите сделать что-то динамическое (добавить или удалить субталенты), вы можете использовать рекурсивные отношения.Это таблица, относящаяся к себе

TABLE TALENT
-------------
id  PK
label
parent_id PK FK (a foreign key to table Talent)

см .: рекурсивные ассоциации

Как мне выполнить поиск талантов высшего уровня дляэтот пользователь?Т.е. в пользовательской таблице должны быть поля для идентификатора каждого таланта?Или я должен выполнить поиск в каждой таблице талантов верхнего уровня, чтобы увидеть, существует ли там этот user_id?

, если вы используете модель раньше, это может быть кошмаром для выполнения запросов, потому чтоВаша таблица Таланты теперь является ДЕРЕВО, которое может содержать несколько уровней ... вы можете ограничить себя определенным количеством уровней, которые вы хотите в таблице своего таланта, я полагаю, что двух достаточно ... таким образом, ваши запросы будут проще

Что-нибудь еще, о чем я должен знать?

при использовании рекурсивных отношений ... внешний ключ должен иметь пустые значения, потому что таланты высших уровней не будут иметь parent_id ...

Удачи!:)

РЕДАКТИРОВАТЬ: хорошо .. я создал модель .. чтобы объяснить ее лучше

model

Редактировать Вторая модель (в форме рождественской елки = D). Обратите внимание, что отношение между Model & Talent и Actor & Talent является отношением 1x1, для этого есть разные способы ( одна и та же ссылка в комментариях)

alt text

, чтобы узнать, есть ли у пользователя таланты .. присоединитесь к трем таблицам в запросе =) надеюсь, это поможет

2 голосов
/ 01 декабря 2010

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

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

Names (Name, Email, Bio)

Talents (TalentType references TalentTypes, Email references Names)

TalentTypes (TalentType, Description, Parent references TalentTypes)

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

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

Models (Email references Talents, ModelingSalary) -- with a check constraint that talents contain a record with modelling talent type

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

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

2 голосов
/ 01 декабря 2010

У вас должна быть одна таблица, в которой есть все о пользователе (имя, доб, любая другая информация о пользователе).У вас должна быть одна таблица, в которой есть все о талантах (id, talentName, TopLevelTalentID (для хранения «вспомогательных» талантов необходимо указать ссылку на «родительский» талант)).У вас должна быть третья таблица для отношений «многие ко многим» между пользователями и талантами: UserTalents, в которой хранятся ID пользователя и TalentID.

Вот статья, в которой объясняется, как добраться до 3-го NF:

http://www.deeptraining.com/litwin/dbdesign/FundamentalsOfRelationalDatabaseDesign.aspx

1 голос
/ 10 декабря 2010

хорошо, извините за неправильный ответ .. это другой подход.

На мой взгляд, у пользователя может быть несколько профессий (актер, модель, музыкант и т. Д.). Обычно я сначала думаю об объектах, а затем переводю их в таблицы.В POO у вас будет класс User и подклассы Actor, Model и т. Д. У каждого из них также могут быть подклассы, такие как TvActor, VoiceOverActor ... в БД у вас будет таблица для каждого таланта и субталента, все онииспользовать один и тот же первичный ключ (идентификатор пользователя), поэтому, если пользователь 4 - это Actor и Model, у вас будет один реестр в таблице Actor и другой в таблице Model, оба с id = 4

Как видите, хранение очень просто ... сложная часть заключается в получении информации.Это потому, что базы данных не имеют понятия наследования (я думаю, что MySQL имеет, но я не пробовал) .. поэтому, если вы хотите, чтобы подпункты пользователя 4, я вижу три варианта:

  • несколько SELECT для каждой имеющейся у вас таблицы талантов и подзащитных, спрашивая, равен ли их идентификатор 4.

    SELECT * FROM Actor WHERE id = 4; SELECT * FROM TvActor WHERE id = 4;

  • Сделать большой запрос, объединяющий все таблицы талантов и субтенталей в левом соединении

    ВЫБРАТЬ * от пользователя ЛЕВОЕ СОЕДИНЕНИЕ Актер ВКЛ User.id = Actor.id ЛЕВОЕ СОЕДИНЕНИЕ TvActor ON Пользователь.id = TvActor.id LEFT JOIN ... WHERE User.id = 4;

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

alt text

Каждаяодин из этих трех вариантов имеет свои плюсы и минусы .. может быть, есть еще один =)

Удачи

PS: ааа, я нашел другой вариант здесь или, может быть, это простоулучшен второй вариант

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