Söz konusu iş ortamının açıklamanıza göre , Öğe - süper tip - ve Kategorilerinin her birini , yani Araba , Tekne ve Düzlem'i (bilinmeyen iki tane daha ile birlikte) kapsayan bir süper tip-alt tip yapısı vardır. alt türler -.
Böyle bir senaryoyu yönetmek için izleyeceğim yöntemin detaylarını vereceğim.
İş kuralları
İlgili kavramsal şemayı tanımlamaya başlamak için , şimdiye kadar belirlenen en önemli iş kurallarından bazıları ( analizi yalnızca açıklanan üç kategoriyle sınırlandırmak, işleri mümkün olduğunca kısa tutmak için) aşağıdaki gibi formüle edilebilir:
- Bir kullanıcı sıfır-bir-veya-pek sahibi Ürünleri
- Bir Öğe , belirli bir anda tam olarak bir Kullanıcıya aittir
- Bir Öğe , farklı noktalarda bir ila birçok Kullanıcıya ait olabilir
- Bir Öğe tam olarak bir Kategoriye göre sınıflandırılmıştır
- Bir Öğe , her zaman,
- ya bir Araba
- veya bir tekne
- veya bir uçak
Açıklayıcı IDEF1X diyagramı
Şekil 1 , önceki formülasyonları, ilgili görünen diğer iş kurallarıyla birlikte gruplandırmak için oluşturduğum bir IDEF1X 1 diyagramını gösterir :
süpertip
Bir yandan, Üst tür olan Öğe , tüm Kategoriler için ortak olan † özelliklerini veya özelliklerini , yani,
- CategoryCode FOREIGN KEY (FK) referanslar bu kadar patikül özelliklere Category.CategoryCode bir alt tür olarak ve işlevleri discriminator yani, bu tam belirten Kategori verilen bir hangi alt tipinin Öğe connected- olmalı,
- OwnerId —Kullanıcı.UserId'yi işaret eden bir FK olarak ayrıldı , ancak özel sonuçlarını daha doğru bir şekilde yansıtmak için bir rol adı 2 atadım.
- Foo ,
- Bar ,
- Baz ve
- CreatedTateTime .
alttipleri
Diğer yandan, her bir Kategoriye ait olan özellikler ‡ ,
- Qux ve Corge ;
- Grault , Garply ve Plugh ;
- Xyzzy , Thud , Wibble ve Flob ;
karşılık gelen alt tip kutusunda gösterilir.
Tanımlayıcılar
Ardından, Item.ItemId PRIMARY KEY (PK) 3'ü farklı rol adlarına sahip alt türlere geçirdi ;
- CarId ,
- BoatId ve
- PlaneId .
Karşılıklı münhasır dernekler
Gösterildiği gibi, (a) her bir süper tip oluşumu ile (b) tamamlayıcı alt tip örneği arasında bire bir (1: 1) bir kardinalite ilişkisi veya ilişkisi vardır .
Münhasır alt tip sembol alt tipleri yani birbirini dışlayan olduğu gerçeğini canlandırıyor, somut Öğe olay sadece tek alt tip örneği tarafından desteklenebilir: birini Araba veya bir Düzlem ya da bir tekne (asla iki ya da daha çok).
† , ‡ gerçek mezhepler söz konusu ürünle değil gibi ben varlık türü özelliklerinden bazıları kazandırılması için klasik tutucu isimlerini kullanmıştır.
Açıklayıcı mantıksal düzey düzeni
Sonuç olarak, açıklayıcı bir mantıksal tasarımı tartışmak için, yukarıda görüntülenen ve açıklanan IDEF1X diyagramına dayanarak aşağıdaki SQL-DDL ifadelerini türettim:
-- You should determine which are the most fitting
-- data types and sizes for all your table columns
-- depending on your business context characteristics.
-- Also, you should make accurate tests to define the
-- most convenient INDEX strategies based on the exact
-- data manipulation tendencies of your business context.
-- As one would expect, you are free to utilize
-- your preferred (or required) naming conventions.
CREATE TABLE UserProfile (
UserId INT NOT NULL,
FirstName CHAR(30) NOT NULL,
LastName CHAR(30) NOT NULL,
BirthDate DATE NOT NULL,
GenderCode CHAR(3) NOT NULL,
Username CHAR(20) NOT NULL,
CreatedDateTime DATETIME NOT NULL,
--
CONSTRAINT UserProfile_PK PRIMARY KEY (UserId),
CONSTRAINT UserProfile_AK1 UNIQUE ( -- Composite ALTERNATE KEY.
FirstName,
LastName,
GenderCode,
BirthDate
),
CONSTRAINT UserProfile_AK2 UNIQUE (Username) -- ALTERNATE KEY.
);
CREATE TABLE Category (
CategoryCode CHAR(1) NOT NULL, -- Meant to contain meaningful, short and stable values, e.g.; 'C' for 'Car'; 'B' for 'Boat'; 'P' for 'Plane'.
Name CHAR(30) NOT NULL,
--
CONSTRAINT Category_PK PRIMARY KEY (CategoryCode),
CONSTRAINT Category_AK UNIQUE (Name) -- ALTERNATE KEY.
);
CREATE TABLE Item ( -- Stands for the supertype.
ItemId INT NOT NULL,
OwnerId INT NOT NULL,
CategoryCode CHAR(1) NOT NULL, -- Denotes the subtype discriminator.
Foo CHAR(30) NOT NULL,
Bar CHAR(30) NOT NULL,
Baz CHAR(30) NOT NULL,
CreatedDateTime DATETIME NOT NULL,
--
CONSTRAINT Item_PK PRIMARY KEY (ItemId),
CONSTRAINT Item_to_Category_FK FOREIGN KEY (CategoryCode)
REFERENCES Category (CategoryCode),
CONSTRAINT Item_to_User_FK FOREIGN KEY (OwnerId)
REFERENCES UserProfile (UserId)
);
CREATE TABLE Car ( -- Represents one of the subtypes.
CarId INT NOT NULL, -- Must be constrained as (a) the PRIMARY KEY and (b) a FOREIGN KEY.
Qux CHAR(30) NOT NULL,
Corge CHAR(30) NOT NULL,
--
CONSTRAINT Car_PK PRIMARY KEY (CarId),
CONSTRAINT Car_to_Item_FK FOREIGN KEY (CarId)
REFERENCES Item (ItemId)
);
CREATE TABLE Boat ( -- Stands for one of the subtypes.
BoatId INT NOT NULL, -- Must be constrained as (a) the PRIMARY KEY and (b) a FOREIGN KEY.
Grault CHAR(30) NOT NULL,
Garply CHAR(30) NOT NULL,
Plugh CHAR(30) NOT NULL,
--
CONSTRAINT Boat_PK PRIMARY KEY (BoatId),
CONSTRAINT Boat_to_Item_FK FOREIGN KEY (BoatId)
REFERENCES Item (ItemId)
);
CREATE TABLE Plane ( -- Denotes one of the subtypes.
PlaneId INT NOT NULL, -- Must be constrained as (a) the PRIMARY KEY and (b) a FOREIGN KEY.
Xyzzy CHAR(30) NOT NULL,
Thud CHAR(30) NOT NULL,
Wibble CHAR(30) NOT NULL,
Flob CHAR(30) NOT NULL,
--
CONSTRAINT Plane_PK PRIMARY KEY (PlaneId),
CONSTRAINT Plane_to_Item_PK FOREIGN KEY (PlaneId)
REFERENCES Item (ItemId)
);
Gösterildiği gibi, süperentite tipi ve subentite tiplerinin her biri karşılık gelen temel tablo ile temsil edilir .
Kolonlar CarId
, BoatId
ve PlaneId
uygun tablo PKler olarak kısıtlanmış, FK kısıtlamaları yoluyla kavramsal düzeyinde bir bire bir ilişki temsil yardım § edilene noktası ItemId
arasında PK sınırlandırılabilir sütun, Item
tablo. Bu, gerçek bir “çiftte” hem süper tip hem de alt tip satırların aynı PK değeriyle tanımlandığını gösterir; bu nedenle,
- (a) (b) alt-tipler için duran tabloların (c) tamamen gereksiz olduğu, sistem kontrollü vekil değerlerini ‖ (b) tutmak için fazladan bir sütunun bağlanması .
§ (Özellikle YABANCI) ANAHTAR kısıtlama tanımları (yorumlarda bahsettiğiniz durum) ile ilgili sorunların ve hataların önlenmesi için , örnek olarak açıklandığı gibi, eldeki farklı tablolar arasında yer alan varoluş bağımlılığını dikkate almak çok önemlidir . Bu SQL Fiddle'da da sağladığım açıklayıcı DDL yapısındaki tabloların bildirim sırası .
‖ Örn, AUTO_INCREMENT özelliğine sahip bir sütunun MySQL üzerine kurulmuş bir veritabanının tablosuna eklenmesi .
Dürüstlük ve tutarlılık konuları
İş ortamınızda, (1) her bir “süper tip” sıranın her zaman karşılık gelen “alt tip” karşılığı ile tamamlandığından emin olmanız ve (2) “Alt tür” satırı, “süper tip” satırının “ayırıcı” sütununda bulunan değerle uyumludur.
Bu tür durumları açıklayıcı bir şekilde uygulamak çok zarif olurdu , ancak maalesef, büyük SQL platformlarının hiçbiri bildiğim kadarıyla bunu yapmak için uygun mekanizmalar sağlamadı. Bu nedenle, ASİT İŞLEMLERİ içindeki prosedür koduna başvurmak , bu koşulların her zaman veritabanınızda karşılanması için oldukça uygundur. Diğer seçenek TRIGGERS kullanmak olabilir, ancak tabiri caizse, işleri düzensiz yapma eğilimindedirler.
Yararlı görünüm bildirme
Yukarıda anlatıldığı gibi mantıksal bir tasarıma sahip olarak, bir veya daha fazla görünüm, yani ilgili taban tabloların iki veya daha fazlasına ait sütunları içeren türetilmiş tablolar oluşturmak çok pratik olacaktır . Bu şekilde, örneğin, "birleşik" bilgileri her almak istediğinizde tüm JOIN'leri yazmak zorunda kalmadan doğrudan bu görünümlerden SEÇEBİLİRSİNİZ.
Örnek veri
Bu bakımdan, temel tabloların aşağıda gösterilen örnek verilerle “doldurulduğunu” söyleyelim:
--
INSERT INTO UserProfile
(UserId, FirstName, LastName, BirthDate, GenderCode, Username, CreatedDateTime)
VALUES
(1, 'Edgar', 'Codd', '1923-08-19', 'M', 'ted.codd', CURDATE()),
(2, 'Michelangelo', 'Buonarroti', '1475-03-06', 'M', 'michelangelo', CURDATE()),
(3, 'Diego', 'Velázquez', '1599-06-06', 'M', 'd.velazquez', CURDATE());
INSERT INTO Category
(CategoryCode, Name)
VALUES
('C', 'Car'), ('B', 'Boat'), ('P', 'Plane');
-- 1. ‘Full’ Car INSERTion
-- 1.1
INSERT INTO Item
(ItemId, OwnerId, CategoryCode, Foo, Bar, Baz, CreatedDateTime)
VALUES
(1, 1, 'C', 'This datum', 'That datum', 'Other datum', CURDATE());
-- 1.2
INSERT INTO Car
(CarId, Qux, Corge)
VALUES
(1, 'Fantastic Car', 'Powerful engine pre-update!');
-- 2. ‘Full’ Boat INSERTion
-- 2.1
INSERT INTO Item
(ItemId, OwnerId, CategoryCode, Foo, Bar, Baz, CreatedDateTime)
VALUES
(2, 2, 'B', 'This datum', 'That datum', 'Other datum', CURDATE());
-- 2.2
INSERT INTO Boat
(BoatId, Grault, Garply, Plugh)
VALUES
(2, 'Excellent boat', 'Use it to sail', 'Everyday!');
-- 3 ‘Full’ Plane INSERTion
-- 3.1
INSERT INTO Item
(ItemId, OwnerId, CategoryCode, Foo, Bar, Baz, CreatedDateTime)
VALUES
(3, 3, 'P', 'This datum', 'That datum', 'Other datum', CURDATE());
-- 3.2
INSERT INTO Plane
(PlaneId, Xyzzy, Thud, Wibble, Flob)
VALUES
(3, 'Extraordinary plane', 'Traverses the sky', 'Free', 'Like a bird!');
--
Daha sonra, avantajlı bir görünüşüdür itibaren toplar sütunlar Item
, Car
ve UserProfile
:
--
CREATE VIEW CarAndOwner AS
SELECT C.CarId,
I.Foo,
I.Bar,
I.Baz,
C.Qux,
C.Corge,
U.FirstName AS OwnerFirstName,
U.LastName AS OwnerLastName
FROM Item I
JOIN Car C
ON C.CarId = I.ItemId
JOIN UserProfile U
ON U.UserId = I.OwnerId;
--
Doğal olarak, benzer bir yaklaşım izlenebilir, böylece “tam” Boat
ve Plane
bilgileri doğrudan tek bir tablodan (bu durumlarda türetilmiş bir tablo ) SEÇEBİLİRSİNİZ.
Size -eğer o aşağıdaki GÖRÜNÜM tanımıyla sonuç takımı gibi NULL işaretlerinin varlığı hakkında sakıncası sonra şunları yapabilirsiniz, örneğin “toplamak” tablolardan sütunlar Item
, Car
, Boat
, Plane
ve UserProfile
:
--
CREATE VIEW FullItemAndOwner AS
SELECT I.ItemId,
I.Foo, -- Common to all Categories.
I.Bar, -- Common to all Categories.
I.Baz, -- Common to all Categories.
IC.Name AS Category,
C.Qux, -- Applies to Cars only.
C.Corge, -- Applies to Cars only.
--
B.Grault, -- Applies to Boats only.
B.Garply, -- Applies to Boats only.
B.Plugh, -- Applies to Boats only.
--
P.Xyzzy, -- Applies to Planes only.
P.Thud, -- Applies to Planes only.
P.Wibble, -- Applies to Planes only.
P.Flob, -- Applies to Planes only.
U.FirstName AS OwnerFirstName,
U.LastName AS OwnerLastName
FROM Item I
JOIN Category IC
ON I.CategoryCode = IC.CategoryCode
LEFT JOIN Car C
ON C.CarId = I.ItemId
LEFT JOIN Boat B
ON B.BoatId = I.ItemId
LEFT JOIN Plane P
ON P.PlaneId = I.ItemId
JOIN UserProfile U
ON U.UserId = I.OwnerId;
--
Burada gösterilen görünümlerin kodu yalnızca açıklayıcıdır. Tabii ki, bazı test alıştırmaları ve değişiklikler yapmak, eldeki sorguların (fiziksel) yürütülmesini hızlandırmaya yardımcı olabilir. Ayrıca, işletmenin gerektirdiği için söz konusu görünümleri kaldırmanız veya sütunlara eklemeniz gerekebilir.
Örnek veriler ve tüm görünüm tanımları bu SQL Fiddle'a dahil edilir, böylece “eylemde” gözlemlenebilirler.
Veri işleme: Uygulama program (lar) ı kodu ve sütun takma adları
Uygulama program (lar) kodunun kullanımı (“sunucu tarafına özel kod” ile kastediyorsanız) ve sütun takma adları, sonraki yorumlarda ortaya koyduğunuz diğer önemli noktalardır:
Sunucu tarafına özel kod ile [bir JOIN] sorunu çözmek için başardı, ama gerçekten tüm sütunlara bu -AND- ekleme takma "stresli" olabilir istemiyorum.
Çok iyi açıklanmış, çok teşekkür ederim. Ancak, şüphelendiğim gibi, ifadeyi daha temiz tutmak için birkaç takma ad kullanmak istemediğim için, bazı sütunlarla benzerlikler nedeniyle tüm verileri listelerken sonuç kümesini değiştirmek zorunda kalacağım.
Uygulama programı kodunu kullanırken sonuç kümelerinin sunum (veya grafik) özelliklerini işlemek için çok uygun bir kaynak olduğunu, satır satır temelinde veri alımından kaçınmanın yürütme hızı sorunlarını önlemek için çok önemli olduğunu belirtmek mümkündür. Amaç, sisteminizin davranışını optimize edebilmeniz için SQL platformunun (tam olarak) ayarlanmış motoru tarafından sağlanan sağlam veri işleme araçlarıyla ilgili veri setlerini “almak” olmalıdır.
Ayrıca, belirli bir kapsamda bir veya daha fazla sütunu yeniden adlandırmak için takma adlar kullanmak stresli görünebilir, ancak kişisel olarak, bu kaynağı (i) ilgili tarafa atfedilen anlam ve niyeti bağlamsallaştırmaya ve (ii) anlamsızlaştırmaya yardımcı olan çok güçlü bir araç olarak görüyorum. sütun; dolayısıyla, bu, ilgili verilerin manipülasyonu ile ilgili olarak kapsamlı bir şekilde düşünülmesi gereken bir husustur.
Benzer senaryolar
Bu yazı dizisine ve birbirini dışlayan alt tiplerle süper tip alt tip ilişkilendirmeleri içeren diğer iki davamı içeren bu yazı grubuna yardımcı olabilirsiniz .
Ben de alt türleri olduğu bir süper tip alt tip küme içeren bir iş ortamı için bir çözüm önermiştir değil de birbirini dışlayan bu (daha yeni) cevap .
Son Notlar
1 Bilgi Modelleme için Entegrasyon Tanımı ( IDEF1X ),Aralık 1993'te ABD Ulusal Standartlar ve Teknoloji Enstitüsü (NIST)tarafından standart olarak oluşturulmuş, oldukça tavsiye edilen bir veri modelleme tekniğidir. Bu çalışma, tamamen teorik çalışmaların bazıları tarafından kaleme (a) 'dayanan tek yaratıcısı ait ilişkisel modeli yani, Dr EF Codd ; (b) Dr. PP Chen tarafından geliştirilen varlık-ilişki görüşü ; ve ayrıca (c) Robert G. Brown tarafından oluşturulan Mantıksal Veritabanı Tasarım Tekniğinde.
2 IDEF1X'te, rol adı , ilgili varlık türü kapsamında tuttuğu anlamı ifade etmek için bir FK özelliğine (veya özelliğine) atanan ayırt edici bir etikettir.
3 IDEF1X standardı, temel geçişi "Bir üst öğenin veya genel öğenin birincil anahtarının alt öğesinde veya kategori öğesinde yabancı anahtar olarak yerleştirilmesinin modelleme süreci" olaraktanımlar.
Item
tablo birCategoryCode
sütun içeriyor . “Dürüstlük ve tutarlılık konuları” başlıklı bölümde belirtildiği gibi: