Ответ 1
"Нормализовать, пока это не повредит, де-нормализуйте, пока он не сработает".
Что важно иметь в виду при разработке базы данных?
Я не хочу ограничивать свой ответ на мои потребности, поскольку я уверен, что другие могут извлечь выгоду из ваших идей. Но я планирую систему управления контентом для сайта, основанного на нескольких клиентах.
"Нормализовать, пока это не повредит, де-нормализуйте, пока он не сработает".
(Предполагая OLTP)
Нормализация ваших данных-структур. (Эффективность де-нормализации обычно может следовать позже, когда это необходимо)
Убедитесь, что вы используете ограничения (CHECK
, NOT NULL
, FOREIGN KEY
, PRIMARY KEY
и DEFAULT
), чтобы убедиться, что в базе данных сначала хранятся только правильные данные. Вы всегда можете купить более быстрое оборудование, но вы не можете покупать более правильные данные.
Установить согласованные стандарты именования. Это сэкономит несколько минут ненужного мышления в долгосрочной перспективе. (Это может считаться иронией, но я серьезно.)
И не сокращайте ничего, если это не очень распространено. Не превращайте базу данных в игру с гантелями сообщений. Удивительно, что становится очевидным через год.
Попробуйте представить SQL-запросы, которые вы будете преформировать.
Это важно, потому что вы сделаете это LOT!
Некоторые вещи я буду иметь в виду. Убедитесь, что у каждой таблицы есть способ однозначно идентифицировать записи (вы сэкономите время, затрачиваемое на то, что не делаете этого). Нормализовать, но не присоединяться к большим многоколоночным естественным клавишам, если вы не хотите, чтобы все было медленным. Используйте цифровой ключ, который автоматически генерируется в родительской таблице.
Да, подумайте о типах запросов и отчетов, которые вам нужно выполнить. Подумайте о расширяемости. Может показаться, что вам не нужно более 10 столбцов товаров в таблице заказов, но что происходит, когда вам нужно 11. Лучше иметь таблицу заказов и таблицу подробных данных заказа.
Убедитесь, что все правила целостности данных включены в базу данных. Не все изменения данных происходят из пользовательского интерфейса, и мне приходилось пытаться исправить слишком много плохо перепутанных баз данных, потому что дизайнеры полагали, что было бы хорошо вставить все правила в графический интерфейс.
Наиболее важные вещи, которые следует учитывать при планировании, - это прежде всего то, как обеспечить целостность данных (если данные бессмысленны, база данных бесполезна) и во-вторых, как обеспечить производительность. Не используйте объектную модель для создания реляционной базы данных, если вы не хотите плохой производительности.
Следующим важным моментом является защита данных и безопасность. Пользователи не должны иметь прямого доступа к таблицам базы данных. Если вашему дизайну требуется динамический SQL, он должен будет иметь этот доступ. Это плохо с точки зрения потенциального взлома в таких вещах, как атаки SQL-инъекций, но что еще более важно, это открывает вашу базу данных для внутренних людей, совершающих мошенничество. Существуют ли поля, где необходимо шифровать данные (информация о кредитной карте, пароли и номера социального страхования относятся к числу элементов, которые никогда не должны храниться в незашифрованном виде). Как вы планируете это делать и как вы планируете аудит дешифрования, чтобы люди не расшифровывали, когда им не нужно было видеть данные. Есть ли законные обручи, которые вы должны пройти (HIPPA и Sarbanes Oxley spring для ума)?
Получите действительно хорошую книгу по моделированию данных - одну, написанную истинным разработчиком баз данных, а не разработчиком .NET, который пытается научить вас, как это делается в "реальном мире".
Проблемное пространство дизайна базы данных просто слишком велико, чтобы быть значительно охваченным на форуме, подобном этому. Несмотря на это, я дам вам несколько личных указателей:
Слушайте приведенные выше сообщения о нормализации. НИКОГДА не денормализовать, потому что вы ДУМАЕТЕ, что у вас есть по соображениям производительности. Вы должны только денормализовать после того, как у вас возникнут проблемы с производительностью (в идеале, в среде QA, а не в производстве). Даже тогда подумайте, что может быть лучший способ написать ваши запросы или улучшить индексацию в первую очередь.
Ограничьте данные как можно больше. Столбцы должны быть NOT NULL как можно больше. Используйте ограничения CHECK и FOREIGN KEY, где бы они ни находились. Если вы этого не сделаете, плохие данные будут попадать в вашу базу данных и вызывать много головных болей и программирование специальных случаев.
Подумайте о своих данных, прежде чем начинать создавать таблицы. Получите хорошее представление о том, как будут протекать ваши процессы и какие данные они будут отслеживать. Часто то, что вы считаете сущностью на первый взгляд, оказывается двумя сущностями. Например, в системе, над которой я работаю, предыдущий дизайнер создал таблицу Member, и вся информация из их приложения была частью таблицы Member. Оказывается, член может захотеть изменить данные, которые были в их приложении, но нам все равно нужно отслеживать, как выглядело оригинальное приложение, поэтому приложение действительно является его собственным сущностью, а Member - это объект, который изначально может быть заполнен из приложение. Короче говоря, сделайте обширный анализ данных, не просто начинайте создавать таблицы.
Поскольку в настоящее время есть несколько сообщений, защищающих это, я добавлю еще одну вещь...
НЕ попадайте в ловушку размещения столбцов идентификаторов на всех ваших таблицах. Есть много ОЧЕНЬ хороших причин, почему современная теория дизайна баз данных использует реальные первичные ключи, и они не являются строго академическими причинами. Я работал с базами данных, которые включали сотни таблиц, многие из которых были многомиллионными таблицами строк, причем более 1000 одновременных пользователей и использование реальных первичных ключей не "ломались".
Использование столбцов ID во всех ваших таблицах означает, что вам нужно будет делать объединения нескольких таблиц, чтобы пересечь базу данных, что становится большой проблемой. Он также способствует продвижению неряшливого дизайна базы данных и даже за его пределами, что часто приводит к проблемам с повторяющимися строками. Другая проблема заключается в том, что при работе с внешними системами вам теперь нужно связывать эти идентификаторы.
Есть места для суррогатных идентификаторов - введите коды кода и концептуальные таблицы (например, таблица системных правил может использовать идентификатор, если в правилах нет реальных идентификаторов). Использование их везде - ошибка ИМО.
Это давняя дискуссия, но мое мнение по этому вопросу, за что оно стоит.
Данные вечны. Обработка идет и идет.
Получите реляционную модель как высокореализованное представление реального мира. Это больше всего на свете.
Обработка будет меняться и развиваться годами. Но ваши данные и модель данных не могут развиваться в одинаковых темпах и с такой же гибкостью. Вы можете добавить обработку, но вы не можете магически добавлять информацию. Вы не хотите удалять информацию (но можете ее игнорировать).
Получить модель справа. Сущности и отношения в ваших диаграммах должны иметь разумный смысл для случайного нетехнического пользователя. Даже прикладное программирование должно быть простым, понятным и точным.
Если вы боретесь с моделью, не придумывайте большие, сложные запросы или (что еще хуже) хранимые процедуры для решения проблем. Процедурные обходы - дорогостоящая ошибка. Поймите, что у вас есть, что вы хотите сделать, и примените принцип YAGNI, чтобы избавиться от вещей, необходимых вам.
Я знаю, что это было сказано, но нормализация, нормализация, нормализация - это ключ. Если есть экземпляр, в котором вы чувствуете, что по какой-либо причине вам необходимо хранить данные в ненормированном формате, не делайте этого. Это должно обрабатываться через представления или в отдельной базе данных отчетов. Мой другой главный совет - избегать полей text/ntext, где это возможно.
"Thumb rule of Databases - Down всегда бьет по всему!"
Примеры: Если у вас есть таблица Customer с столбцами для адреса почтового адреса и доставки и адреса фактуры... Создайте отдельную таблицу CustomerAddress с типом адреса
Если у вас есть таблица CancellationDetails с CancellationReason01, CancellationReason02, CancellationReason03.. создайте отдельную таблицу CancellationReason
Быть практичным. Имейте в виду, каковы ваши цели и не сходят с ума, создавая ненужную сложность. У меня есть некоторые настройки:
Но это средство для конца (и во многих случаях противоречиво и требуют тщательной балансировки), главное - позволить требованиям управлять дизайном. Ваш выбор того, что представляет собой отдельный объект, и что является частью другого объекта, и что такое корм для кошек (не то, о чём вы нуждаетесь), полностью зависит от ваших требований.
Если у вас есть запросы, которые вы собираетесь запустить LOT, сделайте их в хранимые процедуры. Они будут почти всегда работать быстрее.
Если вы будете искать строки вверх по полям, отличным от первичного ключа, обязательно проиндексируйте их.
Это объектно-ориентированный язык? Поэтому попробуйте моделировать объекты перед базой данных. Это поможет вам сосредоточиться на модели.
Понимайте требования так сильно, как только возможно. Затем создайте логическую схему, которая должна измениться только при изменении требований или при переходе на совершенно другой тип базы данных, такой как тот, который не использует SQL. Затем уточните и расширьте свой дизайн в физическом дизайне, который учитывает ваш конкретный продукт СУБД, ваш объем, вашу нагрузку и ваши требования к скорости.
Узнайте, как нормализовать, но также узнайте, когда нарушать правила нормализации.
Я решительно повторяю, что нормализация имеет решающее значение, с тактической де-нормализацией, чтобы следовать по производительности или другим причинам ремонтопригодности. Однако, если вы ожидаете иметь больше, чем просто несколько таблиц, я хотел бы предложить одну оговорку о нормализации, которая сделает вашу жизнь намного легче, так как число таблиц растет.
Предостережение состоит в том, чтобы сделать первичный ключ для каждой таблицы одним числовым столбцом (соответствующим вашему вкусу БД). В академической нормализации идея состоит в том, чтобы объединить все атрибуты (столбцы) объекта (таблицы), чтобы вы могли однозначно идентифицировать экземпляр того, что описывается (строка), и вы можете получить комбинированный первичный ключ с несколькими столбцами, Поэтому всякий раз, когда вы переносите этот составной ключ в качестве внешнего ключа на другие таблицы, вы дублируете эти несколько столбцов в каждой таблице, ссылающейся на него. Это может сработать для вас, если у вас будет только полдюжины таблиц. Но он быстро разваливается, когда вы идете намного больше.
Поэтому вместо многокомпонентного составного первичного ключа перейдите к последовательному числовому первичному ключу, хотя этот подход идет вразрез с некоторыми из строгих учений о нормализации.
Убедитесь, что в модели закодировано как можно больше метаданных. Должно быть возможным вывести практически любое бизнес-правило или концепцию из просто взгляда на модель данных.
Это значит, позаботьтесь о выборе имен, отражающих реальность пользователей (но не бойтесь изменить свое восприятие реальности, если оно помогает модели).
Кодировать все ограничения, которые вы можете в базе данных. Не полагайтесь на прикладной уровень, чтобы предоставлять только разумные данные. Убедитесь, что в первую очередь могут существовать только разумные данные.
Не суммируйте данные в модели. Держите модель как можно более атомной. Либо агрегировать "на лету", либо выполнять регулярные задания агрегации в сводные таблицы.
Выберите хороший раздел между схемами. Некоторое разделение имеет смысл делать с внешними ключами, а некоторые - с помощью чистого физического разделения.
Не используйте большой набор столбцов в качестве первичных ключей
Помните, что нормализация относится только к тому, что вы моделируете. Возможно, вы моделируете коллекцию объектов в своем домене. Возможно, вы записываете серию событий, в которых данные повторяются, потому что одни и те же данные применяются более одного раза. Не смешивайте две вещи.
Я согласен с тем, что знание ваших данных хорошо и нормализуется.
Что-то еще, что я хотел бы предложить, - хранить очень большие текстовые поля в отдельной таблице. Например, если у вас есть контракт, вы можете захотеть сохранить много информации о контракте в одной таблице, но сохраните юридический (и очень большой) документ в отдельной таблице. Просто введите индекс из основной таблицы в юридический документ.
Я бы сказал, что важно помнить, что структура может измениться. Поэтому не задумывайтесь над собой. Убедитесь, что все, что вы делаете, оставляет вам "комнату" и даже возможность перенести данные в другую структуру.
Как вы можете сделать первичный ключ сгенерированным по порядку номером.