У меня есть интересная дискуссия с другим дизайнером базы данных о нормализации. В этом примере у нас есть таблица GameTitles, и каждая запись должна содержать год выпуска игры. Он говорит, что 2NF требует, чтобы все было нормализовано, поэтому для обеспечения соответствия поле года должно быть разделено на таблицу ReleaseYears со своим собственным первичным ключом, на который ссылается таблица GameTitles. Я говорю, что это должно остаться как поле на самой таблице GameTitles.
Мой аргумент в пользу этого заключается в том, что год - это просто не примитивное числовое значение, которое является статичным по своей природе (то есть 2011 год всегда будет 2011 годом). Из-за этого он служит своим собственным идентификатором и ему не нужно ничего, чтобы ссылаться на него, поскольку он является тем, чем он является. Это также вводит дополнительное обслуживание, поскольку теперь вам нужно добавить новый год в таблицу, чтобы просто сослаться на него. Если вы предварительно заполняете таблицу большим диапазоном лет, то у вас есть дополнительные записи, которые потенциально не будут иметь ссылок на них вообще. Это также увеличивает размер базы данных, поскольку теперь у вас есть дополнительная таблица, накладные расходы на запись и дополнительный первичный ключ для самого года. Если вы сохраняете год как поле в таблице GameTitles, вы устраняете все это дополнительное обслуживание и накладные расходы.
Мысли об этом?
редактировать: имеется ввиду, чтобы опубликовать это в StackOverflow. Может ли кто-нибудь проголосовать, чтобы удалить это или пометить это как внимание
источник
Ответы:
Другой дизайнер баз данных просто ошибается, но ваши рассуждения также неверны. Предположим, вы начинаете с этой таблицы, которая имеет единственный ключ-кандидат "game_title".
Вы оцениваете, находится ли он в 2NF, задавая себе эти вопросы.
Q: Прежде всего, это в 1NF?
A: Да, это так.
Вопрос: Каковы основные атрибуты (атрибуты, которые являются частью ключа-кандидата)?
A: "game_title" является единственным основным атрибутом.
Q: Каковы непростые атрибуты?
A: "year_first_released" является единственным.
Q: Функционально "year_first_released" зависит от всего "game_title" или только от его части?
A: Единственный ключ-кандидат "game_title" - это один столбец; у него даже нет частей. Таким образом, year_first_released функционально зависит от всего game_title.
Вуаля. Вы нашли 2NF.
Вы можете прорезать некоторые формальные термины, сначала спросив, есть ли он в 1NF, а затем ответив на этот вопрос.
Q: Существуют ли какие-либо ключи-кандидаты?
A: Нет.
Вуаля. Вы снова нашли 2NF.
По определению, для таблицы, которая нарушает 2NF, она должна иметь как минимум один ключ-кандидат, имеющий более одного столбца.
Вот ваши причины отклонить мнение вашего друга.
Ни одна из этих причин не имеет никакого отношения к тому, находится ли таблица в 2NF.
При проектировании базы данных нет ничего плохого в том, чтобы учитывать вопросы обслуживания, размер базы данных, строки без ссылок, ограничения диапазона и т. Д. Это просто неправильно называть эти вещи нормализацией.
О, и та таблица с двумя столбцами, которую я предоставил выше - это в 5NF.
источник
Создание отдельной таблицы для любого атрибута не имеет ничего общего с нормализацией. 2NF, 3NF, BCNF, 4NF, 5NF занимаются устранением неключевых зависимостей. Если вы удалите какой-либо отдельный атрибут в новую таблицу и замените его атрибутом внешнего ключа, то зависимости в таблице логически будут такими же, как и раньше, поэтому пересмотренная версия таблицы не более или менее нормализована, чем она. был раньше.
источник
С моей точки зрения, отдельная таблица по годам будет иметь смысл только в том случае, если «год выпуска» - это не календарный год, а, например, финансовый год, который может охватывать несколько календарных лет (например, с октября по октябрь).
Эта таблица будет содержать определение (реальная дата начала и окончания) финансового года
источник
От http://en.wikipedia.org/wiki/Second_normal_form :
Вы не указали, является ли год частью ключа кандидата или нет, но я не уверен, что это имеет значение, потому что в любом случае 2NF будет удовлетворен в том, что касается года.
На практическом уровне плохая идея отделять год по всем перечисленным вами причинам.
источник
Мне не нравится аргумент против отдельной таблицы из-за ее размера или того, что в ней будут неиспользуемые строки. Даже если вы положите 1000 лет в эту таблицу, размер будет незначительным.
Тем не менее, я не думаю, что стол нужен вообще. Какой смысл иметь отдельную таблицу на год? Эти данные уже находятся в основной таблице, и вы абсолютно ничего не экономите, создавая вторую таблицу.
Аргумент может быть другим для таблицы календаря, где каждая строка представляет день и может иметь другие атрибуты (день недели, смещение UTC, будь то праздник и т. Д.).
Но только год? Нет, я не вижу никакой пользы вообще ... И как уже указывали другие, спросите их, почему они думают, что это более нормализовано? Или что они получают? Если вы пытаетесь написать такие запросы, как
Вместо того
Тогда я бы попытался убедить вас в том, что последний намного лучше по производительности (при условии, что dt проиндексирован) и хранилищу. Если простота кодирования имеет первостепенное значение, я бы сказал, что постоянный вычисляемый столбец будет лучше, чем другая таблица.
источник
Я полностью согласен с ответом Catcall, за исключением одного момента: «год» не всегда может быть примитивным значением, но я думаю, что это скорее концепция бизнес-логики, чем концепция дизайна базы данных.
Сохраняя тот же дизайн, давайте предположим, что это должны быть только те годы, которые разрешены к выпуску. Таким образом, вы имеете дело не с примитивными числовыми значениями, а с их подмножеством, и, поскольку у этого подмножества нет примитивной реализации, вы должны сделать свою собственную (отдельную таблицу?) И сослаться на нее (с ФК). Таким образом, мы все еще говорим о годах, но нам нужно управлять ими по-другому, потому что они концептуально изменили свое значение. Тем не менее, они все еще «год выпуска», но концептуально отличаются с точки зрения того, что они значат для кого-то в области знаний.
Для этого конкретного случая я снова говорю, что ответ Catcall является правильным, но просто хотел указать на это. (Извините, у меня недостаточно представителей, чтобы комментировать.)
источник