约束管理 #

一、约束概述 #

1.1 什么是约束 #

约束是保证数据完整性和一致性的规则,确保数据符合特定条件。

text
约束作用:
├── 保证数据唯一性
├── 保证数据存在性
├── 保证数据完整性
├── 防止无效数据
└── 维护数据质量

1.2 约束类型 #

类型 说明 用途
UNIQUE 唯一约束 属性值唯一
NODE KEY 节点键约束 组合属性唯一
EXISTS 存在约束 属性必须存在
RELATIONSHIP KEY 关系键约束 关系属性组合唯一

二、唯一约束 #

2.1 创建唯一约束 #

cypher
CREATE CONSTRAINT FOR (p:Person) REQUIRE p.id IS UNIQUE

2.2 创建带名称的唯一约束 #

cypher
CREATE CONSTRAINT person_id_unique FOR (p:Person) REQUIRE p.id IS UNIQUE

2.3 唯一约束效果 #

cypher
CREATE CONSTRAINT FOR (p:Person) REQUIRE p.email IS UNIQUE

CREATE (p:Person {email: 'tom@example.com'})
CREATE (p:Person {email: 'tom@example.com'})

2.4 查看唯一约束 #

cypher
SHOW CONSTRAINTS

2.5 删除唯一约束 #

cypher
DROP CONSTRAINT person_id_unique

三、节点键约束 #

3.1 创建节点键约束 #

cypher
CREATE CONSTRAINT FOR (p:Person) REQUIRE (p.firstName, p.lastName) IS NODE KEY

3.2 创建带名称的节点键约束 #

cypher
CREATE CONSTRAINT person_name_key FOR (p:Person) REQUIRE (p.firstName, p.lastName) IS NODE KEY

3.3 节点键约束效果 #

cypher
CREATE CONSTRAINT FOR (p:Person) REQUIRE (p.firstName, p.lastName) IS NODE KEY

CREATE (p:Person {firstName: 'Tom', lastName: 'Hanks'})
CREATE (p:Person {firstName: 'Tom', lastName: 'Hanks'})

3.4 节点键与唯一约束的区别 #

特性 UNIQUE NODE KEY
唯一性
存在性
单属性
多属性

四、存在约束 #

4.1 创建存在约束 #

cypher
CREATE CONSTRAINT FOR (p:Person) REQUIRE p.name IS NOT NULL

4.2 创建带名称的存在约束 #

cypher
CREATE CONSTRAINT person_name_exists FOR (p:Person) REQUIRE p.name IS NOT NULL

4.3 存在约束效果 #

cypher
CREATE CONSTRAINT FOR (p:Person) REQUIRE p.name IS NOT NULL

CREATE (p:Person {name: 'Tom'})
CREATE (p:Person {age: 30})

4.4 删除存在约束 #

cypher
DROP CONSTRAINT person_name_exists

五、关系约束 #

5.1 创建关系唯一约束 #

cypher
CREATE CONSTRAINT FOR ()-[r:KNOWS]-() REQUIRE r.id IS UNIQUE

5.2 创建关系存在约束 #

cypher
CREATE CONSTRAINT FOR ()-[r:KNOWS]-() REQUIRE r.since IS NOT NULL

5.3 创建关系键约束 #

cypher
CREATE CONSTRAINT FOR ()-[r:KNOWS]-() REQUIRE (r.from, r.to) IS RELATIONSHIP KEY

六、查看约束 #

6.1 查看所有约束 #

cypher
SHOW CONSTRAINTS

6.2 查看特定约束 #

cypher
SHOW CONSTRAINTS WHERE name = 'person_id_unique'

6.3 查看约束详情 #

cypher
SHOW CONSTRAINTS YIELD name, type, entityType, labelsOrTypes, properties

6.4 按类型查看 #

cypher
SHOW CONSTRAINTS WHERE type = 'UNIQUENESS'
SHOW CONSTRAINTS WHERE type = 'NODE_KEY'
SHOW CONSTRAINTS WHERE type = 'NODE_PROPERTY_EXISTENCE'

七、删除约束 #

7.1 删除约束 #

cypher
DROP CONSTRAINT person_id_unique

7.2 条件删除 #

cypher
DROP CONSTRAINT IF EXISTS person_id_unique

7.3 批量删除 #

cypher
CALL apoc.schema.assert({}, {})

八、约束与索引 #

8.1 约束自动创建索引 #

cypher
CREATE CONSTRAINT FOR (p:Person) REQUIRE p.id IS UNIQUE

8.2 查看约束索引 #

cypher
SHOW INDEXES WHERE owningConstraint IS NOT NULL

8.3 约束索引不能单独删除 #

cypher
DROP CONSTRAINT person_id_unique

九、约束最佳实践 #

9.1 为标识属性创建唯一约束 #

cypher
CREATE CONSTRAINT FOR (u:User) REQUIRE u.id IS UNIQUE
CREATE CONSTRAINT FOR (u:User) REQUIRE u.email IS UNIQUE

9.2 为必要属性创建存在约束 #

cypher
CREATE CONSTRAINT FOR (p:Person) REQUIRE p.name IS NOT NULL
CREATE CONSTRAINT FOR (o:Order) REQUIRE o.createdAt IS NOT NULL

