Нормализация БД
Содержание |
Введение
Сразу оговорюсь, что считаю данную тему абсолютно ненужной, а обсуждаю ее только потому, что она требуется для всевозможных «тупопроверочных» работ.
В основе моей нелюбви лежит высосанность из пальца. Как и во многих других областях знаний, теория в основном развивалась значительно позднее (1970-е гг.) накопленной практики применения (примерно с середины 1960 гг. по 1970 г, IBM). Фактически она была навязыванием теоретической наукообразной «скорлупы», сложно сочетаемой с практикой. Хуже того, на планете нет ни одной БД, соответствующей всем нормальным формам. Еще хуже, что сами формы в некоторых формулировках своих определений содержат обсуждение своей же абсурдности. И, напоследок, ещё камень. Беседуя с преподавателями, разглагольствующими о бесценности изучения понятия нормализации в их учебных курсах, я заметил одну закономерность. Большинство из них вообще никогда не имели дел с программированием БД, либо делали это лишь несколько раз. Успешно, как они полагают. Само собой, что кроме аргументов «это же и так понятно/очевидно», «все/каждый это знает/понимает», «без этого вообще никак не управиться» и т.п., ответа на мой простой вопрос о прикладном назначении нормальных форм я не получил ни разу. Найдёте — пришлите, буду безмерно благодарен.
Так вот, в связи с бессмысленностью и теоретизированностью, данная страница изобилует незавершенными тезисами и обрывочными мыслями, за что приношу отдельные извинения.
Нормальная форма — требование, предъявляемое к структуре таблиц в теории реляционных баз данных для устранения из базы избыточных функциональных зависимостей между атрибутами.
На данном этапе развития мысли теоретиков, выделено 6 основных и 2 дополнительных формы нормализации. Для упрощения формулировок договоримся, что каждая последующая форма должна отвечать требованиям всех предыдущих.
- 1. (1970) Отношение находится в первой нормальной форме, когда весь набор каждого атрибута содержит только простейшее (атомарное, неделимое без потери смысла) значение, и значение каждого атрибута содержит только единичное значение от набора данных.
- 2. (1971) Каждый неключевой атрибут таблицы функционально зависит от ее потенциального ключа.
- 3. (1971) Каждый неключевой атрибут транзитивно независим от потенциального ключа таблицы. Атрибуты, которые не соответствуют описанию первичного ключа, удаляются из таблицы. (Все понятно?)
- 3a. Бойса–Кодда (1974) Каждая непростейшая функциональная зависимость в таблице является зависимостью от суперключа.
- 4. (1977) Каждая непростейшая множественная зависимость в таблице является зависимостью от суперключа.
- 5. (1979) Каждая непростейшая объединенная зависимость в таблице определяется суперключом таблицы.
- 5а. DKNF (domain-key normal form) (1981) База данных не содержит ограничений, отличных от доменных и ключевых. (По большому счету, считается, что данная форма обобщает три предыдущих из данного списка.)
- 6. (2002) Таблица соответствует всем нетривиальным зависимостям объединения.
Для первой нормальной формы имеет смысл обсуждать некоторые основополагающие (базовые) условия.
- Нет упорядочивания строк, то есть порядок строк не имеет значения и смысла.
- Столбцы также следуют в произвольном порядке.
- Отсутствуют повторяющиеся строки.
- Каждое пересечение строки и столбца содержит ровно одно значение из соответствующего набора данных.
- Все столбцы не являются составными.
Также важнейший смысл несет атомарность значения, то есть невозможность, а, скорее, ненужность дальнейшего деления. Так, полный телефонный номер содержит код страны и код региона. Если не предполагается поиск по этим критериям и привязка к ним ввода данных, то такой номер будет атомарным. В противном случае номер должен быть разделен на три части. (Последнее решение будет всегда актуально для больших БД.)
Доступ к этим материалам предоставляется только зарегистрированным пользователям!
Ключевые поля
Данное понятие имеет множество равнозначно используемых синонимов: ключ, идентификатор, ID, key.
По теории нормализации, почти любое поле БД может использоваться для однозначной идентификации записи (бред). На практике это недостижимо в принципе и для названной цели используется дополнительное поле, которое хранит уникальное значение. Его тип и размер обсуждены ниже.
Первичный ключ — поле таблицы БД, используемое для однозначной идентификации записи. Такое поле может быть только одно.
Потенциальный ключ — поле таблицы БД, которое соответствует требованиям к первичному ключу, но не используются в качестве такового.
Суперключ (superkey) — комбинация атрибутов (полей), которая может использоваться в качестве первичного ключа. Обычно в таблице можно выделить множество таких суперключей.
....
С точки зрения многих современных СУБД, идентификация записи вообще возможна только по первичному ключу. То есть понятие номера записи как бы и не существует, хотя оно есть всегда. Это приводит к огромным и неоправданным ресурсным потерям, но является отражением реальности.
Ещё более того, большинство СУБД работает с «чистым SQL», требуя обязательного наличия ключевого поля. Без этого невозможно обновление данных.
Тип данных и размер ключевого (идентификационного) поля
Для разбора этого вопроса потребуется вспомнить некоторые правила расчета количества информации. Разнообразие вариантов содержания поля равно количеству вариантов одного символа в степени количества отведенных для поля символов (n). Для двоичной записи это будет 2n, для десятичной — 10n, для русского текста — 66n, а если использовать символы Unicode — (216)n. Потенциально, из этого количества надо вычитать единицу, но нулевой символ обычно соответствует пустому значению.
Также вспомним, что в реляционной СУБД поле содержит целое количество байт.
Из сказанного выше вытекает выраженное в цифрах:
Доступ к этим материалам предоставляется только зарегистрированным пользователям!
(Естественно, надо не забывать, что, условно, первые 32 символа кодовых таблиц используются для служебных целей, но для общего понимания это несущественно.)
Теперь нужно дать оценку способности воспринимать человеком запись приведенных вариантов с точки зрения кода для каждого жителя Земли.
Доступ к этим материалам предоставляется только зарегистрированным пользователям!
Именно в связи с этим хочется обратить дополнительное внимание на целочисленный тип данных, который описывает числа по сути просто двоичной системой и, соответственно, обладает наибольшей читаемостью, емкостью и удобством манипулирования. Отсюда сделаем вывод, что для ключевых полей (идентификаторов) следует использовать поля целочисленных типов. Многие современные СУБД позволяют задать и количество байт, отводимых для этого поля, а не фиксировать его, как это практиковалось ранее. Также для них прекрасно реализовано автоматическое наращение (автоинкремент, autoincrement), что избавляет разработчика от написания сложных и крайне ответственных процедур.
Несоответствие правилам нормализации
Естественно, что эта ошибка всегда будет присутствовать у начинающих, так как сам принцип разбивки одной привычной и легко воспринимаемой таблицы на совокупность кучки мелких, которые сложно и в голове-то удержать, не встречает никакого понимания. На моем опыте нескольких тысяч человек исключений из этого правила не встретилось. Для большинства такой переход к восприятию данных дается мучительно тяжело, для 5–15% — не дается в принципе. И дело отнюдь не в неправильном изложении и т.п. Просто так устроен мозг. Все мои занятия, посвященные этой теме, всегда начинались с указания, что правила нормализации заучивать не надо, с ними можно только ознакомиться самостоятельно. Любопытных оказалось несколько человек, долго потом плевавшихся. Лично я встречал только троих людей, утверждавших, что они это знают и понимают. Один из них — Лес Пинтер. Но все они всегда выдвигали такое количество оговорок, что из них явно вытекало полное отсутствие здравого и прикладного смысла, на которые, наоборот, и надо опираться. Всегда!
Итак, упрощенная конкретизация, системно используемая на занятиях и при индивидуальных консультациях.
Доступ к этим материалам предоставляется только зарегистрированным пользователям!
....
Избыточность или денормализация
Под избыточностью БД понимают наличие данных, которые могут быть получены путем обработки других данных. То есть, с абсолютизированной точки зрения, это существенная ошибка на стадии разработки структуры. Но подобная оценка далеко не всегда правильна.
В ряде случаев в БД вводится преднамеренная избыточность с целью ускорения обработки. В качестве простого примера можно привести систему складского хранения.
Доступ к этим материалам предоставляется только зарегистрированным пользователям!
Таким образом, именно факт отсутствия продуманной денормализации будет грубой ошибкой разработки структуры БД. К сожалению, ошибкой чрезвычайно распространенной.
Чрезмерная нормализация
Да, и такое может получиться, хотя, казалось бы, чаще всего бывает наоборот.
В качестве примера приведем ФИО контактного лица в системе, где эти сведения играют минимальную роль и приведены в количестве нескольких десятков. Можно это реализовать в виде обычного текстового поля, а можно подключить справочник имен объемом в несколько десятков мегабайт. Будет занято место на диске и в памяти, оператор нас проклянет, эффект будет равен нулю, зато мы соблюдем все правила нормализации. Кстати, переделать простой вариант в сложный займет несколько часов, не считая переделки отчетов и интерфейса. Но такую нужду для приведенного примера представить невозможно.
Оценка объема БД для всех жителей планеты
По оценке, на конец 2020 года население Земли составляет около 7 830 500 000 человек, а к 2050 г. по оценке ООН, оно составит 9,5 млрд человек. Для удобства расчетов мы примем его за 10 млрд, что позволит учесть рост базы ещё на 30–35 лет (нереально большой срок для компьютерной программы) и упростит расчеты.
Упрощение будет заключаться в том, что каждый байт, отводимый под хранение сведений об одном человеке, будет давать примерно гигабайт по совокупности для всех людей.
... Посещаем занятия или думаем, гм, мозгом.