将表连接到自身

发布于 2024-12-10 12:04:07 字数 205 浏览 0 评论 0原文

这是我的数据库表模板上的一个。

Id int PK
Title nvarchar(10) unique
ParentId int 

这是我的问题。如果我在“Id”和“ParentId”列之间创建关系,是否有问题? (我的意思是在表与其自身之间创建关系) 我需要一些关于开发步骤中插入或更新或删除操作期间可能出现的问题的建议。谢谢

this is one on my database tables template.

Id int PK
Title nvarchar(10) unique
ParentId int 

This is my question.Is there a problem if i create a relation between "Id" and "ParentId" columns?
(I mean create a relation between a table to itself)
I need some advices about problems that may occur during insert or updater or delete operations at developing step.thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

口干舌燥 2024-12-17 12:04:07

您可以自行将桌子完美地连接起来。

但是,您应该意识到,您的设计允许您具有多个层次结构级别。由于您使用的是 SQL Server(假设 2005 或更高版本),因此您可以使用递归 CTE 获取树结构。

概念验证准备:

declare @YourTable table (id int, parentid int, title varchar(20))

insert into @YourTable values
(1,null, 'root'),
(2,1,    'something'),
(3,1,    'in the way'),
(4,1,    'she moves'),
(5,3,    ''),
(6,null, 'I don''t know'),
(7,6,    'Stick around');

查询 1 - 节点级别:

with cte as (
    select Id, ParentId, Title, 1 level 
    from @YourTable where ParentId is null

    union all

    select yt.Id, yt.ParentId, yt.Title, cte.level + 1
    from @YourTable yt inner join cte on cte.Id = yt.ParentId
)
select cte.*
from cte 
order by level, id, Title

You can perfectly join the table with it self.

You should be aware, however, that your design allows you to have multiple levels of hierarchy. Since you are using SQL Server (assuming 2005 or higher), you can have a recursive CTE get your tree structure.

Proof of concept preparation:

declare @YourTable table (id int, parentid int, title varchar(20))

insert into @YourTable values
(1,null, 'root'),
(2,1,    'something'),
(3,1,    'in the way'),
(4,1,    'she moves'),
(5,3,    ''),
(6,null, 'I don''t know'),
(7,6,    'Stick around');

Query 1 - Node Levels:

with cte as (
    select Id, ParentId, Title, 1 level 
    from @YourTable where ParentId is null

    union all

    select yt.Id, yt.ParentId, yt.Title, cte.level + 1
    from @YourTable yt inner join cte on cte.Id = yt.ParentId
)
select cte.*
from cte 
order by level, id, Title
东京女 2024-12-17 12:04:07

不,您可以在表中进行自连接,不会有任何问题。你说的是插入、更新、删除操作中哪些类型的问题?您可以在添加新记录之前检查一些条件,例如 ParentId 是否存在,或者您可以在删除父记录时检查是否存在子项。

您可以像这样进行自加入:

select t1.Title, t2.Title as 'ParentName'
from table t1 
left join table t2 
on t1.ParentId = t2.Id  

No, you can do self join in your table, there will not be any problem. Are you talking which types of problems in insert, update, delete operation ? You can check some conditions like ParentId exists before adding new record, or you can check it any child exist while deleting parent.

You can do self join like :

select t1.Title, t2.Title as 'ParentName'
from table t1 
left join table t2 
on t1.ParentId = t2.Id  
冷弦 2024-12-17 12:04:07

您在这里已经得到了很多好的答案。另一件需要考虑的事情是引用完整性。表上可以有一个指向同一个表中另一列的外键。观察:

CREATE TABLE tempdb.dbo.t
(
    Id INT NOT NULL ,
    CONSTRAINT PK_t PRIMARY KEY CLUSTERED ( Id ) ,
    ParentId INT NULL ,
    CONSTRAINT FK_ParentId FOREIGN KEY ( ParentId ) REFERENCES tempdb.dbo.t ( Id )
)

通过这样做,您可以确保 ParentId 列中不会出现垃圾。

You've got plenty of good answers here. One other thing to consider is referential integrity. You can have a foreign key on a table that points to another column in the same table. Observe:

CREATE TABLE tempdb.dbo.t
(
    Id INT NOT NULL ,
    CONSTRAINT PK_t PRIMARY KEY CLUSTERED ( Id ) ,
    ParentId INT NULL ,
    CONSTRAINT FK_ParentId FOREIGN KEY ( ParentId ) REFERENCES tempdb.dbo.t ( Id )
)

By doing this, you ensure that you're not going to get garbage in the ParentId column.

深海夜未眠 2024-12-17 12:04:07

它称为自加入 并且可以将其添加到表中,如下例所示

select e1.emp_name 'manager',e2.emp_name 'employee'
from employees e1 join employees e2
on e1.emp_id=e2.emp_manager_id 

Its called Self Join and it can be added to a table as in following example

select e1.emp_name 'manager',e2.emp_name 'employee'
from employees e1 join employees e2
on e1.emp_id=e2.emp_manager_id 
姐不稀罕 2024-12-17 12:04:07

我之前在菜单层次结构表上看到过这样做没有错误,只要您的插入/更新/删除查询写得好,您就不应该有任何问题。

例如,当您插入时检查父 ID 是否存在,当您删除检查时,如果此操作合适或不允许删除具有子项的项目,您也会删除所有子项。

I have seen this done without errors before on a table for menu hierarchy you shouldnt have any issues providing your insert / update / delete queries are well written.

For instance when you insert check a parent id exists, when you delete check you delete all children too if this action is appropriate or do not allow deletion of items that have children.

¢蛋碎的人ぎ生 2024-12-17 12:04:07

这样做很好(这是一种并不罕见的模式)。您必须确保将子记录添加到实际存在的父记录等中,但这里与任何其他约束都有不同之处。

您可能想查看递归公用表表达式:

http://msdn.microsoft。 com/en-us/library/ms186243.aspx

作为查询整个记录“树”的一种方式。

It is fine to do this (it's a not uncommon pattern). You must ensure that you are adding a child record to a parent record that actually exists etc., but there's noting different here from any other constraint.

You may want to look at recursive common table expressions:

http://msdn.microsoft.com/en-us/library/ms186243.aspx

As a way of querying an entire 'tree' of records.

一直在等你来 2024-12-17 12:04:07

这不是问题,因为这是现实生活中常见的关系。如果您没有父级(发生在顶层),则需要将此字段保留为“空”,然后才能正常进行更新和删除传播工作。

This is not a problem, as this is a relationship that's common in real life. If you do not have a parent (which happens at the top level), you need to keep this field "null", only then do update and delete propagation work properly.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文