Necromancing.
Jawaban yang benar adalah: itu tergantung pada mesin basis data mana dan pada alat manajemen mana.
Mari kita buat contoh:
Kami memiliki tabel laporan,
dan laporan dapat memiliki orang tua (menupoint, seperti kategori),
dan orang tua itu sendiri dapat memiliki orang tua (mis. Pusat laba),
dan seterusnya ad infinitum.
Contoh paling sederhana dari hubungan rekursif standar, seperti dengan entitas / hierarki referensi-diri.
Tabel SQL-Server yang dihasilkan adalah:
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
Tetapi Anda mendapatkan masalah:
Ketika Anda perlu menghapus menupoint dengan semua submenupoints, Anda TIDAK BISA mengatur delete-cascade, karena Microsoft SQL-Server tidak mendukung penghapusan cascaded rekursif (di sisi lain, PostGreSQL melakukannya [tetapi hanya jika grafik bukan cyclic], sedangkan MySQL sama sekali tidak menyukai struktur tabel ini, karena tidak mendukung CTE rekursif).
Jadi Anda agak menghapus integritas / fungsionalitas penghapusan dengan itu, sehingga wajib untuk menerapkan fungsi tersebut dalam kode Anda sendiri, atau dalam prosedur tersimpan (jika RDBMS Anda mendukung prosedur tersimpan).
Tidak diragukan lagi ini akan meledakkan segala jenis impor / ekspor data dinamis sepenuhnya otomatis, karena Anda tidak dapat menjalankan pernyataan penghapusan untuk semua tabel sesuai dengan hubungan asing-kunci (non-referensi sendiri), juga tidak dapat melakukan pemilihan sederhana * dan buat sisipan untuk setiap baris dalam urutan acak.
Misalnya, ketika Anda membuat skrip INSERT menggunakan SSMS, maka SSMS tidak akan mendapatkan kunci asing, dan karenanya memang membuat pernyataan-penyisipan yang akan menyisipkan entri dengan dependensi, sebelum menyisipkan induk dependensi, yang akan gagal dengan kesalahan , karena kunci asing sudah ada.
Namun, pada sistem manajemen database yang tepat (seperti PostgreSQL), dengan tooling yang tepat, ini seharusnya tidak menjadi masalah. Hanya memahami bahwa hanya karena Anda membayar banyak untuk RDBMS Anda (saya sedang melihat Anda, Microsoft; Oracle =?), Dan / atau tool-belt-nya, itu tidak berarti diprogram dengan benar. Dan begitu juga OpenSource (mis. MySQL) membuat Anda kebal terhadap hal-hal kecil yang luar biasa.
Iblis ada dalam perinciannya, seperti kata pepatah lama.
Sekarang, bukan berarti Anda tidak bisa mengatasi masalah seperti itu, tapi saya benar-benar tidak akan merekomendasikan hal itu, jika sistem Anda akan menjadi kompleks (misalnya 200 + tabel).
Plus, dalam pengaturan komersial yang biasa (seperti yang digambarkan oleh Dilbert), Anda tidak akan diberikan waktu itu.
Pendekatan yang jauh lebih baik, meskipun lebih sulit, akan menjadi tabel penutupan.
Itu akan memiliki bonus tambahan yang juga berfungsi di MySQL.
Setelah Anda menerapkan fungsi penutupan-sekali, Anda akan membuatnya berfungsi di tempat-tempat tambahan dalam waktu singkat.