通常、親の子階層を表すときは、次のような表があります(処理速度を上げるために深さの列を追加することもできます)。親と子は両方とも同じエンティティの行表。
データベースのツリーの深さを制限する
エンティティの関係
複合PKEY私が把握しようとしています何
子ID
親ID
は1つに、ツリーの深さを制限する方法です。言い換えれば、もし誰かが子供の親であれば、私はその親が子供であることをどうやって防ぐのですか?したがって、祖父母を育てることは不可能です。
通常、親の子階層を表すときは、次のような表があります(処理速度を上げるために深さの列を追加することもできます)。親と子は両方とも同じエンティティの行表。
データベースのツリーの深さを制限する
エンティティの関係
複合PKEY私が把握しようとしています何
子ID
親ID
は1つに、ツリーの深さを制限する方法です。言い換えれば、もし誰かが子供の親であれば、私はその親が子供であることをどうやって防ぐのですか?したがって、祖父母を育てることは不可能です。
RDBMSによっては、INSERT/UPDATEトリガーでこれを処理できます。単純に親を子供にもならないように制限するには、あまりにも悪くあってはいけません(私はトリガーを必要以上に使用することは嫌ですが)。特定のレベル数(たとえば100)に制限しようとすると、パフォーマンスの問題が発生する可能性があります。
MS SQL Serverでは、制約でユーザー定義関数を使用することもできます。しかし、限界があるので、私はそれがここで動作するかどうかわからない。私はそれをテストしようとします。
EDIT:
私は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
これらは、アプリケーションレベルではなく実装する必要が制約されていますデータベースレベルでは – Balanivash
私はアプリケーションレベルでこれを定義する考え方が嫌いでした。なぜなら、許可されてはならないデータベースに関係を挿入することができるからです。ある時点で子供をテーブルから取り出さなければならないので、それは不可能だと思いますか? – mogronalol
あなたはどのRDBMSを使用していますか? –