Datomic - db/isComponent эквивалентно обеспечению зависимости внешнего ключа?

В документации Datomic Schema - они упоминают атрибут схемы, называемый db/isComponent, Похоже, это относится к отношениям, определенным :db.type/ref,

db/isComponent не используется в примере Сиэтла. Справедливо ли сказать, что :db.type/ref отношения в Datomic не являются "принудительными" (для использования концепций зависимостей внешнего ключа реляционной базы данных) - если вы не установите их с помощью db/isComponent?

2 ответа

Решение

Сдерживающие отношения (:db.type/ref + :db/isComponent)

:db/isComponent используется для указания отношений содержания, т.е. отношения композиции из UML. Вы можете думать об этом как о типе отношения " А имеет Б ". Модельная часть простого блога является ярким примером:

Статья-Комментарий

В Datomic, если вы используете :db/isComponent атрибут как часть отношения Article-Comments выше, отвод статьи также отменит все ее комментарии. Для полного примера кода посмотрите на отношения Datomic: сдерживание, то есть суть db / isComponent.

Обратите внимание, что в Datomic нет ничего, что мешало бы вам добавлять неправильный тип сущности в :db.type/ref приписывать. В приведенном выше примере Datomic позволит вам добавить ссылку на сущность "Автор" (а не комментарий), не обращая на это особого внимания. Вот где ограничения внешнего ключа вступают в игру.

Ограничения внешнего ключа (:db.type/ref + функции базы данных)

Datomic определяет отношения, используя :db.type/ref атрибут, но на самом деле ничего не навязывает им. Чтобы использовать произвольные ограничения внешнего ключа, вам нужно вместо этого использовать функции базы данных.

В базе данных Сиэтла вы упоминаете, :community/orgtype атрибуты должны ссылаться только на несколько допустимых значений перечисления (:community.orgtype/*) но на самом деле нет принудительного исполнения во время выполнения:

введите описание изображения здесь

Чтобы показать, как произвольные ограничения внешнего ключа могут быть реализованы в Datomic, я написал функцию базы данных (называемую add-fk), который предотвращает связывание неверного значения перечисления с :community/orgtype атрибутов.

Для полного примера кода посмотрите на Datomic: функции базы данных и суть ограничений внешнего ключа. Например, add-fk Поведение функции базы данных показано ниже:

 ;; will succeed
 [[:db/add #db/id [:db.part/user] :community/name "15th Ave Community"]
  [:add-fk #db/id [:db.part/user] :community/orgtype :community.orgtype/personal]])

 ;; will fail
 [[:db/add #db/id [:db.part/user] :community/name "15th Ave Community"]
  [:add-fk #db/id [:db.part/user] :community/orgtype :community.type/email-list]])
 ;; java.lang.Exception: :community.type/email-list is not one of 
 ;; [[:community.orgtype/community], [:community.orgtype/commercial], 
 ;; [:community.orgtype/personal], [:community.orgtype/nonprofit]]

Нет. В Datomic db/isComposite относится к композиции (в отличие от агрегации) в смысле OOP/UML.

Если для db/isComposite задано значение true, то при удалении сущности все подкомпоненты также извлекаются. Когда вы касаетесь объекта, все его подкомпонентные объекты затрагиваются рекурсивно.

Рассмотрим 2 разных примера отношений из мира электронной коммерции:

1) Клиент ---- UserPreferences

Как правило, это композиция. Время жизни объекта предпочтений зависит от времени жизни объекта Customer. В Datomic ссылка userPreferences на Customer должна иметь атрибут db/isComposite, установленный в значение true.

2) Клиент ---- OrderItem

Обычно это агрегация. OrderItem может существовать, даже если Клиент был удален. Это тип ссылки по умолчанию в Datomic.

Реляционная модель реализует обе зависимости как внешние ключи, поэтому с точки зрения представления ответ будет следующим: да, db / isComponent может быть представлен в СУБД как ссылочное ограничение (FOREIGN KEY) с действием CASCADE, но концептуально он не эквивалентен.

Другие вопросы по тегам