Подтвердить что ты не робот

Почему составные клавиши обескуражены в спящем режиме?

Это из Официальное руководство Hibernate:

Существует альтернативное объявление <composite-id>, которое позволяет получить доступ к устаревшим данным с помощью составных клавиш. Его использование сильно не рекомендуется ни для чего другого.

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

Какая альтернатива? Создать дополнительный автоматически созданный столбец и использовать его в качестве первичного ключа? Мне все равно нужно запросить мои 3 столбца в любом случае!?

Короче говоря, почему это утверждение верно? и какая лучшая альтернатива?

4b9b3361

Ответ 1

Они отговаривают их по нескольким причинам:

  • они громоздки в использовании. Каждый раз, когда вам нужно ссылаться на объект (или строку), для примера в вашем веб-приложении вам нужно передать 3 параметра, а не только один.
  • они неэффективны. Вместо простого хэширования целого числа, база данных должна содержать хеширование из 3 столбцов.
  • они приводят к ошибкам: разработчики неизбежно внедряют методы equals и hashCode класса первичного ключа неправильно. Или они делают его изменчивым и изменяют свое значение после его хранения в HashSet или HashMap
  • они загрязняют схему. Если другой таблице необходимо ссылаться на эту таблицу с тремя столбцами, ей необходимо будет иметь только 3 столбца вместо одного в качестве внешнего ключа. Теперь предположим, что вы следуете одному и тому же дизайну и сделаете эту внешнюю ключевую часть из трех столбцов первичного ключа этой новой таблицы, вы быстро получите первичный ключ из 4 столбцов, а затем 5-столбцовую PK в следующей таблице и т.д. и т.д., что приводит к дублированию данных и грязной схеме.

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

Ответ 2

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

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

Мифы на натуральных клавишах

  • Композитные клавиши менее эффективны, чем суррогатные ключи. Нет! Это зависит от используемого механизма базы данных:
  • Природные ключи не существуют в реальной жизни. Извините, но они существуют! В авиационной промышленности, например, следующий кортеж будет всегда уникальным в отношении данного запланированного полета (авиакомпания, departureDate, flightNumber, operatingSuffix). В более общем плане, когда набор бизнес-данных гарантированно будет уникальным по заданному стандарту, тогда этот набор данных является [хорошим] кандидатом на естественный ключ.
  • Натуральные клавиши "загрязняют схему" дочерних таблиц. Для меня это скорее чувство, чем реальная проблема. Наличие первичного ключа из 4 столбцов по 2 байта может быть более эффективным, чем один столбец из 11 байтов. Кроме того, 4 столбца могут использоваться для непосредственного запроса дочерней таблицы (с использованием 4 столбцов в предложении where) без присоединения к родительской таблице.

Недостатки суррогатных ключей

Суррогатные клавиши:

  • Источник проблем с производительностью:
    • Обычно они реализуются с использованием автоинкрементных столбцов, что означает:
      • Обратная связь с базой данных каждый раз, когда вы хотите получить новый идентификатор (я знаю, что это можно улучшить с помощью кеширования или алгоритмов [seq] hilo, но все же эти методы имеют свои недостатки).
      • Если в один день вам нужно переместить свои данные из одной схемы в другую (это происходит довольно регулярно в моей компании), вы можете столкнуться с проблемами столкновения с идентификаторами. И да, я знаю, что вы можете использовать UUID, но для последних требуется 32 шестнадцатеричных цифры! (Если вы заботитесь о размере базы данных, это может быть проблемой).
      • Если вы используете одну последовательность для всех своих суррогатных ключей, то, наверняка, в вашей базе данных вы столкнетесь с разногласиями.
  • Ошибка. Последовательность имеет предел max_value, поэтому - как разработчик - вы должны обратить внимание на следующие факты:
    • Вы должны выполнить цикл (когда достигнуто максимальное значение, оно возвращается к 1,2,...).
    • Если вы используете последовательность в качестве порядка (по времени) ваших данных, тогда вы должны обрабатывать случай циклирования (столбец с Id 1 может быть более новым, чем строка с максимальным значением Id - 1).
    • Убедитесь, что ваш код (и даже ваши клиентские интерфейсы, которые не должны выполняться, поскольку он должен быть внутренним идентификатором) поддерживает целые числа 32b/64b, которые вы использовали для хранения ваших значений последовательности.
  • Они не гарантируют дублирование данных. Вы всегда можете иметь 2 строки со всеми одинаковыми значениями столбцов, но с другим сгенерированным значением. Для меня это проблема THE суррогатных ключей с точки зрения дизайна базы данных.
  • Подробнее в Википедии...

Почему Hibernate предпочитает/нуждается в суррогатных ключах?

Как указано в Java Persistence with Hibernate:

Более опытные пользователи Hibernate используют исключительно saveOrUpdate(); его гораздо проще позволить Hibernate решить, что нового и что старое, особенно в более сложной сети объектов со смешанным состоянием. только (не очень серьезный) недостаток эксклюзивного saveOrUpdate() что он иногда не может догадаться, является ли экземпляр старым или новым без запуска SELECT в базе данных, например, когда класс сопоставлен с естественным составным ключом и без версии или временной метки свойство.

Некоторые проявления ограничения (вот как, я думаю, мы должны это назвать) можно найти здесь.

Заключение

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

Надеюсь, что это помогло кому-то!

Ответ 3

Я рассмотрел бы проблему с дизайнерской точки зрения. Это не просто, если Hibernate считает их хорошими или плохими. Реальный вопрос: являются ли естественные ключи хорошими кандидатами хорошими идентификаторами для моих данных?

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

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

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

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

Природные клавиши приносят только недостатки: я не могу придумать единственное преимущество для использования естественных ключей.

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

Ответ 4

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

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

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

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

Итак, с точки зрения OP и других, которые ищут: если вы хотите остаться db-инвариантом с вашей разработкой (в которой Hibernate специализируется) - используйте суррогатный метод, и когда чтение данных имеет тенденцию замедляться или вы замечаете некоторые запросы дренируют производительность, возвращаются к вашей конкретной базе данных и добавляют составные, кластерные индексы, которые оптимизируют порядок запросов.

Ответ 5

Если документация Hibernate правильно понята:

"Существует альтернативное объявление <composite-id>, которое разрешает доступ к устаревшим данным с составными ключами. Его использование сильно не рекомендуется ни для чего другого".

по теме 5.1.4. id тега xml <id>, который позволяет скопировать первичное ключевое отображение слишком рано, мы можем заключить, что в документации на спящий режим не рекомендуется использовать <composite-id> вместо тега <id> xml для композитного отображения первичного ключа и НЕ сделайте любую ссылку отрицательной для использования составных первичных ключей.