Skip to content

Schema

Triplox schema.

Every Datom added to Triplox is validated by a schema. The schema itself is described by entities. Schema is data and no different in terms of storage then standard entities. A schema entity has the following attributes:

AttributeDescriptionRequired?
:db/identA unique name or identifier for an entity. Usually this is a schema entity.Yes
:db/valueTypeDefines the type of value associated with an attribute.Yes
:db/cardinalityWeather a attribute does have a single or multiple values.Yes
:db/uniqueDefines a uniqueness constraints for values associated with an attribute.No

:db/ident is a unique keyword identifying an entity. In most cases it is used to identify attributes in queries, but :db/ident can also be used to define an enum like collection of possible values. Examples are the values of :db/valueType and :db/cardinality below or the value of :db/txResult

For :db/ident it is recommended to prefix identifiers with the general entity class that an attribute is going to be used for. Meaning it is discouraged to use :name for the name of people and the name of products and instead use two attributes :person/name and :product/name. This avoids confusion and also gives better index locality when joining.

Allowed value types:

identDescription
:db.type/keywordEDN keyword
:db.type/stringUTF-8 string
:db.type/long64-bit signed integer
:db.type/refEntity reference (same encoding as Long; schema-only distinction)
:db.type/booleantrue / false
:db.type/double64-bit IEEE 754 float
:db.type/float32-bit IEEE 754 float
:db.type/instantTimestamp (microseconds since epoch)
:db.type/uuid128-bit UUID
:db.type/bytesArbitrary binary data
:db.type/bigintArbitrary precision integer
:db.type/vectorOrdered collection of heterogeneous values
:db.type/mapString-keyed map with heterogeneous values

The composite types vector and map allow the same data types as described above. The recursive values have no type checks to them, meaning a attribute of type vector can hold values of type long, strings, doubles and nested vectors without schema-level checks. In particular refs are just longs, so they will not get typed checked in the transaction pipeline if they sit in composite types. In the worst case you end up with dangling references.

Cardinality can take two values:

identDescription
:db.cardinality/oneAn entity has at most one value for this attribute.
:db.cardinality/manyAn entity may have multiple values for this attribute.

Unique attributes are indexed by value (VAE index) and checked during transaction processing.

identDescription
:db.unique/valueAt most one entity may assert a given value. No lookup refs or upserts.
:db.unique/identitySame uniqueness constraint, plus lookup refs and identity upsert.

Only :db.unique/identity attributes participate in tempid upsert resolution. :db.unique/value is a constraint only: transactions may assert it, but they cannot use it to resolve lookup refs or adopt an existing entity for a tempid.