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, но концептуально он не эквивалентен.