Constraints and shared uniqueness
Wiki / Indexes and constraints
On this page
- Uniqueness constraints
- Existence constraints
- Node-key constraints
- Element-uniqueness constraints
- Group- (multi-label) uniqueness constraints
The failing inserts in this article are intentional examples. Execute them individually against disposable data: an Explorer script stops at its first error.
Uniqueness constraints
A uniqueness constraint guarantees no two nodes with a given label share a value for a property. It is index-backed: declaring one ensures a backing index exists, and enforcement is then a cheap posting-list check.
CREATE CONSTRAINT FOR (u:User) REQUIRE u.id IS UNIQUE;
DROP CONSTRAINT FOR (u:User) REQUIRE u.id IS UNIQUE;
SHOW CONSTRAINTS;
Behaviour:
- Enforced on writes — a
CREATEorSETthat would put a second node on the same(label, property)value fails with a constraint error. - Validated at creation —
CREATE CONSTRAINTfails if existing data already contains a duplicate for that pair. - Backing index is protected — you cannot
DROP INDEXon a pair that backs a live constraint; drop the constraint first. (Dropping the constraint leaves the backing index in place; remove it explicitly withDROP INDEXif unwanted.)
CREATE CONSTRAINT FOR (u:User) REQUIRE u.id IS UNIQUE;
CREATE (:User {id: 1});
CREATE (:User {id: 1}); // error: uniqueness violation on :User(id) = 1
Existence constraints
REQUIRE n.prop IS NOT NULL guarantees every node with the label carries the
property. It is validated at the statement/transaction boundary (so the order
in which a statement sets properties doesn't matter) and at declaration against
existing data.
CREATE CONSTRAINT FOR (p:Person) REQUIRE p.name IS NOT NULL;
DROP CONSTRAINT FOR (p:Person) REQUIRE p.name IS NOT NULL;
CREATE (:Person {age: 5}); // error: missing required property `name`
Node-key constraints
REQUIRE (n.a, n.b) IS NODE KEY is the composite generalisation: every labelled
node must carry all the key properties, and the property tuple must be
unique within the label.
CREATE CONSTRAINT FOR (p:Person) REQUIRE (p.first, p.last) IS NODE KEY;
CREATE (:Person {first: 'Ada', last: 'Lovelace'});
CREATE (:Person {first: 'Ada', last: 'Byron'}); // ok (different tuple)
CREATE (:Person {first: 'Ada', last: 'Lovelace'}); // error: duplicate node key
CREATE (:Person {first: 'Ada'}); // error: missing key property
Element-uniqueness constraints
REQUIRE EACH n.prop IS UNIQUE is uniqueness per element: no other node
with the label may hold any of this node's elements, in any position — but a
node repeating its own element across slots is allowed (a staged id where
draft == live is the steady state, not a violation).
CREATE CONSTRAINT FOR (u:User) REQUIRE EACH u.id IS UNIQUE;
CREATE (:User {id: ['xxx', null, 'xxx']}); // ok (own repeat)
CREATE (:User {id: [null, 'xxx', null]}); // error: element uniqueness violation
CREATE (:User {id: 'xxx'}); // error (a scalar is one element)
It is backed by an element index (Element indexes and staged values): declaring the constraint
auto-creates the index if absent, existing data is validated at declaration,
and the backing index cannot be dropped while the constraint lives.
SHOW CONSTRAINTS reports it as ELEMENT_UNIQUE.
Group- (multi-label) uniqueness constraints
A plain IS UNIQUE constraint is scoped to one label: a :User and a
:Product may each hold id = 'x' independently. A label alternation
(n:A|B|C) opts a set of labels into a shared uniqueness namespace — the
value must be unique across the union of nodes carrying any of those labels
(a Galactus DB extension).
CREATE CONSTRAINT FOR (n:Person|Company|Address) REQUIRE n.id IS UNIQUE;
CREATE (:Person {id: 'x'});
CREATE (:Company {id: 'x'}); // error: group uniqueness violation
CREATE (:Vehicle {id: 'x'}); // ok: Vehicle was not opted in
Semantics:
-
Opt-in by label. Only the named labels participate; a label outside the group shares no namespace with it. A node with no property, or with the property but none of the group's labels, is unconstrained.
-
Own repeats are fine. One node carrying two of the group's labels (
:Person:Company {id: 'x'}) posts the same value twice but is a single node, not a collision. -
Gaining a label is checked.
SET n:Companysubjectsn's existing properties to the group there and then. -
Removal is automatic. Deleting the node, removing the property, or removing the group label frees the value immediately — enforcement fans across each label's index, so there is no separate structure to keep in sync.
-
Modifiable in place — CREATE adds, DROP removes. The group is keyed by the property, so the label set is edited without a rebuild. The verbs are asymmetric on purpose: CREATE never destroys, so re-running any old CREATE is safe.
// add: union more labels in (revalidated; rejected if existing data collides) CREATE CONSTRAINT FOR (n:Person|Company|Vehicle) REQUIRE n.id IS UNIQUE; // remove: name the labels to opt out (relaxing, so never fails) DROP CONSTRAINT FOR (n:Vehicle) REQUIRE n.id IS UNIQUE; // {Person, Company} DROP CONSTRAINT FOR (n:Company|Vehicle) REQUIRE n.id IS UNIQUE; // removes bothRe-declaring with a smaller set does not shrink the group (CREATE only ever unions — use DROP to remove). The group vanishes once its last label is removed. A removed label's backing index is left in place, and becomes eligible for
DROP INDEXagain. A single-labelDROP … IS UNIQUEprefers a plain uniqueness constraint on that pair, and only removes the label from a group when no plain unique exists.
Each participating label gets a backing (label, id) hash index for free
(auto-created, backfilled, and drop-protected while the constraint lives), so
MATCH (p:Person {id: 'x'}) still seeks. Existing data is validated across the
union at declaration. SHOW CONSTRAINTS reports it as GROUP_UNIQUE with the
labels joined by |.
The alternation is valid only with a plain IS UNIQUE; IS NOT NULL,
IS NODE KEY, and REQUIRE EACH … IS UNIQUE remain single-label.
SHOW CONSTRAINTS reports each constraint's type (UNIQUE,
NODE_PROPERTY_EXISTENCE, NODE_KEY, ELEMENT_UNIQUE, GROUP_UNIQUE).
Related articles
EXPLAIN and PROFILE · Resident and hybrid storage · Schema and maintenance procedures