2015-10-23 8 views
0

У меня есть сомнения относительно entity vs value type в спящем режиме.
Приведем пример User и Address. Здесь Пользователь является entity и возьмем Адрес как component.Адрес как тип сущности или значения в спящем режиме

Если у пользователя может быть только один адрес, то в этом случае будет только одна таблица «Пользователь» и нет таблицы для адреса, поскольку она отображается как компонент. Но, допустим, у пользователя может быть несколько адресов, поэтому в этом случае нам нужно иметь другую таблицу, кроме пользователя, для этого сопоставления.
Здесь у меня есть два варианта: first, Адрес как объект и second Адрес как компонент.

Я понимаю, что для адреса не будет shared reference, поэтому он не должен отображаться как Entity и адрес карты как компонент. Но в этом случае я могу отобразить Address as Entity (никто не останавливает меня, чтобы сделать это). Итак, мои вопросы: если я буду сопоставлять адрес как сущность вместо компонента, будет ли какой-то недостаток.

+0

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

+0

Трудно сказать наверняка, не видя всей конструкции. Делает ли что-нибудь * еще нужно адрес? Если это так, таблица будет выглядеть как лучший вариант (это может быть так или иначе). Вы будете хранить дублированные данные в таблицах. Значение каждой * вещи *, которая нуждается в адресе, будет содержать одни и те же поля. Это не здорово. – ChiefTwoPencils

+0

@ ChiefTwoPencils- Нет, адрес не будет использоваться кем-либо, кроме пользователя. В случае множественного адреса конкретного сопоставления пользователей и компонентов нам по-прежнему требуется другая таблица. Итак, в этом случае лучше ли было бы работать с сущностью или компонентом? – Anand

ответ

0

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

Как отметили другие люди, вы получите немного лучшую производительность, если вы наберете адрес как @Embedded, а не как отдельный @Entity. Тем не менее, невозможно ответить на вопрос «сколько» будет лучше, если производительность будет зависеть от ваших прецедентов и ваших данных. Вещи, которые повлияют на вашу производительность, - это, в частности, латентность сети, фрагментация (вакуумный статус) вашей БД, создание индексов БД и конфигурация спящего режима (ленивая или нетерпевая загрузка). И в отношении «что лучше» - на этот вопрос нельзя ответить, пока все эти факторы не будут приняты во внимание.Я мог бы сказать вам, что у меня есть БД с N миллионами пользователей, где в среднем каждый пользователь имеет 15 адресов. Я выполнил выбор и получил пользователя за 120 мс, а другой - для получения всех адресов этого пользователя в 109 мс. Однако это не поможет вам ответить на ваш вопрос, поскольку ваши данные будут по-разному распределены, вы будете испытывать различную задержку в сети, время отклика БД.

Причины выбрать отображение в @Embedded:

  • Высокая производительность имеет решающее значение для вашего сценария использования или применения. Действительно ли N ms действительно для ВАШЕГО приложения?
  • Меньше дискового хранилища, используемого БД.
  • Вы не создаете БД с нуля. У вас есть уже существующая схема БД, и вы хотите получить к ней доступ через Hibernate, но не можете изменить схему.
  • Вы всегда (или почти всегда) получаете доступ к объекту Address при загрузке пользователя.
  • Вам гарантировано, что вам НИКОГДА не потребуется хранить несколько адресов для одного пользователя, или вы знаете, что вам не нужно запрашивать пользователей на основе адреса реляционным способом. Это позволит вам сериализовать коллекцию адресов в clob или blob в вашей БД. В зависимости от того, как вы это делаете, отдельные данные адреса могут быть доступны и запрошены, но становятся более интересными.

Reaons выбрать отображение в виде отдельного @Entity

  • Стилистические предпочтения и дополнительной задержки и накладные расходы приемлемы.
  • Хотите поддержать возможность иметь несколько адресов для одного пользователя в будущем И хотите фильтровать/запрашивать данные по адресам.
  • Вам часто нужен Пользователь для прецедентов, в которых адрес не имеет отношения.
  • Связанный с этим элемент: пропускная способность сети является проблемой, и вы хотите передать как можно меньше данных по сети, а данные адреса будут доступны нечасто при загрузке пользователя (настроено как ленивая загрузка)
  • Вы хотите иметь разные разрешения гранта БД для двух наборов данных. то есть одному пользователю (в данном случае, возможно, другому приложению) разрешено обновлять имя пользователя, но не адрес, тогда как другому разрешено обновлять оба.
  • У некоторых пользователей нет адреса, и вы хотите избежать нулевых проверок. Пустая коллекция - ваше стилистическое предпочтение.
+0

Преимущество для 'Entity': если вы размещаете адрес как отдельный объект, вы можете легче изменить адреса (например: глобально очистить данные адреса с помощью языковых правил). Когда приложение растет, а в других таблицах есть ссылки на адрес, вы сохраняете свои адресные данные в одной таблице. – djmj

0

Java сам по себе не имеет понятия композиции.

A class или attribute не может быть помечен как компонент или состав. Единственное отличие - это идентификатор объекта.

Компонент не имеет идентификатора, поэтому постоянный класс компонента не требует никакого свойства идентификатора или сопоставления идентификаторов.

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

+0

Не могли бы вы рассказать мне пример использования, когда мы должны идти за компонентом (не имеет идентификатора) и сущности (имеет идентификатор) – Anand

+0

Вы можете захотеть отделить их для будущих случаев, чтобы отделить их друг от друга. Также логически легче видеть разные объекты и как они разделены, даже если они находятся в одной таблице.У каждого класса есть свои цели и обязанности, поэтому они моделируются по-разному. Это также делает ваш код немного более модульным. Также не было бы соединения, так что это было бы также быстрее по производительности. – Dale

1

Адрес Entity имеет следующие недостатки:

  • Производительность в БД, потому что вам нужно дополнительно:
    • присоединиться к выберите + ограничение внешнего ключа
    • дополнительный первичный генератор ключ + индекс первичного ключа для адреса (он также увеличит размер БД)
  • Производительность и память в спящем режиме: каждый объект имеет много поддержки во время работы в спящем режиме. Например. кэш уровня спящего режима 1 - он включен по умолчанию (кеш уровня транзакции). Дешевле иметь одну сущность с 20 полями, чем 2 объекта с 10 полями в каждом + реальности между ними.
+0

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

+0

В этом случае вы можете добиться лишь небольшого улучшения уровня спящего режима. Также когда-нибудь разумно использовать типы данных json или массива в некоторой базе данных, например postgres. – sibnick

+0

Какое будет небольшое улучшение уровня Hibernate? – Anand

Смежные вопросы