В случае простых атомарных значений я склонен не соглашаться с общепринятым мнением по этому поводу, в основном, в отношении сложности. Рассмотрим стол со шляпами. Вы можете сделать "денормализованный" способ:
CREATE TABLE Hat (
hat_id INT NOT NULL PRIMARY KEY,
brand VARCHAR(255) NOT NULL,
size INT NOT NULL,
color VARCHAR(30) NOT NULL /* color is a string, like "Red", "Blue" */
)
Или можно еще нормализовать, составив "цветную" таблицу:
CREATE TABLE Color (
color_id INT NOT NULL PRIMARY KEY,
color_name VARCHAR(30) NOT NULL
)
CREATE TABLE Hat (
hat_id INT NOT NULL PRIMARY KEY,
brand VARCHAR(255) NOT NULL,
size INT NOT NULL,
color_id INT NOT NULL REFERENCES Color(color_id)
)
Конечным результатом последнего является то, что вы добавили некоторую сложность - вместо:
SELECT * FROM Hat
Теперь вы должны сказать:
SELECT * FROM Hat H INNER JOIN Color C ON H.color_id = C.color_id
Это дополнительное присоединение - большое дело? Нет - по сути, это основа реляционной модели проектирования - нормализация позволяет предотвратить возможные несоответствия в данных. Но каждая подобная ситуация добавляет немного сложности, и, если нет веской причины, стоит спросить, зачем вы это делаете. Я считаю возможными "веские причины" включить:
- Есть ли другие атрибуты, которые "свисают" с этого атрибута? Вы фиксируете, скажем, и "название цвета", и "шестнадцатеричное значение", так что шестнадцатеричное значение всегда зависит от названия цвета? Если да, то вам определенно нужна отдельная таблица цветов, чтобы избежать ситуаций, когда в одной строке есть («Красный», «# FF0000»), а в другой («Красный», «# FF3333»). Множественные коррелированные атрибуты - это сигнал №1 о том, что объект должен быть нормализован.
- Будет ли набор возможных значений часто меняться? Использование нормализованной таблицы поиска упростит будущие изменения элементов набора, поскольку вы просто обновляете одну строку. Однако, если это происходит нечасто, не упирайтесь в утверждения, которые вместо этого должны обновлять множество строк в основной таблице; базы данных неплохо справляются с этим. Если вы не уверены, проведите тесты скорости.
- Будет ли набор возможных значений напрямую управляться пользователями? Т.е. есть ли экран, на котором они могут добавлять / удалять / изменять порядок элементов в списке? В таком случае, очевидно, необходим отдельный стол.
- Будет ли список различных значений влиять на какой-либо элемент пользовательского интерфейса? Например, такое "цветное" дроплист в пользовательском интерфейсе? Тогда вам будет лучше иметь его в отдельной таблице, а не выполнять SELECT DISTINCT в таблице каждый раз, когда вам нужно отобразить дроплист.
Если ни один из них не подходит, мне будет трудно найти другую (хорошую) причину для нормализации. Если вы просто хотите убедиться, что значение является одним из определенного (небольшого) набора допустимых значений, вам лучше использовать ОГРАНИЧЕНИЕ, в котором говорится, что значение должно быть в определенном списке; делает вещи простыми, и вы всегда можете "перейти" на отдельную таблицу позже, если возникнет необходимость.
person
Ian Varley
schedule
20.12.2008