моделирование нескольких отношений «многие ко многим» в datomic

Может быть, я все еще думаю о sql, но у меня возникли проблемы с написанием схемы datomic для простого блога. Я не очень понимаю атрибут :db/cardinality и что он означает.

С точки зрения этого типа системы, как мы моделируем эти отношения

  • Система поддерживает несколько пользователей
  • У каждого пользователя может быть много категорий
  • У каждого пользователя может быть много статей
  • В каждой категории может быть много пользователей
  • В каждой категории может быть много статей
  • Каждая статья может иметь много комментариев
  • У каждого комментария есть один пользователь

person zcaudate    schedule 06.02.2013    source источник
comment
In terms of this type of system, how do we model these relationships не уверены, что вы ожидаете, что кто-то создаст для вас всю соответствующую схему Datomic...? отношения «многие ко многим» говорят сами за себя, нет необходимости в конкретном бизнес-примере   -  person deprecated    schedule 12.02.2013
comment
`Я действительно не понимаю атрибут :db/cardinality и его значение`, тогда это ваша настоящая проблема. Существует множество учебных ресурсов, от документов до презентаций InfoQ и github.com/Datomic/day- атомарного   -  person deprecated    schedule 12.02.2013


Ответы (2)


Посмотрите на следующую диаграмму и прочитайте полный пример кода (схема, примеры данных и запросы) по адресу https://gist.github.com/a2ndrade/5651419. Это должно помочь вам понять, как моделировать данные в Datomic.

Datomic Schema: Блог

Запрос

Обратите внимание, что некоторые отношения не моделируются явно, поскольку отношения в Datomic являются двунаправленными, а остальную информацию можно получить с помощью простых запросов Datalog. Например, запрос:

(d/q '[:find ?cid ?c
   :in $ ?u
   :where
   [?uid :user/username ?u]
   [?aid :article/category ?cid]
   [?aid :article/author ?uid]
   [?cid :category/name ?c]]
 (d/db conn) "john.smith")

находит все идентификаторы категорий и их имена, для которых пользователь («john.smith») написал статьи.

Отношения сдерживания

Важным решением моделирования является то, чтобы статьи указывали на комментарии и помечали связь как :db/isComponent, поскольку комментарии не должны существовать сами по себе, а должны быть частью статьи. Datomic обязательно отзовет все комментарии, связанные со статьей, если сама статья будет отозвана.

Применение бизнес-правил

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

person a2ndrade    schedule 26.05.2013

Давайте сначала рассмотрим более простой случай, когда у вас есть отношение «один ко многим» между типами сущностей (в вашем случае пользователи и комментарии):

user ---- * comment

Вы можете моделировать это, позволяя каждому комментарию указывать только на одного пользователя с помощью атрибута, скажем, :comment/user типа :db.type/ref.

Это было бы естественной моделью, поскольку комментарий мог иметь не более одного пользователя. Мы говорим, что мощность не больше 1, т.е. количество значений (в данном случае ссылок на пользователей) не может превышать 1.

Это можно указать в схеме с помощью :db/cardinality :db.cardinality/one, что на самом деле используется по умолчанию, поэтому нам не нужно указывать это явно.

Обратите внимание, что, поскольку объекты Datomic не типизированы, невозможно принудительно установить фактическую кардинальность, равную 1, т.е. любой атрибут может отсутствовать. (Сущности имеют неявные типы через их фактические атрибуты. Их обслуживание и интерпретация полностью зависят от вашего приложения)

С другой стороны, если вы хотите, чтобы какой-либо комментарий был применим более чем к одному пользователю, у вас есть отношение «многие ко многим»:

user * ---- * comment

Этого можно добиться, разрешив атрибуту :comment/user иметь значение :db/cardinality :db.cardinality/many, т.е. разрешая множественные ссылки из комментариев на пользователей.

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

Вы также можете сделать так, чтобы количество ссылок на количество элементов было указано на пользователей, а не на комментарии.

Я надеюсь, что это достаточно ясно, чтобы помочь вам начать :)

person clojureman    schedule 12.02.2013