Necromancing.
Doğru cevap: hangi veritabanı motoruna ve hangi yönetim aracına bağlı olduğuna bağlıdır.
Bir örnek verelim:
Bir rapor tablomuz var
ve bir raporun bir ebeveyni (menupoint, kategori gibi)
olabilir ve o ebeveyni bir ebeveyni (örneğin, Kâr merkezi)
vb.
Herhangi bir kendi kendini referans alan varlık / hiyerarşide olduğu gibi standart özyinelemeli ilişkinin en basit örneği.
Sonuçta ortaya çıkan SQL-Server tablosu:
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
Ama bir sorunun olsun:
Eğer tüm submenupoints ile menupoint silmek gerektiğinde, CAN NOT çünkü silme-kaskad set Microsoft SQL-Sunucu diğer taraftan (özyinelemeli basamaklı siler desteklemez, PostGreSQL yapar [ama sadece grafik döngüsel değildir], ancak MySQL bu tür tablo yapısını hiç beğenmez, çünkü özyinelemeli CTE'leri desteklemez).
Bu nedenle, silme-bütünlüğünü / işlevselliğini bu tür işlevsellikten arındırıp, kendi işlevselliğinizde kendi kodunuzda veya saklı bir prosedürde (RDBMS'niz saklı prosedürleri destekliyorsa) uygulamayı zorunlu kılar.
Bu şüphesiz herhangi bir tam otomatik dinamik veri ithalat / ihracatını havaya uçuracaktır, çünkü (otomatik referans olmayan) yabancı anahtar ilişkilerine göre tüm tablolar için bir silme ifadesini çalıştıramazsınız ya da basit bir seçim yapamazsınız. * ve her satır için isteğe göre bir sıra oluşturun.
Örneğin, SSMS'yi kullanarak bir INSERT betiği oluşturduğunuzda, SSMS yabancı anahtarı almaz ve bu nedenle gerçekten bir hatayla başarısız olacak olan bağımlılığın üstünü eklemeden önce bağımlılıklarla entriks ekleyen insert ifadeleri oluşturur. , çünkü yabancı anahtar yerinde.
Ancak, uygun araç gereç yönetim sistemlerinde (PostgreSQL gibi) uygun araçlarla bu bir problem olmamalı. Sadece RDBMS'niz için çok para ödemenizin (size bakıyorum, Microsoft; Oracle =?) Ve / veya alet kemeri olması, doğru bir şekilde programlandığı anlamına gelmez. Ayrıca OpenSource (örn. MySQL) sizi böyle harika minutilere karşı bağışıklık kazandırmaz.
Eski demişler gibi şeytan ayrıntılarda gizlidir.
Şimdi, bu tür sorunları çözemezsiniz, ancak sisteminiz karmaşık olacaksa (örneğin 200+ masa) gerçekten tavsiye etmem.
Artı, normal bir ticari ortamda (Dilbert tarafından tasvir edildiği gibi), o zaman size sadece bir şey verilmeyecek.
Çok daha iyi bir yaklaşım, daha zor olsa da, bir kapatma masası olacaktır.
Bu aynı zamanda MySQL üzerinde de çalıştığı için ilave bir ikramiye olurdu.
Kapatma fonksiyonelliğini bir kez uyguladığınızda, hemen hemen hiç çalışmayacak ek yerlerde çalışmasını sağlayabilirsiniz.