проблема, связанная с атомарностью в таблице базы данных - PullRequest
1 голос
/ 17 мая 2011

Я создаю страницу форума, для которой я создал следующую схему базы данных:

Forum(questionId, postedByUserId, questionSubject, questionBody, TagIds);

Tags(tagId, tagName);

Записи в форуме будут выглядеть примерно так:

(1, 1, 'sample subject', 'sample body', '1 4 2') ...

И примерные записи тегов будут:

(1, 'C'), (2, 'C++'), (3, 'Java'), (4, 'Data Structure') ...

Теперь проблема в том, что первая нормальная форма говорит, что все поля должны быть атомарными, что в данном случае не выполняется, но я думаю, что пространство сохраняется, как если бы я создавал новую таблицу forum_tag(questionId, tagId);, тогда я думаю, что это займет больше места в базе данных, но было бы правильно концептуально.

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

Пожалуйста, объясните, что лучше и почему, потому что есть много случаев, когда я обнаруживал такую ​​проблему, но все время оставался неоднозначным, что мне делать!

Так что, пожалуйста, помогите.

Заранее спасибо:)

Ответы [ 3 ]

1 голос
/ 17 мая 2011

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

Рассмотрим следующий поиск по предложенной вами схеме: найдите все записи на форуме, где один из связанных тегов равен «4».Для большинства СУБД этот запрос потребует последовательного сканирования всей таблицы форумов.В зависимости от объема данных это могут быть миллионы дисковых операций ввода-вывода.

Теперь рассмотрим таблицу соединений

ForumTags (ForumId, TagId) primary key (ForumId, TagId)

Далее, допустим, что есть индекс на TagId в дополнение кавтоматическое включение индекса (ForumId, TagId)

Тот же запрос приведет к поиску индекса со значением «4» в одном из индексов и потребует всего лишь дюжину дисковых операций ввода / вывода.

Одной из целей нормализации является ключевой доступ ко всем данным.первая нормальная форма соответствует этой цели.

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

1 голос
/ 17 мая 2011

Я бы сделал ваши поля атомарными. В большинстве случаев у вас есть поле, в котором значения объединяются в одно поле, позже возникают головные боли, когда вам приходится постоянно разбирать эти данные на части для составления отчетов или анализа. Что, если вы хотите сделать что-то столь же простое, как подсчет ваших тегов? Из-за неатомарных данных вы даже не сможете сделать быстрый SELECT COUNT(). У вас также будут большие проблемы при создании запросов, которые пересекают ссылки на форумах с разными тегами. Скажите, что вы хотите запросить все сообщения на форуме с тегом "программирование"?

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

0 голосов
/ 17 мая 2011

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

ForumTags (ftID, Forum, Tag)

Таким образом, ваша база данных должным образом нормализована, поэтому добавление и удалениеТеги на форумах становятся намного проще.Не беспокойтесь о дополнительном пространстве, которое может занять в базе данных, как говорит Уолтер Митти: «Пространство дешево, поиск гораздо дешевле».Как правило: нормализация всегда хорошая идея, если явно не доказано иное

...