답변:
자체 참조 테이블에는 문제가 없습니다.
깊이있는 (무한?) 중첩 계층 구조에 대한 일반적인 데이터베이스 디자인 패턴입니다.
hierarchyid
유형을 도입했습니다 .
괴롭힘.
정답은 다음과 같습니다. 데이터베이스 엔진과 관리 도구에 따라 다릅니다.
예를 들어 보겠습니다
. 보고서 테이블이 있고 보고서
에 상위 (카테고리와 같은
메뉴 포인트)가있을 수 있으며 해당 상위 자체에 상위 (예 : 이익 센터) 등이있을 수 있습니다
.
자체 참조 엔터티 / 계층 구조와 마찬가지로 표준 재귀 관계의 가장 간단한 예입니다.
결과 SQL-Server 테이블은 다음과 같습니다.
IF EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'dbo.FK_T_FMS_Reports_T_FMS_Reports') AND parent_object_id = OBJECT_ID(N'dbo.T_FMS_Reports'))
ALTER TABLE dbo.T_FMS_Reports DROP CONSTRAINT FK_T_FMS_Reports_T_FMS_Reports
GO
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'dbo.T_FMS_Reports') AND type in (N'U'))
DROP TABLE dbo.T_FMS_Reports
GO
CREATE TABLE dbo.T_FMS_Reports
(
RE_UID uniqueidentifier NOT NULL
,RE_RE_UID uniqueidentifier NULL
,RE_Text nvarchar(255) NULL
,RE_Link nvarchar(400) NULL
,RE_Sort int NOT NULL
,RE_Status int NOT NULL
,PRIMARY KEY CLUSTERED ( RE_UID )
);
GO
ALTER TABLE dbo.T_FMS_Reports WITH CHECK ADD CONSTRAINT FK_T_FMS_Reports_T_FMS_Reports FOREIGN KEY(RE_RE_UID)
REFERENCES dbo.T_FMS_Reports (RE_UID)
-- ON DELETE CASCADE -- here, MS-SQL has a problem
GO
ALTER TABLE dbo.T_FMS_Reports CHECK CONSTRAINT FK_T_FMS_Reports_T_FMS_Reports
GO
그러나 문제가 발생합니다.
모든 하위 메뉴 지점이있는 메뉴 포인트를 삭제해야하는 경우 Microsoft SQL-Server 는 재귀 연속 삭제를 지원하지 않기 때문에 delete-cascade를 설정할 수 없습니다 (반면 PostGreSQL은 [ 그래프는 순환 적이 지 않다.] 반면 MySQL은 재귀 적 CTE를 지원하지 않기 때문에 이런 종류의 테이블 구조를 전혀 좋아하지 않는다.
따라서 삭제 무결성 / 기능을 사용하여 자체 코드 또는 저장 프로 시저 (RDBMS가 저장 프로 시저를 지원하는 경우)에서 해당 기능을 구현해야합니다.
이것은 (자체 참조가 아닌) 외래 키 관계에 따라 모든 테이블에 대해 delete 문을 실행하거나 간단한 선택을 수행 할 수 없기 때문에 모든 종류의 완전 자동 동적 데이터 가져 오기 / 내보내기를 의심 할 것입니다. * 임의의 순서로 모든 행에 대한 삽입을 작성하십시오.
예를 들어, SSMS를 사용하여 INSERT 스크립트를 만들면 SSMS는 외래 키를 얻지 못하므로 종속성이있는 항목을 삽입하기 전에 종속성이있는 항목을 삽입하는 삽입 문을 작성하여 오류로 실패합니다. 외래 키가 있기 때문입니다.
그러나 적절한 도구를 사용하여 PostgreSQL과 같은 적절한 데이터베이스 관리 시스템에서는 이것이 문제가되지 않습니다. RDBMS (Microsoft, Oracle =?), 및 / 또는 툴 벨트에 대해 많은 비용을 지불한다고해서 제대로 프로그래밍 된 것은 아닙니다. 그리고 OpenSource (예 : MySQL)도 그러한 훌륭한 축소에 면역되지 않습니다.
오래된 말이 진행됨에 따라 악마는 세부 사항에 있습니다.
이제 이러한 문제를 해결할 수는 없지만 시스템이 복잡 할 경우 (예 : 200+ 테이블) 실제로 권장하지 않습니다.
또한 Dilbert가 묘사 한 일반적인 상업 환경에서는 그 시간이 주어지지 않습니다.
훨씬 어려운 접근 방식은 클로저 테이블 일 것입니다.
그것은 MySQL에서도 작동하는 추가 보너스를 가질 것입니다.
클로저 기능을 한 번 구현하면 거의 모든 시간에 추가 장소에서 작업하게됩니다.
관계가 실제로 계층 적이며 네트워크 관계가 아닌 것이 좋습니다 (예 : BOM은 계층 적 관계가 아닌 네트워크 관계 임).
쿼리 속도가 느릴 수 있습니다. 작업 속도를 높이기 위해 클로저 테이블을 사용할 수 있습니다.
http://karwin.blogspot.ca/2010/03/rendering-trees-with-closure-tables.html