我想知道如何在 MySQL 中使用闭包表对层次结构进行建模时对同级节点的名称强制执行唯一的约束。
这是我的架构:
create table spaces (
id int not null,
name varchar(50) not null,
parent int not null,
primary key (id),
foreign key (parent) references spaces(id),
unique key (name, parent)
)
create table space_paths (
ancestor int not null,
descendant int not null,
depth int not null,
primary key (ancestor, descendant),
foreign key (ancestor) references spaces(id),
foreign key (descendant) references spaces(id)
)
使用此架构,我在spaces
表上使用唯一约束来验证没有同级具有相同的名称。
此方法的缺点是它非规范化封装在space_paths
表中的层次结构元数据。这意味着我需要手动管理spaces
表中parent
字段与space_paths
表中路径的一致性。
有没有办法重新设计架构,让数据库在同级之间强制实施唯一的名称约束,而不必非规范化?
在这里,使用闭包表并不是您问题的相关部分——您只想对parent, name
进行UNIQUE KEY
,这似乎已经定义了,所以您应该很好。
可能引起您悲伤的一件事是您对parent
列有NOT NULL
约束。您将如何支持"根"节点?您可以使根节点使用与其 ID 列相等的父值,但这需要一个自分配的主键(AFAIK 您无法在插入语句中引用自动增量值):
INSERT INTO spaces(id, name, parent) values (0, 'root', 0);