Лучшие практики базы данных

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

Мое оригинальное мышление было то, что таблица будет иметь и user_id и profile_id поля, поэтому если пользователь отправит комментарий, это дает user_id, оставляет profile_id незаполненное

действительно ли это правильно, неправильно, там лучший путь?

7
задан Bill Karwin 27 May 2010 в 06:56
поделиться

4 ответа

Раньше я использовал централизованную таблицу комментариев и имел поле для fk_table, на которое она ссылается.

например:

comments(id,fk_id,fk_table,comment_text)

Таким образом, вы можете использовать запросы UNION для объединения данных из нескольких источников.

SELECT c.comment_text FROM comment c JOIN user u ON u.id=c.fk_id WHERE c.fk_table="user"
UNION ALL
SELECT c.comment_text FROM comment c JOIN profile p ON p.id=c.fk_id WHERE c.fk_table="profile"

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

1
ответ дан 6 December 2019 в 19:33
поделиться

Если комментарии являются общими для нескольких объектов, вы можете создать таблицу для каждого объекта:

user_comments (user_id, comment_id)
profile_comments (profile_id, comment_id)

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

4
ответ дан 6 December 2019 в 19:33
поделиться

Какое бы ни было лучшее решение, ИМХО зависит не только от таблицы, но и от того, как это используется в другом месте приложения.

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

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

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

Существует также совершенно другое возможное решение проблемы, но это зависит от того, имеет ли это смысл в домен. Что, если в приложении есть другие места, где пользователь и плакат могут использоваться как взаимозаменяемые? Что, если Пользователь - это просто особый профиль? Тогда я думаю, что решение нужно решать в основном в таблицах user / profile. Например (сокращенно псевдо-sql):

create table AbstractProfile (ID primary key, type ) -- type can be 'user' or 'profile'
create table User(ProfileID primary key references AbstractProfile , ...)
create table Profile(ProfileID primary key references AbstractProfile , ...)

Затем в любом месте вашего приложения, где пользователь или профиль могут использоваться взаимозаменяемо, вы можете ссылаться на LoginID.

5
ответ дан 6 December 2019 в 19:33
поделиться

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

3
ответ дан 6 December 2019 в 19:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: