Неправильные методы проектирования баз данных: совершаете ли вы эти ошибки?

Опубликовано: 2022-03-11

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

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

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

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

Плохая практика № 1: игнорирование цели данных

Данные сохраняются для последующего использования, и цель всегда состоит в том, чтобы хранить и извлекать их наиболее эффективным способом. Для этого разработчик базы данных должен заранее знать, что будут представлять данные, как они будут получены и с какой скоростью, каков будет их рабочий объем (т. е. сколько данных ожидается) и, наконец, , как он будет использоваться.

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

Но, конечно, объем данных — не единственный аспект, который следует учитывать, поскольку назначение данных также влияет на уровень нормализации, структуру данных, размер записи и общую реализацию всей системы.

Таким образом, доскональное знание цели системы данных, которую вы создаете, приводит к соображениям при выборе ядра базы данных, сущностей для проектирования, размера и формата записи, а также политик управления ядром базы данных.

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

Плохая практика № 2: плохая нормализация

Проектирование базы данных не является детерминированной задачей; два проектировщика баз данных могут следовать всем правилам и принципам нормализации для данной задачи, и в большинстве случаев они будут генерировать разные макеты данных. Это присуще творческой природе разработки программного обеспечения. Тем не менее, есть некоторые методы анализа, которые имеют смысл в каждом случае, и следование им — лучший способ получить базу данных, которая работает наилучшим образом.

Изображение одного набора данных, ведущего к двум разным макетам

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

Если вы столкнулись с таблицами, которые не соответствуют 3NF, 2NF или даже 1NF, рассмотрите возможность изменения дизайна этих таблиц. Усилия, которые вы вкладываете в это, окупятся в очень краткосрочной перспективе.

Плохая практика № 3: Избыточность

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

Избыточные поля и таблицы — это кошмар для разработчиков, поскольку они требуют бизнес-логики для поддержания многих версий одной и той же информации в актуальном состоянии. Это накладные расходы, которых можно избежать, если строго следовать правилам нормализации. Хотя иногда резервирование может показаться необходимым, оно должно использоваться только в очень специфических случаях и должно быть четко задокументировано, чтобы его можно было учитывать в будущих разработках.

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

Плохая практика № 4: плохая ссылочная целостность (ограничения)

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

Плохая практика № 5: Неиспользование возможностей ядра БД

Когда вы используете ядро ​​базы данных (DBE), у вас есть мощное программное обеспечение для ваших задач обработки данных, которое упростит разработку программного обеспечения и гарантирует, что информация всегда верна, безопасна и пригодна для использования. DBE предоставляет такие услуги, как:

  • Представления, которые обеспечивают быстрый и эффективный способ просмотра данных, обычно денормализуя их для запросов без потери правильности данных.
  • Индексы, которые помогают ускорить запросы к таблицам.
  • Агрегатные функции, помогающие анализировать информацию без программирования.
  • Транзакции или блоки предложений, изменяющих данные, которые все выполняются и фиксируются или отменяются (откатываются), если происходит что-то непредвиденное, таким образом сохраняя информацию в постоянно правильном состоянии.
  • Блокировки, обеспечивающие безопасность и правильность данных во время выполнения транзакций.
  • Хранимые процедуры, предоставляющие функции программирования для решения сложных задач управления данными.
  • Функции, позволяющие выполнять сложные вычисления и преобразования данных.
  • Ограничения, которые помогают гарантировать правильность данных и избегать ошибок.
  • Триггеры, помогающие автоматизировать действия при возникновении событий с данными.
  • Оптимизатор команд (планировщик выполнения), который работает под капотом, гарантируя, что каждое предложение выполняется наилучшим образом, и сохраняет планы выполнения для будущих случаев. Это одна из лучших причин для использования представлений, хранимых процедур и функций, поскольку их планы выполнения постоянно хранятся в DBE.

Незнание или игнорирование этих возможностей приведет разработку к крайне неопределенной траектории и, несомненно, к ошибкам и будущим проблемам.

Плохая практика № 6: Составные первичные ключи

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

Изображение составного первичного ключа

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

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

Плохая практика № 7: плохое индексирование

Иногда у вас будет таблица, которую вам нужно запросить по многим столбцам. По мере роста таблицы вы заметите, что операции SELECT для этих столбцов замедляются. Если таблица достаточно велика, вы логично подумаете о создании индекса для каждого столбца, который вы используете для доступа к этой таблице, но почти сразу обнаружите, что производительность операций SELECT улучшается, а операций INSERT, UPDATE и DELETE падает. Это, конечно, связано с тем, что индексы должны быть синхронизированы с таблицей, что означает огромные накладные расходы для DBE. Это типичный случай чрезмерного индексирования, который можно решить разными способами; например, имея только один индекс для всех столбцов, отличных от первичного ключа, который вы используете для запроса таблицы, упорядочивание этих столбцов от наиболее часто используемых к наименее может обеспечить лучшую производительность во всех операциях CRUD, чем один индекс для каждого столбца.

С другой стороны, наличие таблицы без индекса по столбцам, которые используются для запросов к ней, как мы все знаем, приведет к снижению производительности при выполнении операций SELECT.

Кроме того, эффективность индекса иногда зависит от типа столбца; индексы по столбцам INT показывают наилучшую возможную производительность, но индексы по VARCHAR, DATE или DECIMAL (если это когда-либо имеет смысл) не так эффективны. Это соображение может даже привести к перепроектированию таблиц, доступ к которым должен осуществляться с максимально возможной эффективностью.

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

Плохая практика № 8: плохие соглашения об именах

Это то, с чем программисты всегда сталкиваются, когда сталкиваются с существующей базой данных: понимание того, какая информация в ней хранится, по именам таблиц и столбцов, потому что часто другого пути нет.

Имя таблицы должно описывать, какую сущность она содержит, а имя каждого столбца должно описывать, какую информацию он представляет. Это легко, но становится сложно, когда таблицы должны быть связаны друг с другом. Имена начинают запутываться и, что еще хуже, если соглашения об именах путают с нелогичными нормами (например, «имя столбца должно быть 8 символов или меньше»). Конечным последствием является то, что база данных становится нечитаемой.

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

  • Нет ограничений на размер имени таблицы или столбца. Лучше иметь описательное имя, чем аббревиатуру, которую никто не помнит или не понимает.
  • Равные имена имеют одинаковое значение. Избегайте полей с одинаковыми именами, но с разными типами или значениями; это рано или поздно приведет к путанице.
  • Если нет необходимости, не будьте лишним. Например, в таблице «Товар» нет необходимости иметь такие столбцы, как «ИмяТовара», «ЦенаТовара» или подобные имена; «Имя» и «Цена» достаточно.
  • Остерегайтесь зарезервированных слов DBE. Если столбец должен называться «Index», что является зарезервированным словом SQL, попробуйте использовать другое, например «IndexNumber».
  • Если вы придерживаетесь простого правила первичного ключа (одиночное целое число генерируется автоматически), назовите его «Id» в каждой таблице.
  • При присоединении к другой таблице определите необходимый внешний ключ как целое число с именем «Id», за которым следует имя присоединяемой таблицы (например, IdItem).
  • При именовании ограничений используйте префикс, описывающий ограничение (например, «PK» или «FK»), за которым следует имя задействованной таблицы или таблиц. Конечно, экономное использование символов подчеркивания («_») помогает сделать текст более читабельным.
  • Чтобы назвать индексы, используйте префикс «IDX», за которым следует имя таблицы и столбец или столбцы индекса. Кроме того, используйте «UNIQUE» в качестве префикса или суффикса, если индекс уникален, и подчеркивайте, где это необходимо.

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

Некоторые заключительные замечания

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

В Интернете есть хорошие рекомендации по проектированию баз данных, а также плохие методы и вещи, которых следует избегать при проектировании баз данных. Просто сделайте свой выбор и придерживайтесь его.

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