9.3 使用节点键约束组合唯一 #

cypher
CREATE CONSTRAINT FOR (p:Person) REQUIRE (p.firstName, p.lastName, p.birthDate) IS NODE KEY

9.4 约束命名规范 #

text
命名建议:
├── 使用描述性名称
├── 包含标签名
├── 包含属性名
├── 包含约束类型
└── 使用下划线分隔

9.5 约束数量建议 #

text
建议:
├── 每个标签至少有一个唯一约束
├── 避免过多的存在约束
├── 合理使用节点键约束
└── 定期审查约束

十、约束与性能 #

10.1 约束对写入的影响 #

text
影响:
├── 插入时需要检查约束
├── 更新时需要检查约束
├── 批量导入时影响较大
└── 建议导入后创建约束

10.2 约束对查询的优化 #

cypher
CREATE CONSTRAINT FOR (p:Person) REQUIRE p.id IS UNIQUE

MATCH (p:Person)
WHERE p.id = 'person_001'
RETURN p

10.3 批量导入策略 #

cypher
CALL {
    LOAD CSV WITH HEADERS FROM 'file:///data.csv' AS row
    CREATE (p:Person {id: row.id, name: row.name})
} IN TRANSACTIONS OF 1000 ROWS

CREATE CONSTRAINT FOR (p:Person) REQUIRE p.id IS UNIQUE

十一、实际应用示例 #

11.1 用户约束 #

cypher
CREATE CONSTRAINT user_id_unique FOR (u:User) REQUIRE u.id IS UNIQUE
CREATE CONSTRAINT user_email_unique FOR (u:User) REQUIRE u.email IS UNIQUE
CREATE CONSTRAINT user_username_unique FOR (u:User) REQUIRE u.username IS UNIQUE
CREATE CONSTRAINT user_name_exists FOR (u:User) REQUIRE u.name IS NOT NULL

11.2 产品约束 #

cypher
CREATE CONSTRAINT product_id_unique FOR (p:Product) REQUIRE p.id IS UNIQUE
CREATE CONSTRAINT product_sku_unique FOR (p:Product) REQUIRE p.sku IS UNIQUE
CREATE CONSTRAINT product_name_exists FOR (p:Product) REQUIRE p.name IS NOT NULL
CREATE CONSTRAINT product_price_exists FOR (p:Product) REQUIRE p.price IS NOT NULL

11.3 订单约束 #

cypher
CREATE CONSTRAINT order_id_unique FOR (o:Order) REQUIRE o.id IS UNIQUE
CREATE CONSTRAINT order_number_unique FOR (o:Order) REQUIRE o.orderNumber IS UNIQUE
CREATE CONSTRAINT order_status_exists FOR (o:Order) REQUIRE o.status IS NOT NULL
CREATE CONSTRAINT order_created_exists FOR (o:Order) REQUIRE o.createdAt IS NOT NULL

11.4 关系约束 #

cypher
CREATE CONSTRAINT knows_since_exists FOR ()-[r:KNOWS]-() REQUIRE r.since IS NOT NULL
CREATE CONSTRAINT purchased_at_exists FOR ()-[r:PURCHASED]-() REQUIRE r.purchasedAt IS NOT NULL

十二、约束错误处理 #

12.1 唯一约束冲突 #

cypher
CREATE CONSTRAINT FOR (p:Person) REQUIRE p.email IS UNIQUE

CREATE (p:Person {email: 'tom@example.com'})
CREATE (p:Person {email: 'tom@example.com'})

解决方案:

cypher
MERGE (p:Person {email: 'tom@example.com'})
ON CREATE SET p.name = 'Tom'

12.2 存在约束冲突 #

cypher
CREATE CONSTRAINT FOR (p:Person) REQUIRE p.name IS NOT NULL

CREATE (p:Person {age: 30})

解决方案:

cypher
CREATE (p:Person {name: 'Tom', age: 30})

12.3 使用TRY-CATCH处理 #

cypher
CALL apoc.do.when(
    EXISTS((:Person {email: 'tom@example.com'})),
    'RETURN "Email already exists" AS message',
    'CREATE (p:Person {email: "tom@example.com"}) RETURN p',
    {}
) YIELD value
RETURN value

十三、总结 #

约束管理要点:

操作 语法 说明
创建唯一约束 CREATE CONSTRAINT … REQUIRE p.prop IS UNIQUE 属性值唯一
创建节点键 CREATE CONSTRAINT … REQUIRE (p.prop1, p.prop2) IS NODE KEY 组合唯一且存在
创建存在约束 CREATE CONSTRAINT … REQUIRE p.prop IS NOT NULL 属性必须存在
查看约束 SHOW CONSTRAINTS 查看所有约束
删除约束 DROP CONSTRAINT name 删除约束

最佳实践:

  1. 为标识属性创建唯一约束
  2. 为必要属性创建存在约束
  3. 使用节点键约束保证组合唯一
  4. 批量导入后再创建约束
  5. 定期审查约束使用情况

下一步,让我们学习高级特性!

最后更新:2026-03-27