Necromance.
Câu trả lời đúng là: nó phụ thuộc vào công cụ cơ sở dữ liệu nào và công cụ quản lý nào.
Hãy lấy một ví dụ:
Chúng tôi có một bảng báo cáo
và một báo cáo có thể có cha mẹ (menupoint, giống như thể loại)
và chính cha mẹ đó có thể có cha mẹ (ví dụ: Trung tâm lợi nhuận),
v.v.
Ví dụ đơn giản nhất về mối quan hệ đệ quy tiêu chuẩn, như với bất kỳ thực thể / hệ thống phân cấp tự tham chiếu nào.
Bảng SQL-Server kết quả là:
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
Nhưng bạn gặp phải một vấn đề:
Khi bạn cần xóa một menupoint với tất cả các menu con của nó, bạn KHÔNG THỂ thiết lập xóa tầng, bởi vì Microsoft SQL-Server không hỗ trợ xóa tầng đệ quy (mặt khác, PostGreQuery không [nhưng chỉ khi đồ thị không theo chu kỳ], trong khi MySQL hoàn toàn không thích loại cấu trúc bảng này, vì nó không hỗ trợ các CTE đệ quy).
Vì vậy, bạn sẽ loại bỏ tính toàn vẹn / chức năng xóa với nó, khiến nó bắt buộc phải thực hiện chức năng đó trong mã của riêng bạn hoặc trong một thủ tục được lưu trữ (nếu RDBMS của bạn hỗ trợ các thủ tục được lưu trữ).
Điều này chắc chắn sẽ làm nổ tung bất kỳ loại nhập / xuất dữ liệu động hoàn toàn tự động nào, bởi vì bạn không thể đơn giản chạy một câu lệnh xóa cho tất cả các bảng theo các mối quan hệ khóa ngoài (không tự tham chiếu), cũng như bạn không thể thực hiện một lựa chọn đơn giản * và tạo một chèn cho mỗi hàng theo thứ tự tùy ý.
Ví dụ: khi bạn tạo tập lệnh INSERT bằng SSMS, thì SSMS sẽ không nhận được khóa ngoại và do đó, thực sự tạo ra các câu lệnh chèn sẽ chèn các mục nhập với các phụ thuộc, trước khi nó chèn cha mẹ của phụ thuộc, sẽ không có lỗi , bởi vì khóa ngoại được đặt đúng chỗ.
Tuy nhiên, trên các hệ thống quản lý cơ sở dữ liệu phù hợp (như PostgreSQL), với công cụ thích hợp, đây không phải là vấn đề. Chỉ cần hủy bỏ rằng chỉ vì bạn trả nhiều tiền cho RDBMS của bạn (Tôi đang nhìn bạn, Microsoft; Oracle =?) Và / hoặc vành đai công cụ của nó, điều đó không có nghĩa là nó được lập trình đúng. Và OpenSource cũng không (ví dụ như MySQL) khiến bạn miễn nhiễm với những chi tiết vụn vặt tuyệt vời như vậy.
Ma quỷ là trong các chi tiết, như người xưa nói.
Bây giờ, không phải là bạn không thể giải quyết các vấn đề như vậy, nhưng tôi thực sự không khuyến nghị điều đó, nếu hệ thống của bạn sẽ phức tạp (ví dụ: hơn 200 bảng).
Ngoài ra, trong một bối cảnh thương mại thông thường (như được miêu tả bởi Dilbert), bạn sẽ không được cho thời gian đó.
Một cách tiếp cận tốt hơn nhiều, mặc dù khó khăn hơn, sẽ là một bảng đóng cửa.
Điều đó sẽ có thêm phần thưởng mà nó cũng hoạt động trên MySQL.
Khi bạn triển khai chức năng đóng một lần, bạn sẽ có chức năng này ở những nơi khác mà hầu như không có thời gian.