Присоединяй стол к себе - PullRequest
1 голос
/ 17 октября 2011

это один из моих шаблонов таблиц базы данных.

Id int PK
Title nvarchar(10) unique
ParentId int 

Это мой вопрос. Есть ли проблема, если я создаю связь между столбцами «Id» и «ParentId»? (Я имею в виду создать связь между таблицей к себе) Мне нужно несколько советов о проблемах, которые могут возникнуть во время операций вставки, обновления или удаления при разработке step.thanks

Ответы [ 7 ]

5 голосов
/ 17 октября 2011

Вы можете отлично присоединиться к столу самостоятельно.

Вы должны знать, однако, что ваш дизайн позволяет вам иметь несколько уровней иерархии.Поскольку вы используете 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
3 голосов
/ 17 октября 2011

Нет, вы можете самостоятельно присоединиться к вашему столу, проблем не будет.Вы говорите, какие типы проблем в операции вставки, обновления, удаления?Вы можете проверить некоторые условия, такие как ParentId, существует перед добавлением новой записи, или вы можете проверить, существует ли любой дочерний элемент при удалении родителя.

Вы можете сделать самостоятельное присоединение, например:

select t1.Title, t2.Title as 'ParentName'
from table t1 
left join table t2 
on t1.ParentId = t2.Id  
2 голосов
/ 17 октября 2011

У вас здесь много хороших ответов. Еще одна вещь, которую следует учитывать, это ссылочная целостность Вы можете иметь внешний ключ в таблице, который указывает на другой столбец в той же таблице. Обратите внимание:

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.

1 голос
/ 17 октября 2011

Я видел, как это делалось без ошибок, прежде чем в таблице для иерархии меню у вас не должно быть проблем при условии, что ваши запросы на вставку / обновление / удаление хорошо написаны.

Например, когда вы вставляете проверку, существует родительский идентификатор, когда вы удаляете проверку, вы также удаляете все дочерние элементы, если это действие подходит или не разрешает удаление элементов, имеющих дочерние элементы.

1 голос
/ 17 октября 2011

Это называется Self Join , и его можно добавить в таблицу, как в следующем примере

select e1.emp_name 'manager',e2.emp_name 'employee'
from employees e1 join employees e2
on e1.emp_id=e2.emp_manager_id 
0 голосов
/ 17 октября 2011

Это не проблема, так как это обычные отношения в реальной жизни. Если у вас нет родителя (что происходит на верхнем уровне), вам нужно оставить это поле пустым, только тогда правильно обновляйте и удаляйте работу по распространению.

0 голосов
/ 17 октября 2011

Это нормально (это не редкость). Вы должны убедиться, что вы добавляете дочернюю запись в родительскую запись, которая действительно существует и т. Д., Но здесь нет никаких отличий от других ограничений.

Возможно, вы захотите взглянуть на рекурсивные общие табличные выражения:

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

Как способ запроса целого «дерева» записей.

...