限制数据库树深度

时间:2011-07-08 11:57:30

标签: sql database tree relationship

通常,当我表示父子层次结构时,我有一个表如下(我可能还会添加其他深度列以加快速度),其中父项和子项都是来自同一实体表的行的外键关系。

实体关系
复合p 儿童身份
父母身份

我想弄清楚的是如何将树的深度限制为一个。换句话说,如果有人是孩子的父母,如何防止父母本身成为孩子,那么祖父母甚至不可能进一步生活?

1 个答案:

答案 0 :(得分:1)

根据您的RDBMS,您可以在INSERT / UPDATE触发器中处理类似的事情。为了简单地限制父母也不是一个孩子,它不应该太糟糕(虽然我讨厌使用触发器超过必要)。如果您尝试限制到一定数量的级别(比如100),那么您可能会遇到性能问题。

在MS SQL Server中,您还可以在约束中使用用户定义的函数。但是有限制,所以我不知道它是否适用于此。我会尝试测试它。

修改

我刚刚在MS SQL Server 2008上对此进行了测试,看起来它的工作正常:

CREATE FUNCTION dbo.Is_Child (@parent_id INT) RETURNS BIT
AS
BEGIN
    DECLARE @return BIT
    IF EXISTS (SELECT * FROM dbo.Test_Trees WHERE child_id = @parent_id)
        SET @return = 1
    ELSE
        SET @return = 0

    RETURN @return
END
GO
CREATE TABLE dbo.Test_Tree_Objects (
    my_id INT NOT NULL,
    CONSTRAINT PK_Test_Tree_Objects PRIMARY KEY CLUSTERED (my_id)
)
CREATE TABLE dbo.Test_Trees (
    my_id INT NOT NULL IDENTITY,
    parent_id INT NOT NULL CHECK (dbo.Is_Child(parent_id) = 0),
    child_id INT NOT NULL,
    CONSTRAINT PK_Test_Trees PRIMARY KEY CLUSTERED (my_id),
    CONSTRAINT FK_Test_Trees_parent_id FOREIGN KEY (parent_id) REFERENCES dbo.Test_Tree_Objects (my_id),
    CONSTRAINT FK_Test_Trees_child_id FOREIGN KEY (child_id) REFERENCES dbo.Test_Tree_Objects (my_id)
)
GO

INSERT INTO dbo.Test_Tree_Objects (my_id) VALUES (1), (2), (3), (4), (5)
GO

INSERT INTO dbo.Test_Trees (parent_id, child_id) VALUES (1, 2)
INSERT INTO dbo.Test_Trees (parent_id, child_id) VALUES (2, 3)

DROP TABLE dbo.Test_Trees
DROP TABLE dbo.Test_Tree_Objects
DROP FUNCTION dbo.Is_Child
GO