Подтвердить что ты не робот

Ненужная нормализация

Мы с моим другом строим сайт и имеем серьезные разногласия. Ядром сайта является база данных комментариев о "людях". В основном люди могут вводить комментарий, и они могут ввести человека, о котором идет речь. Затем зрители могут искать базу данных для слов, которые находятся в комментарии или в частях имени человека. Он полностью создан пользователем. Например, если кто-то хочет опубликовать комментарий о неверно названной версии имени человека, они могут, и это ОК. Таким образом, может быть несколько написаний разных людей, перечисленных как несколько разных записей (некоторые из них имеют среднее имя, некоторые с псевдонимом, некоторые неверные и т.д.), Но все в порядке. Нам все равно, будут ли люди комментировать случайные люди или воображаемые люди.

В любом случае проблема заключается в том, как мы структурируем базу данных. Сейчас это всего лишь одна таблица с идентификатором комментария в качестве первичного ключа, а затем есть поле для "человека" , о котором идет комментарий:

комментарий ID - комментарий - человек

1 - "он странный" - Джон Смит

2 - "вонючая девушка" - Дженни

3 - "гей" - Джон Смит

4 - "должен мне 20 долларов" - Jennyyyyyyyyy

Все работает нормально. Используя базу данных, я могу создавать страницы, в которых перечислены все "комментарии" для определенного "человека" . Однако он одержим тем, что база данных не нормализована. Я прочитал о нормализации и узнал, что он ошибался. Таблица IS в настоящее время нормализована, поскольку идентификатор комментария уникален и диктует "комментарий" и "человек" . Теперь он настаивает на том, что "человек" должен иметь это СОБСТВЕННЫЙ стол, потому что это "вещь". Я не думаю, что это необходимо, потому что, хотя "человек" действительно является более крупным контейнером (у одного "человека" может быть много "комментариев" о них), база данных, похоже, отлично работает с "человеком", являющимся атрибутом идентификатор комментария. Я использую различные вызовы PHP для разных вариантов SQL, чтобы сделать его магическим образом более сложным на выходе и другим способом, которым пользователь может искать и видеть результаты, но на самом деле настройка довольно проста. Теперь я разрешаю пользователям оценивать комментарии с большими пальцами вверх и большими пальцами вниз, и я сохраняю "оценку" как другое поле в одной таблице.

Я чувствую, что в настоящее время нет необходимости иметь отдельную таблицу только для уникальных записей "человек" , потому что "люди" не имеют собственного "счета" или каких-либо их собственных атрибутов. Делают только комментарии. Мой друг настолько настойчив, что это необходимо для эффективности. Наконец, я сказал: "Хорошо, если вы хотите, чтобы я создал отдельную таблицу и дал" человеку "это собственное поле, то каково было бы второе поле? Потому что, если в таблице есть только один столбец, это кажется бессмысленным. что позже мы можем создать потребность в том, чтобы дать" человеку "свою собственную таблицу, но тогда мы можем справиться с этим". Затем он сказал, что строки не могут быть первичными ключами и что мы будем преобразовывать "лиц" в текущей таблице в числа, а числа будут первичным ключом в новой таблице "человек" . Для меня это кажется ненужным, и это затруднит чтение текущей таблицы. Он также считает, что создать вторую таблицу позже невозможно, и что нам нужно предвидеть, что нам может понадобиться это для чего-то позже.

Кто прав?

4b9b3361

Ответ 1

По-моему, твой друг прав.

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

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

Ответ 2

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

Ответ 3

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

Ответ 4

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

Если вы планируете добавить больше, а именно, чтобы люди могли иметь учетные записи или что-то действительно, я думаю, что было бы разумно разделить ваши данные на таблицы Person, Comments. Это не сложно и упрощает расширение вашей функциональности.

Ответ 5

Вы правы.

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

Но здесь похоже, что у вас есть неструктурированные данные, без идентификации; и что ничто/никто не заинтересован в том, чтобы убедиться, что "дженни" и "дженний" на самом деле являются одним и тем же человеком, не говоря уже о "дженни-доке" и "моей кузине"...

Ответ 6

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

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

Ответ 7

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

Давайте рассмотрим, что у вас есть:

  • Любой данный экземпляр CommentId функционально определяет Person (FD: CommentIdPerson)
  • Любой данный экземпляр CommentId функционально определяет Comment (FD: CommentIdComment)
  • Любой данный экземпляр CommentId функционально определяет UserId (FD: CommentIdUserId)
  • Любой данный экземпляр CommentId функционально определяет Score (FD: CommentIdScore)

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

