Конструкция DB: 1-я нормальная форма и повторяющиеся группы

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

    CustID  Name  Address       Phone1      Phone2       Phone3

     102    Jerry  234 East..   555-2342   555-9854     555-2986

вы должны создать вторую таблицу телефонных номеров, а затем на соединение вы получите:

CustID  Name     Address       Phone

102 Jerry    234 East..   555-2342
102 Jerry    234 East..   555-9854
102 Jerry    234 East..   555-2986

иногда это немного более неоднозначно, и трудно сказать, когда группа заголовков столбцов квалифицируется. Например, предположим, что на данный момент у вас есть два теста, которые вы запускаете на каждом аппаратном обеспечении. И ваш первый дизайн DB дает больше всего горизонтальный подход:

дизайн 1

SN     Test1_Max   Test1_Min    Test1_Mean  Test2_Max   Test2_Min    Test2_Mean
2093      23          2            15         54          -24           45  

очевидно, что это повторяющаяся группа, которую гораздо легче представить как (на соединении между "частями"и " тестами"):

Дизайн 2

SN     Test      Max    Min    Mean     
2093    1        23     2      15       
2093    2        54     -24     45      

однако вы можете пойти еще более вертикально:

дизайн 3

SN     Test    Statistic    Value
2093    1        Max          23
2093    1        Min          2
2093    1        Mean         15       
2093    2        Max          54
2093    2        Min         -24
2093    2        Mean         45  

дизайн 3 надо? Как вы решаете, как это сделать? Каковы плюсы и минусы между 2 и 3? Кажется, что оба могут быть легко выбраны или объединены с SQL, с преимуществом, предоставленным Design 3, потому что вы можете легко добавить новую статистику без фактического изменения структуры таблицы.

но прежде чем кто-нибудь пойдет и скажет, что чем больше вертикали, тем лучше, бывают времена, когда это более неоднозначно. Например:

дизайн 4

SN      AverageCurrent (mA)    BatteryCapacity (mA)  
2093          200                    540  

может быть вместо этого:

дизайн 5

SN      mA_Measuremnt       Value
2093    AverageCurrent      200 
2093    BatteryCapacity     540 

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

подводя итог этому смехотворно длинному вопросу, следует ли удалять и нормализовать повторяющиеся группы, только если они точно такой же домен и имеют то же самое значение?. Если это так, то действительно только телефонный пример и, вероятно, два теста в дизайне 1 соответствуют этим критериям. Хотя кажется, что могут быть преимущества дизайна для дизайна 3 и 5, Даже если статистика дизайна 3 имеет разные значения, строго говоря, и AverageCurrent и BatteryCapacity определенно имеют разные значения в дизайне 5.

7 ответов


Дизайн 2 и дизайн 4-лучшие способы пойти при условии, что результаты не всегда будут присутствовать (он же NULLs в Desigin 1). Если они всегда принимаются, то первый дизайн в порядке.

Я считаю, что повторяющиеся группы В SQL будут на самом деле, если у вас есть столбец, заполненный значениями add'L, например, Phone_Number содержит "123-444-4444, 123-333-3334" и т. д.

в любом случае, более поздние проекты являются неоптимальными - вы продолжаете принимать это на окончательный уровень и иметь " один истинный Таблица Поиска"http://www.dbazine.com/ofinterest/oi-articles/celko22 или значение атрибута сущности http://tonyandrews.blogspot.com/2004/10/otlt-and-eav-two-big-design-mistakes.html

http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:10678084117056

в любом случае, это почти всегда плохо. Хотя они могут иметь общий тип данных/домена смысл отличается-таким образом, они должны остаются отдельные атрибуты (maxtemp, mintemp и др.)


Я думаю (и был обучен) 1NF как "все строки должны быть одинаковой длины", а не "без повторяющихся групп". С этой точки зрения вы можете принять решение немного легче из следующего:

в дизайне 1 оба теста всегда присутствуют? Если так,то это не повторяющаяся группа. Все ли средние значения всегда присутствуют в дизайне 2? Может ли быть больше (или меньше) в данной строке?

в дизайне 4 оба эти значения всегда присутствуют? Если так, то все в порядке. Если нет то следует использовать дизайн 5.


вот правило для повторяющихся групп - что функционально зависит?

если статистическое значение функционально зависит от имени SN, Test и Statistic, то у вас есть три ключевых элемента и один элемент value. ( SN, Test, Statistic -> Value )

в этом конкретном случае -- aggregated data (mean, sum, min, max) -- у вас есть двусмысленность, потому что вы не имеете дело с атомарными объектами, вы имеете дело с агрегатами. Строго говоря, вы не должны хранить агрегаты, вы должны вычислять их. (Да, я знаю, что это непрактично, но это теория отношений.)

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

