封じ込め関係 ( :db.type/ref
+ :db/isComponent
)
:db/isComponent
包含関係、つまり UML からの構成関係を指定するために使用されます。「 AにはBがある」というような関係と考えることができます。シンプルなブログの一部をモデル化するのは明確な例です:
Datomic では、:db/isComponent
上記の Article-Comments 関係の一部として属性を使用すると、記事を撤回すると、そのコメントもすべて撤回されます。完全なコード サンプルについては、Datomic: 包含関係、つまり db/isComponent gistを参照してください。
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]]