Прежде всего, спросите себя, почему вы все равно создали атрибут CommentId? Строго говоря, это изготовленный атрибут - он не связан ни с чем "реальным". Комментарий: обычно называемый суррогатным ключом. Суррогатный ключ - это просто значение, которое стоит в для уникального набора значений, соответствующего некоторой другой группе атрибутов. Итак, какая группа атрибутов CommentId суррогат? Мы можем понять, что , задав следующие вопросы и добавив в модель новый FD:

  • 1) Должен ли комментарий быть уникальным? Если это так, то FD: CommentCommentId должен быть правдой.
  • 2) Можно ли сделать один и тот же комментарий несколько раз, пока речь идет о другом Лице? Если это так, то FD: Person + CommentCommentId должен быть истинным, а FD в 1 выше - false.
  • 3) Можно ли сделать одно и то же замечание несколько раз о том же Личном лице, если оно было сделано разные UserId? Если это так, то FDs в 1 и 2 не могут быть правдой, но FD: Person + Comment + UserIdCommentId может быть правдой.
  • 4) Можно ли сделать один и тот же комментарий несколько раз о том же Листе одним и тем же UserId, но имеют разные оценки? Это подразумевает FD: Person + Comment + UserId '+ ScoreCommentId является истинным, а остальные ложными.

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

Предположим, что FD: Person + Comment + UserIdCommentId оказывается верным. Логическое последствия таковы:

  • Person + Comment + UserId и CommentId служат в качестве эквивалентных ключей по отношению к Score
  • Score должен быть связан с одним, но не с двумя его ключами (чтобы избежать транзитивных зависимостей). Очевидным выбором будет CommentId, поскольку он был специально создан как суррогат.
  • Отношение, связанное с: CommentId, Person, Comment, UserId необходимо для привязки Ключ к его суррогату.

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

Создание суррогатных ключей является практическим вопросом, имеющим некоторое значение. Подумайте, что может произойти, если вы решите не использовать суррогатный ключ, но полный набор атрибутов Person + Comment + UserId вместо этого, особенно если это необходимо на нескольких таблицах в качестве внешнего или первичного ключа:

  • Комментарий может добавить много места накладных расходов к вашей базе данных, потому что она повторяется в нескольких таблицах. Вероятно, это более чем несколько символов.
  • Что произойдет, если кто-то решит отредактировать комментарий? Это изменение должно быть распространено ко всем таблицам, где Комментарий является частью ключа. Не красивое зрелище!
  • Индексирование сложных сложных клавиш может занимать много места и/или делать для медленной производительности обновления.

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

Теперь вернемся к тому, нужно ли создавать суррогат для Person. Живет ли Person с левой стороны от многих или любых FD? Если это произойдет, его значение будет распространяться через ваши базы данных, и есть случай для создания суррогата для него. Является ли человек текстовым или числовым атрибутом, не имеет отношения к выбору создания суррогатного ключа.

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

Ответ 8

Если вы никогда не намереваетесь связывать столбец пользователя с пользователем или чем-то еще, и данные, по-видимому, не нуждаются в проверке целостности или целостности данных, просто почему это происходит в реляционной базе данных? Разве это не было бы прецедентом для базы данных nosql? Или я что-то упускаю?

Ответ 9

Здесь сделка. Всякий раз, когда вы что-то создаете, вы хотите убедиться, что у него есть место для роста. Вы хотите попытаться предвидеть будущие проекты и будущие достижения вашей программы. В этом случае вы правы, говоря, что в настоящее время нет необходимости добавлять таблицу лиц, которая просто содержит 1 поле (не считая идентификатор, если у вас есть поле идентификатора int и имя человека). Однако в будущем вам могут понадобиться другие атрибуты для таких людей, как имя, фамилия, адрес электронной почты, дата добавления и т.д.

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

Ответ 10

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

user -> id | username | password | email

comment -> id | user_id | content

SQL, чтобы присоединиться к комментариям пользователей:

SELECT user.username, comment.content FROM user JOIN comment WHERE user.id = comment.user_id;

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

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

Ответ 11

С этой базой данных вы можете почувствовать, что все в порядке, но в будущем может возникнуть какая-то проблема, когда вы хотите, чтобы пользователи знали больше из базы данных. Предположите, что вы хотите узнать о количестве комментариев, сделанных для человека с name= 'abc'. В этом случае вам придется пройти всю таблицу комментариев и продолжить подсчет. Вместо этого вы можете иметь атрибут "count" для каждого человека и увеличивать его каждый раз, когда комментарий делается на этом человеке.
Что касается нормализации, всегда лучше иметь нормализованную базу данных, поскольку она уменьшает избыточность и делает базу данных интуитивно понятной. Если вы ожидаете, что в будущем ваша база данных будет большой, тогда должна присутствовать нормализация.