约束管理 #
一、约束概述 #
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 | 删除约束 |
最佳实践:
- 为标识属性创建唯一约束
- 为必要属性创建存在约束
- 使用节点键约束保证组合唯一
- 批量导入后再创建约束
- 定期审查约束使用情况
下一步,让我们学习高级特性!
最后更新:2026-03-27