При использовании ORM на что нужно обращать внимание при разработке базы данных

19

На что следует обратить внимание при разработке базы данных, когда вы знаете, что к базе данных будет осуществляться доступ с помощью Википедии по объектному реляционному сопоставлению (ORM) ? Также см. Entity Framework NHibernate или LLBLGenPro.

В качестве примера я отмечу ограничение в 2100 параметров для вызова RPC SqlServer. Это проблема при использовании LLBLgen и объединении таблиц, когда были использованы составные первичные ключи, см. Статью MSDN для составных ключей .

BozoJoe
источник
4
Без обид, но «объединение таблиц с более чем одним первичным ключом» .. это переопределяет одно из основных правил таблицы, одно PK на таблицу. Что именно вы имели в виду?
Marian
Как это достигает предела 2100 параметров? У вас есть таблицы с таким количеством столбцов? Кроме того, я предполагаю, что вы имеете в виду «объектно-реляционное сопоставление», а не «объектно-ролевое моделирование»
Джон Сондерс
Ограничение параметра 2100 иногда является проблемой, если вы передаете большой список значений в SQL 'IN' (массив LINQ.Contains (member)). Однако это не имеет ничего общего с дизайном базы данных; это больше проблема шаблона запроса. Самый простой обходной путь для ORM, которые «страдают» от этого, состоит в том, чтобы вставить список во временную [постоянную] таблицу и присоединиться к ней и / или использовать подзапрос, который выбирает элементы для запроса, откуда бы они ни исходили. (Передача тысяч элементов в SQL 'IN', как правило, плохо, независимо от того, используете ли вы OR OR или нет).
КристоферА
@Джон, да объектно-реляционное сопоставление
BozoJoe
4
@BozoJoe: таблица может - по определению - иметь только один первичный ключ. Не существует СУБД, которая позволила бы вам определить более одного первичного ключа для одной таблицы.
a_horse_with_no_name

Ответы:

17

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

Я действительно пошел бы другим путем и спросил бы, что я должен знать об ОРМ. Убедитесь, что вы знаете: - Как мне профилировать запросы? - Как я могу переопределить ORM и написать свой собственный запрос? - Могу ли я использовать сохраненные процы вместо этого?

База данных должна быть независимой от ORM, так как, скорее всего, она переживет приложение.

Эрик Хамфри - Лотсхелп
источник
+1: «База данных должна быть независимой от ORM». Придерживайтесь стандартов проектирования баз данных, и хорошие ORM тоже будут счастливы.
MicSim
12
  1. Никогда не позволяйте ORM создавать или обновлять схему. Всегда используйте его сгенерированный SQL в качестве шаблона, но прежде чем вносить изменения, просмотрите его (я видел, как наш ORM создает избыточные индексы, использует плохие типы данных ... все эти плохие вещи)

  2. Знайте, что ваша ORM не может сделать. Некоторое время Django не поддерживал группу через ORM, что доставляло боль (все еще остается интересным для старых систем!). Таким образом, знание ограничений ORM является обязательным для администратора баз данных, даже если они не являются теми, кто пишет код для ORM

  3. Периодически собирайте медленные журналы, агрегируйте их через mysqlslowlog и просматривайте топ-10 или около того. В основном это покажет вам запросы, которые заняли наибольшее общее время. Запрос, который занимал в среднем 1 секунду, но выполнялся 50 000 раз за последний месяц, показался бы в этом сводном отчете большим пальцем;)

Я бы не сказал пойти так экстремально, чтобы полностью сбросить ORM. Если ваши разработчики, использующие ORM, не являются администраторами баз данных, они, скорее всего, напишут SQL, такой же плохой или хуже, чем ORM. Таким образом, в конечном итоге это упадет на администратора, чтобы посмотреть, что происходит.

TechieGurl
источник
1
И рассмотрите возможность размещения очень сложной логики в хранимой процедуре. ORM могут вызывать хранимые процессы, и для очень сложной логики проще настроить производительность процесса.
HLGEM
7

Есть несколько вещей, которые я сразу заметил в устаревшей базе данных, которая отличается от базы данных, созданной ORM, такими как Sequel и ActiveRecord для Ruby.

  1. Использование первичного ключа во всех таблицах называется 'id'. Да, это может быть отменено, но idэто по умолчанию.
  2. Использование множественных имен для таблиц.
  3. Использование символов подчеркивания («snakecase») для разделения слов, создающих описательные имена таблиц и полей.
  4. Использование _idдобавляется к внешним ключам: макет, как правило, похож referenced_table_id.

Я писал свой SQL вручную в течение многих лет, потому что я не доверял ORM, но в последние два или три года я начал использовать два ранее упомянутых ORM, и меня впечатляет то, насколько хорошо они интегрируются с существующими базами данных, и насколько хорошо они могут расшифровать базу данных, если соблюдаются их соглашения, или я найду время, чтобы дать им подсказки, необходимые для понимания устаревшей БД.

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

жестяной человек
источник
1
К вашему сведению: существуют инструменты для решения различий в соглашениях об именах для многих картографических операторов. У меня есть надстройка для Visual Studio, которая заботится об этом для Entity Framework и Linq-to-SQL с именованием на основе правил; см. huagati.com/dbmltools для более подробной информации об этом.
КристоферА
1
Id является антипаттерном SQL для именования поля id и не должен использоваться.
HLGEM
Не хочешь объяснить, почему? Как мы обрабатываем отношения между таблицами, когда нам нужно выполнять поиск типа «один ко многим» и «много к одному»? В ORM, которые я использую, не используя ID, определенно идет против течения.
Жестянщик
2

Это немного зависит (:)) от того, какой маппер OR вы используете, так что потратьте некоторое время на изучение того, что db поддерживает рассматриваемый маппер OR.

Например, операторы сопоставления Microsoft не поддерживают все встроенные типы данных SQL Server, не поддерживают некоторые из новых / расширенных функций TSQL (на ум приходят рекурсивные запросы, советы по оптимизации и т. Д.).

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

Для хорошей производительности БД (и для сохранения здравомыслия БД :)) вы все равно должны следовать передовым методам, когда дело доходит до проектирования схемы БД; сначала нормализуйте и денормализуйте там, где это необходимо. На стороне кода, не переусердствуйте с вашей объектной моделью ; даже если OR mapper поддерживает сложные модели наследования и сущности, которые объединяют много таблиц, это также области, где вы рискуете столкнуться с проблемами из-за слишком сложных запросов, попадающих в базу данных и т. д. Профиль, профиль, профиль и не просто использовать ORM сгенерированные запросы как должное. Имейте в виду, что запросы, сгенерированные сопоставителем OR, часто могут быть настроены так же, как обычные запросы SQL, и что два функционально эквивалентных запроса на стороне объекта (например, запросы linq) могут иногда приводить к совершенно разным запросам SQL.

Кристофера
источник