для ваших примеров следуйте дизайну хранилища данных, чтобы найти более прагматичный тест:

не могли бы вы нарезать и кости другим ключом?

подумайте о своем статистическом факте как точка, окруженная тремя измерениями: (SN, тест, статистика). Это действительно так? (Со сводными данными, это часто мутно.)

вместо этого давайте рассмотрим подробные данные, которые мы должны были сохранить: SN, Test, Score. Ясно, что на пересечении этих двух измерений есть два измерения (SN, Test) и одна мера (оценка). Мы можем получить любое количество статистических данных из этих подробных данных, используя измерение (SN или Test)

для примера батареи вы, вероятно, do хотите создать его как базу данных EAV вместо более типичной реляционной базы данных. Ваши измерения (AvergaeCurrent и BatteryCapacity) дают вам веские основания использовать Объект-Атрибут-Значение проектирование баз данных.

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


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

дизайн 1

SN     Test1_Max   Test1_Min    Test1_Mean  Test2_Max   Test2_Min    Test2_Mean
2093      23          2            15         54          -24           45  

это лучшее с точки зрения производительности. Для этого не требуется никаких соединений. Если число поля детерминированы и не произвольны (например, у каждого человека не более двух тестовых баллов), то это лучше, хотя и более жестко, если вы решите связать более двух тестовых баллов с человеком. С ЗП unique здесь для каждой строки компонент database engine может вернуться, как только найдет совпадение, что является еще одной причиной повышения производительности.

Дизайн 2

SN     Test      Max    Min    Mean     
2093    1        23     2      15       
2093    2        54     -24     45      

это полезно, если SN 2093 может иметь N тестов в своем профиле. Аналогично, если количество тестов, скажем, 10 м, тогда тоже эта конструкция лучше, чем иметь 30 столбцов. Каждый запрос и сравнение будут довольно тяжелыми. Это также полезно, если ваше приложение требует запросы, где он хочет получить лучший тест для студентов 2093 или при желании сделать некоторые аналитики и отчетности вокруг результатов тестов. Это более гибкий, хотя и немного медленнее, чем предыдущий. Я предпочитаю это, потому что у меня есть предчувствие, что вам, вероятно, будет интересна статистика тестов и студенты может иметь более двух тестов каждый.

дизайн 3

SN     Test    Statistic    Value
2093    1        Max          23
2093    1        Min          2
2093    1        Mean         15       
2093    2        Max          54
2093    2        Min         -24
2093    2        Mean         45  

это полезно, если ваши запросы были заинтересованы в значениях больше всего. Например, если вас интересует, сколько значений было больше 80, это будет быстро. В вашем случае это не имеет смысла. В конечном итоге вы будете делать слишком много самостоятельных соединений. Чтение будет медленным! Однако записи, вероятно, будут быстрее, потому что вы можете быстро обновить max score for SN 2093 и Test 2 (предполагая, что столбец статистики является перечислением вместо строки, потому что сравнение строк может быть дорогостоящим).

дизайн 4

SN      AverageCurrent (mA)    BatteryCapacity (mA)  
2093          200                    540  

дизайн 5

SN      mA_Measuremnt       Value
2093    AverageCurrent      200 
2093    BatteryCapacity     540 

те же аргументы применить. Это действительно зависит от того, собираетесь ли вы оптимизировать чтение или запись? Например, для веб-приложений, Если вам это сойдет с рук, я предпочитаю дизайн 1. Например, я обычно знаю, что у пользователя будет не более 3 телефонов числа, поэтому я сделаю их полями в столбце пользователя и избегу соединений. Чтение выполняется быстро, хотя для записи некоторых полей требуется значение null.


когда вы уверены, что "тест" будет (когда-либо) иметь только Max, Min и Mean - > использовать дизайн 2. Однако, если возможно, что в будущем появится новая "статистика", лучше использовать дизайн 3.

ответ:

следует ли удалять и нормализовать повторяющиеся группы только в том случае, если они точно совпадают с доменом и имеют одинаковое значение?

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


Я предлагаю перемещать повторяющиеся группы только в отдельные таблицы, если они имеют переменную длину. Если у вас когда-либо будут только Phone1, Phone2 и Phone3, нет необходимости их разделять. В другом случае, если количество повторений варьируется, то лучше разработать отдельную таблицу.

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


дизайн 1 фактически находится в 1NF, если у вас есть ПК на CustID. Это может быть в 3NF, если данные не зависят ни от чего, кроме PK, например Phone1, не повторяется для другого CustID.

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