2015-01-06 1 views
2

Я пытаюсь решить, должен ли я нажимать конкретный столбец в свою собственную таблицу или если я должен использовать другой метод или ограничение какого-то рода.SQL Server, чтобы нормализовать это или нет?

Допустим, у меня есть таблица вроде:

tbl_Location 

LocationID PK int 
Address varchar(100) 
City varchar(50) 
State varchar(50) 

Еще другая таблица, как:

tbl_Store 

StoreID PK int 
StoreName varchar(50) 
LocationID int FK 

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

tbl_StoreLocation 

StoreID int 
LocationID int 

Вопрос 2: Есть ли преимущество по-прежнему с использованием идентичности PK/auto increment, если я должен был поставить это в свою таблицу?

В редком случае местоположение может быть удалено из таблицы tbl_Location. Если он удален, в методе один (все в одной таблице), мне нужно установить для LocationID значение NULL. Второй метод, мне придется использовать каскад.

Чтобы еще больше усложнить ситуацию, магазины могут иметь продукты, а LocationID - их местоположение по умолчанию. При создании продукта он по умолчанию использует свой идентификатор LocationID из tbl_Store, или если я разбиваю его на другую таблицу, таблицу tbl_StoreLocation. Так что толкает это дальше, например:

tbl_Product 

ProductID PK int 
StoreID FK int 
ProductName varchar(50) 
LocationID fk int <----- 

Или я опять (И каждый продукт может иметь только одно местоположение):

tbl_ProductLocation 

ProductID int 
LocationID int 

Я читал о более глубоких фазах нормализации, но что Мне нужно понимание понимания - это анализ времени/выгоды/структуры для чего-то такого простого.

Как вы думаете?

+4

Вы использовали бы отдельную таблицу ТОЛЬКО, если бы было несколько местоположений. Без исключений. – Misunderstood

+0

@ Понятно, спасибо. Я всегда делал это именно так, но после прочтения массивного документа о нормализации это испортило мой мозг :) – user1447679

+0

Должен ли быть FK? Есть те, которые говорят, что это не требуется для 3NF, но я поместил список допустимых значений в FK. – Paparazzi

ответ

0

К вопросу 1: Если магазин должен иметь в одном месте, не менее одного и не более чем один, так что избыточно толкать связь между магазином и местом в другую таблицу. Но если в магазине нет места, так как его местоположение может быть удалено, вы должны использовать таблицу tbl_StoreLocation. В таком случае вы должны удалить столбец LocationID из таблицы tbl_Store.

Для вопроса 2: Да, полезно использовать столбец PK identity/auto increment, если вы должны положить это в свою собственную таблицу. Почему нет? Вы все еще используете его для отношений.

Несколько слов о продуктах. Вы сказали - «магазины могут иметь продукты» - поэтому продукт относится к магазину, но к местоположению, поэтому местоположение продукта - это его расположение магазина. Только если вы измените это бизнес-правило, вам необходимо переконфигурировать вашу базу данных в переписке.

+0

Если местоположение удалено и этот идентификатор местоположения существует в таблице Store, не так ли просто установить это в таблице хранилища в NULL? Нули разрешены ... вместо создания отдельной таблицы? Что касается продукта, когда в магазине создается продукт, он может выбрать место для этого продукта, а местоположение по умолчанию, которое выбрано первым, - это местоположение магазина. Однако они могут выбрать другое место. Это странная установка. Я думаю, что отдельная таблица переполнена для StoreLocation или ProductLocation, так как оба могут иметь только одно местоположение. – user1447679

+0

Что касается меня, я не использую столбцы с нулевым значением в внешних ключах. Причина в том, что в соединениях * Результаты не позволяют легко отличить NULL от данных из NULL, которые представляют собой отказ от присоединения *, как указано здесь - [Null Values ​​and Joins] (http://technet.microsoft. com/en-us/library/ms190409 (v = sql.105) .aspx) – Serg

+0

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

0

Кажется, что излишним, чтобы иметь отдельную таблицу, когда продукт и магазин, оба будут иметь одно место. Мне кажется, неплохо было бы представить здесь немного SCD.Почему бы не добавить bit колонки IsEffective OR имеет EffectiveTill столбец, который будет иметь штамп времени, соответствующий дату (значение по умолчанию 31-12-2999 и время до, когда запись в таблицах tbl_Location, tbl_Product или tbl_Store является эффективным.

Если место удаляется, просто обновите столбец EffectiveTill до getdate() Если местоположение продукта должно быть внезапно изменилось, просто обновить EffectiveTill для этой строки в getdate() и вставить новую строку с новым locationID.

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