Использование внешних ключей при обращении к агрегатным корням по id - PullRequest
0 голосов
/ 28 мая 2019

Рекомендуется ссылаться на другой совокупный корень по идентификатору, а не по ссылке (см. «Реализация доменного дизайна», стр. 359 и далее).

// direct reference
class AggregateRootA(val b: AggregateRootB)

// reference by ID (preferred)
class AggregateRootA(val b: AggregateRootBId)

class AggregateRootB(val id: AggregateRootBId)
class AggregateRootBId(val id: Long)

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

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

Есть ли минус в использовании внешнего ключа, кроме немного более громоздкого тестирования?

Ответы [ 2 ]

2 голосов
/ 28 мая 2019

Есть ли какой-либо недостаток использования внешнего ключа здесь, кроме немного более громоздкого тестирования?

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

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

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

Короче говоря, тщательно измеряйте затраты, связанные с наличием ограничения, с преимуществами его наличия.

1 голос
/ 28 мая 2019

Это слишком долго, чтобы добавить в качестве комментария, но я просто добавляю к тому, что @VoiceOfUnreason ответил, поэтому, пожалуйста, примите этот ответ, а не это:)

Просто чтобы быть педантичным по этому поводу: вы имеете в виду DRI (декларативную ссылочную целостность), поскольку даже отношение внешнего ключа может быть отключено.

В DRI нет ничего плохого по своей сути, так как он имеет вполне обоснованное назначение. Это, конечно, будет иметь смысл в том же ограниченном контексте, что и данные в одной базе данных. Для разных BC вы можете либо вообще отказаться от применения отношения и работать только с денормализованными данными, либо применить отношение путем сохранения объектов значений в хранилище данных вашего BC. Агрегаты из "чужой" БК будут ВО в вашем БК. В этом случае все, что упомянуто @VoiceOfUnreason вступает в игру. В некоторых случаях может иметь смысл обеспечить, чтобы определенные изменения состояния происходили в разумном порядке. Например, вы, возможно, захотите зарегистрировать клиента, прежде чем активировать телефонную линию.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...