Проектирование баз данных, 11 важных правил
Когда разработчики проектируют базу данных, они руководствуются 3 нормальными формами. Они склонны считать, что нормализация - единственный способ проектирования. Следуя такому мнению, они часто попадают в тупик, когда весь проект движется вперед.
Эти правила нормализации являются важными рекомендациями, но принятие их в качестве единственно верного ориентира вызывает проблемы. Ниже приведены 11 правил для успешного проектирования базы данных.
Правило 1: Какова природа приложения (OLTP или OLAP)?
Когда вы начинаете разработку базы данных, первое, что нужно определить - природа приложения, которое вы разрабатываете: будет оно транзакционное или аналитическое? Многие разработчики находят применение трем нормальным формам не задумываясь о характере приложения, а затем у них возникают вопросы о том, как получить информацию о производительности и настройке. Как уже сказано выше, есть два вида приложений: основанные на транзакциях и аналитические. Давайте разберемся, что это за типы.
Транзакционный: в этом типе приложения ваш конечный пользователь больше интересуется четырьмя функциями CRUD: созданием, чтением, обновлением и удалением записей. Официальное название такой базы данных - OLTP.
Аналитический: в таких приложениях ваш конечный пользователь больше заинтересован в анализе, отчетности, прогнозировании и т. д. Эти типы баз данных имеют меньшее количество вставок и обновлений. Основная цель здесь - собрать и проанализировать данные как можно быстрее. Официальное название такой базы данных - OLAP.
Если вы считаете, что вставки, обновления и удаления будут использоваться чаще, то создайте нормализованный дизайн таблицы, или же создайте плоскую денормализованную структуру базы данных.
Ниже приведена простая диаграмма, показывающая, как имена и адрес в левой части составляют простую нормализованную таблицу. С помощью денормализованной структуры мы создали структуру плоской таблицы.
Правило 2: Разбейте свои данные на логические части, упростите себе работу
Это правило на самом деле является первым правилом из 1-й нормальной формы. Одним из признаков нарушения этого правила является то, что ваши запросы используют слишком много функций синтаксического анализа, таких как SUBSTRING, CHARINDEX и т. д., Тогда, вероятно, это правило необходимо применять.
К примеру, ниже приведена таблица с именами учеников. Если вам понадобится запросить имена учеников,, содержащих «Koirala», но не содержащих «Harisingh», представьте, какой запрос вы получите.
Поэтому лучше было бы разбить это поле на логические части, чтобы мы могли писать чистые и оптимальные запросы.
Правило 3: Не переусердствуйте с правилом 2
Разработчики - люди, зачастую воспринимающие все буквально. Если вы скажете им как нужно делать, они будут делать только так и могут переусердствовать, что может привести к нежелательным последствиям. Это также относится к правилу 2, о котором мы только что говорили выше. Когда вы думаете о декомпозиции, остановитесь и спросите себя, насколько она нужна? Разложение должно быть обдуманным и логичным.
Например,ниже вы видите поле номера телефона. Вряд ли вы часто будете использовать коды ISD для телефонных номеров отдельно (пока ваша заявка не потребует этого). Поэтому было бы разумным решением не разбивать его, поскольку это может привести к большему количеству осложнений.
Правило 4: Относитесь к дублирующим неоднородным данным как к своему главному врагу.
Соберите и обработайте дубликаты данных. Основная проблема относительно повторяющихся данных заключается не в том, что требуется пространство на жестком диске, а в путанице, которую они создают.
Например, на приведенной ниже таблице вы можете заметить, что «5th Standard» и «Fifth standard» означает то же самое.Возможно данные попали в систему из-за плохого ввода данных или плохой проверки. Если вы когда-либо захотите получить отчет, они будут отображаться как разные объекты, что очень сбивает с толку.
Одно из возможных решений - перемещение в другую основную таблицу и их передача через внешние ключи. На рисунке ниже показано, мы создали новую главную таблицу под названием «Standards» и связали ее с помощью простого внешнего ключа.
Правило 5: Следите за данными, заполненные разделителями
Второе правило 1-й нормальной формы говорит избегать повторения групп. Пример повторяющихся групп отображен на рисунке ниже. Если вы внимательно изучите поле «Syllabus», то увидите, что там слишком много данных. Эти поля называются «Повторяющиеся группы». Если нам нужно манипулировать этими данными, запрос будет сложным, а производительность запросов оставит желать лучшего.
Эти типы столбцов, которые имеют заполненные разделителями данные, нуждаются в особом внимании, и лучшим подходом было бы переместить эти поля в другую таблицу и связать их с ключами для лучшего управления.
Итак, теперь применим второе правило 1-й нормальной формы: «Избегайте повторения групп». Вы можете видеть на приведенном выше рисунке, что мы создали отдельную таблицу учебных планов - Syllabus Table, а затем сделал отношение «многие ко многим» (many-to-many relationship) к таблице предметов - Subject Table.
При таком подходе поле «Syllabus» в основной таблице больше не повторяется и имеет разделители данных.
Правило 6: Следите за частичными зависимостями
Следите за полями, которые частично зависят от первичных ключей. Например, в приведенной выше таблице мы видим, что первичный ключ создается с номером и стандартом. Теперь внимательно посмотрите на поле «Syllabus»: оно связано со стандартом, а не со студентом напрямую (roll number).
Учебный план (syllabus) связан со стандартом, по которому учится студент, а не непосредственно со студентом. Поэтому, если завтра мы хотим обновить учебный план, мы должны обновить ее для каждого учащегося, что кропотливо и нелогично. Имеет смысл перемещать эти поля и связывать их со стандартной таблицей.
Посмотрите, как мы переместили поле «Syllabus» и привязали его к таблице стандартов.
Это правило не что иное, как 2-я нормальная форма: «Все ключи должны зависеть от полного первичного ключа, а не частично».
Правило 7. Тщательно выбирайте производные столбцы
Если вы работаете над приложениями OLTP, избавление от производных столбцов было бы хорошей мыслью, если только не существует веской причины для повышения производительности. В случае работы с OLAP, где нам нужно производить много сумм и вычислений, эти поля необходимы для повышения производительности.
На приведенном выше рисунке вы можете увидеть, как среднее поле зависит от меток и объекта. Это также одна из форм избыточности. Подумайте, действительно ли нужны поля, полученные из других полей?
Это правило также выражено в 3-й нормальной форме:«Ни один столбец не должен зависеть от других столбцов непервичного ключа». Не стоит применять это правило вслепую, так как не всегда избыточные данные плохие. Если избыточные данные являются расчетными данными, проанализируйте ситуацию, а затем решите, хотите ли вы реализовать третью нормальную форму.
Правило 8: Не следует избегать избыточности, если в основе лежит производительность
Пусть избежание избыточности не будет для вас строгим правилом. Если есть настоятельная потребность в производительности, подумайте о денормализации. При нормализации вам нужно создавать соединения со многими таблицами, а при денормализации, объединения сокращают и, таким образом, повышают производительность.
Правило 9: Многомерные данные - совсем другая вещь.
Проекты OLAP в основном касаются многомерных данных. К примеру, вы хотите получить данные о продажах по стране, клиенту и дате. Иными словами, вы смотрите на данные о продажах, которые имеют три пересечения измерений.
Для таких ситуаций более рациональным является дизайн размеров и фактов. Простыми словами вы можете создать простую центральную таблицу фактов продаж, в которой есть поле суммы продаж, и она связывает все таблицы измерений с использованием отношения внешнего ключа.
Правило 10: Централизуйте таблицы имен и значений.
Много раз я сталкивался с таблицами имен и значений. Они предполагают наличие ключа и некоторых данных с ним связанных. Например, на приведенном ниже рисунке вы видите, что у нас есть таблица валют (currency table) и таблица стран (country table). Если вы внимательно посмотрите на данные, в них на самом деле есть только ключ и значение.
Для таких таблиц целесообразно создать центральную таблицы и дифференцировать данные с использованием поля “тип”.
Правило 11: Самореференция PK и FK для неограниченных иерархических данных
Мы неоднократно сталкиваемся с данными с неограниченной иерархией типа «родители-потомки» . Например, рассмотрим многоуровневый маркетинговый сценарий, в котором у продавца может быть несколько продавцов под ним. Для таких сценариев подойдет использование первичного ключа с саморегуляцией и внешнего ключа .
Смысл этой статьи не в том, чтобы не следовать нормальным формам, а в том, чтобы не действовать слепо в их рамках: учитывайте в первую очередь характер вашего проекта и тип данных, с которыми вы имеете дело.