Jika saya memahami spesifikasi Anda dengan baik, skenario Anda melibatkan — di antara aspek-aspek penting lainnya — struktur subtipe-supertipe .
Saya akan mencontohkan di bawah ini bagaimana (1) memodelkannya pada tingkat abstraksi konseptual dan kemudian (2) mewakilinya dalam desain DDL tingkat logis .
Peraturan bisnis
Formulasi konseptual berikut adalah salah satu aturan paling penting dalam konteks bisnis Anda:
- Sebuah Playlist dimiliki oleh salah tepat satu grup atau tepat satu Pengguna pada titik tertentu dalam waktu
- Sebuah Playlist dapat dimiliki oleh satu-ke-banyak Grup atau Pengguna pada titik-titik yang berbeda dalam waktu
- Sebuah Pengguna memiliki nol-satu-atau-banyak Playlist
- Grup A memiliki nol-satu-atau-banyak Daftar Putar
- Sebuah kelompok terdiri dari satu-ke-banyak Anggota (yang harus Pengguna )
- Seorang Pengguna dapat menjadi Anggota dari nol-satu-atau-banyak Grup .
- Sebuah kelompok terdiri dari satu-ke-banyak Anggota (yang harus Pengguna )
Karena asosiasi atau hubungan (a) antara Pengguna dan Daftar Putar dan (b) antara Grup dan Daftar Putar cukup mirip, fakta ini mengungkapkan bahwa Pengguna dan Grup adalah subtipe entitas yang saling eksklusif dari Pihak 1 , yang pada gilirannya akan menjadi supertipe entitas mereka —supertype- subtipe cluster adalah struktur data klasik yang muncul dalam skema konseptual dari jenis yang sangat beragam—. Dengan cara ini, dua aturan baru dapat ditegaskan:
- Suatu Pihak dikategorikan oleh tepat satu Jenis Pihak
- Suatu Pihak adalah Kelompok atau Pengguna
Dan empat aturan sebelumnya harus dirumuskan ulang menjadi hanya tiga:
- Sebuah Playlist dimiliki oleh tepat satu partai pada titik tertentu dalam waktu
- Sebuah Playlist dapat dimiliki oleh satu-ke-banyak Pihak pada titik-titik yang berbeda dalam waktu
- Suatu Pihak memiliki Daftar Putar nol-satu-atau-banyak
Diagram Eksposisi IDEF1X
Diagram IDEF1X 2 yang ditunjukkan pada Gambar 1 mengkonsolidasikan semua aturan bisnis tersebut bersama dengan yang lain yang tampak relevan:
Seperti yang diperlihatkan, Grup dan Pengguna digambarkan sebagai subtipe yang dihubungkan oleh masing-masing baris dan simbol eksklusif dengan Party , supertype.
The Party.PartyTypeCode properti singkatan dari subtipe diskriminator , yaitu, yang menunjukkan jenis subtipe misalnya harus melengkapi kejadian supertype diberikan.
Juga, Party terhubung dengan Daftar Putar melalui properti OwnerId yang digambarkan sebagai KUNCI LUAR NEGERI yang menunjuk ke Party.PartyId . Dengan cara ini, Pihak saling terkait (a) Daftar Putar dengan (b) Grup dan (c) Pengguna .
Oleh karena itu, karena instance Pihak tertentu adalah Grup atau Pengguna , Daftar Putar tertentu dapat ditautkan dengan paling banyak satu kejadian subtipe.
Tata letak tingkat logis ilustrasi
Diagram IDEF1X yang diuraikan sebelumnya telah melayani saya sebagai platform untuk membuat pengaturan SQL-DDL logis berikut (dan saya telah memberikan catatan sebagai komentar yang menyoroti beberapa poin relevansi tertentu — misalnya, deklarasi kendala—):
-- 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 domain.
-- As one would expect, you are free to utilize
-- your preferred (or required) naming conventions.
CREATE TABLE PartyType ( -- Represents an independent entity type.
PartyTypeCode CHAR(1) NOT NULL,
Name CHAR(30) NOT NULL,
--
CONSTRAINT PartyType_PK PRIMARY KEY (PartyTypeCode),
CONSTRAINT PartyType_AK UNIQUE (Name)
);
CREATE TABLE Party ( -- Stands for the supertype.
PartyId INT NOT NULL,
PartyTypeCode CHAR(1) NOT NULL, -- Symbolizes the discriminator.
CreatedDateTime TIMESTAMP NOT NULL,
--
CONSTRAINT Party_PK PRIMARY KEY (PartyId),
CONSTRAINT PartyToPartyType_FK FOREIGN KEY (PartyTypeCode)
REFERENCES PartyType (PartyTypeCode)
);
CREATE TABLE UserProfile ( -- Denotes one of the subtypes.
UserId INT NOT NULL, -- To be constrained as both (a) the PRIMARY KEY and (b) a FOREIGN KEY.
UserName CHAR(30) NOT NULL,
FirstName CHAR(30) NOT NULL,
LastName CHAR(30) NOT NULL,
GenderCode CHAR(3) NOT NULL,
BirthDate DATE NOT NULL,
--
CONSTRAINT UserProfile_PK PRIMARY KEY (UserId),
CONSTRAINT UserProfile_AK1 UNIQUE ( -- Multi-column ALTERNATE KEY.
FirstName,
LastName,
GenderCode,
BirthDate
),
CONSTRAINT UserProfile_AK2 UNIQUE (UserName), -- Single-column ALTERNATE KEY.
CONSTRAINT UserProfileToParty_FK FOREIGN KEY (UserId)
REFERENCES Party (PartyId)
);
CREATE TABLE MyGroup ( -- Represents the other subtype.
GroupId INT NOT NULL, -- To be constrained as both (a) the PRIMARY KEY and (b) a FOREIGN KEY.
Title CHAR(30) NOT NULL,
--
CONSTRAINT Group_PK PRIMARY KEY (GroupId),
CONSTRAINT Group_AK UNIQUE (Title), -- ALTERNATE KEY.
CONSTRAINT GroupToParty_FK FOREIGN KEY (GroupId)
REFERENCES Party (PartyId)
);
CREATE TABLE Playlist ( -- Stands for an independent entity type.
PlaylistId INT NOT NULL,
OwnerId INT NOT NULL,
Title CHAR(30) NOT NULL,
CreatedDateTime TIMESTAMP NOT NULL,
--
CONSTRAINT Playlist_PK PRIMARY KEY (PlaylistId),
CONSTRAINT Playlist_AK UNIQUE (Title), -- ALTERNATE KEY.
CONSTRAINT PartyToParty_FK FOREIGN KEY (OwnerId) -- Establishes the relationship with (a) the supertype and (b) through the subtype with (c) the subtypes.
REFERENCES Party (PartyId)
);
CREATE TABLE GroupMember ( -- Denotes an associative entity type.
MemberId INT NOT NULL,
GroupId INT NOT NULL,
IsOwner BOOLEAN NOT NULL,
JoinedDateTime TIMESTAMP NOT NULL,
--
CONSTRAINT GroupMember_PK PRIMARY KEY (MemberId, GroupId), -- Composite PRIMARY KEY.
CONSTRAINT GroupMemberToUserProfile_FK FOREIGN KEY (MemberId)
REFERENCES UserProfile (UserId),
CONSTRAINT GroupMemberToMyGroup_FK FOREIGN KEY (GroupId)
REFERENCES MyGroup (GroupId)
);
Tentu saja, Anda dapat membuat satu atau lebih penyesuaian sehingga semua karakteristik konteks bisnis Anda diwakili dengan ketelitian yang dibutuhkan dalam database aktual.
Catatan : Saya telah menguji tata letak logis di atas pada db <> biola ini dan juga pada SQL Fiddle ini , keduanya "berjalan" pada PostgreSQL 9.6, sehingga Anda dapat melihat mereka "sedang beraksi".
Siput
Seperti yang Anda lihat, saya tidak memasukkan Group.Slug
atau Playlist.Slug
sebagai kolom dalam deklarasi DDL. Ini karena, sesuai dengan penjelasan Anda berikut
Ini slug
adalah versi unik, huruf kecil, ditulis dgn tanda penghubung dari masing-masing entitas mereka title
. Misalnya, a group
dengan title
'Kelompok Uji' akan memiliki slug
'kelompok uji'. Duplikat ditambahkan dengan bilangan bulat tambahan. Ini akan berubah kapan saja title
perubahan mereka . Saya percaya itu berarti mereka tidak akan membuat kunci utama yang hebat? Ya, slugs
dan usernames
unik di tabel masing-masing.
orang dapat menyimpulkan bahwa nilai-nilai mereka dapat diturunkan (yaitu, mereka harus dihitung atau dihitung dalam hal yang sesuai Group.Title
dan Playlist.Title
nilai - nilai, kadang-kadang dalam hubungannya dengan -Saya berasumsi, semacam sistem yang dihasilkan- INTEGER), jadi saya tidak akan menyatakan kolom kata di salah satu tabel dasar karena mereka akan memperkenalkan penyimpangan pembaruan.
Sebaliknya, saya akan menghasilkan Slugs
mungkin, dalam tampilan , yang (a) termasuk derivasi dari nilai-nilai tersebut dalam kolom virtual dan (b) dapat digunakan secara langsung dalam operasi SELECT selanjutnya — menambahkan bagian INTEGER dapat diperoleh, misalnya, dengan menggabungkan nilai (1) yang Playlist.OwnerId
dengan (2) tanda hubung menengah dan (3) nilai Playlist.Title
;
atau, berdasarkan kode program aplikasi, meniru pendekatan yang dijelaskan sebelumnya (mungkin secara prosedural), setelah set data terkait diambil dan diformat untuk interpretasi pengguna akhir.
Dengan cara ini, salah satu dari dua metode akan menghindari “update sinkronisasi” mekanisme yang harus diletakkan di tempat IFF yang Slugs
dipertahankan dalam kolom tabel dasar.
Pertimbangan integritas dan konsistensi
Sangat penting untuk menyebutkan bahwa (i) setiap Party
baris harus dilengkapi setiap saat dengan (ii) masing-masing rekan tepat di salah satu tabel yang berdiri untuk subtipe, yang (iii) harus "mematuhi" nilai yang terkandung dalam Party.PartyTypeCode
kolom —Mencatat pembeda—.
Akan sangat menguntungkan untuk menegakkan situasi semacam itu secara deklaratif , tetapi tidak ada sistem manajemen basis data SQL utama (termasuk Postgres) yang memasok instrumen yang diperlukan untuk melanjutkan seperti itu; oleh karena itu, menulis kode prosedural dalam TRANSAKSI ASAM sejauh ini merupakan pilihan terbaik untuk menjamin bahwa keadaan yang dijelaskan sebelumnya selalu dipenuhi dalam database Anda. Kemungkinan lain akan beralih ke PEMICU, tetapi mereka cenderung membuat hal-hal berantakan, sehingga untuk berbicara.
Kasus yang sebanding
Jika Anda ingin membuat beberapa analogi, Anda mungkin tertarik untuk melihat jawaban saya untuk pertanyaan (baru) yang berjudul
karena skenario yang sebanding dibahas.
Catatan akhir
1 Pihak adalah istilah yang digunakan dalam konteks hukum ketika merujuk pada individu atau kelompok individu yang membentuk satu entitas , sehingga denominasi ini cocok untuk mewakili konsep Pengguna dan Grup sehubungan dengan lingkungan bisnis yang dimaksud.
2 Definisi Integrasi untuk Pemodelan Informasi ( IDEF1X ) adalah teknik pemodelan data yang sangat direkomendasikan yang ditetapkan sebagai standar pada bulan Desember 1993 oleh Institut Standar dan Teknologi Nasional (NIST)Amerika Serikat. Ini didasarkan pada (a) beberapa karya teoritis awal yang ditulis oleh satu-satunya pencetus model relasional , yaitu, Dr. EF Codd ; pada (b) pandangan entitas-hubungan , yang dikembangkan oleh Dr. PP Chen ; dan juga pada (c) Teknik Desain Basis Data Logis, yang dibuat oleh Robert G. Brown.
Party
baris harus dilengkapi setiap saat dengan (ii) mitra masing-masing tepat di salah satu tabel yang berdiri untuk subtipe, yang (iii) harus 'mematuhi' nilai yang terkandung dalamParty.PartyTypeCode
kolom —ditandai pembeda— ".