Ya, identifikasi asosiasi atau hubungan banyak-ke-banyak (M: N untuk singkatnya) adalah situasi yang dihadapi oleh seorang praktisi basis data secara umum ketika menyusun skema konseptual. Asosiasi rasio kardinalitas tersebut muncul dalam lingkungan bisnis yang sifatnya sangat berbeda, dan ketika diwakili dengan tepat pada tingkat logis melalui, misalnya, pengaturan SQL-DDL, mereka tidak memperkenalkan redudansi berbahaya.
Dengan cara ini, tujuan dari latihan pemodelan basis data harus mencerminkan karakteristik yang relevan dari konteks bisnis yang diminati dengan presisi tinggi ; oleh karena itu, jika Anda mengidentifikasi dengan benar bahwa ada banyak asosiasi M: N, maka Anda harus mengungkapkannya dalam (a) skema konseptual dan juga dalam (b) deklarasi tingkat logis masing-masing, tidak peduli berapa banyak koneksi itu —atau lainnya— jenis rasio kardinalitas harus diatasi.
Peraturan bisnis
Anda telah memberikan pertanyaan yang dikontekstualisasikan dengan baik, dan juga telah mengklarifikasi bahwa database yang Anda kerjakan adalah murni hipotesis, yang merupakan poin penting karena saya hargai bahwa skenario bisnis "dunia nyata" seperti yang sedang dipertimbangkan akan jauh lebih luas dan, karenanya, akan menyiratkan persyaratan informasi yang lebih kompleks.
Saya memutuskan untuk (1) membuat beberapa modifikasi dan perluasan pada aturan bisnis yang telah Anda berikan untuk (2) menghasilkan skema konseptual yang lebih deskriptif — walaupun masih agak hipotetis—. Berikut adalah beberapa formulasi yang saya kumpulkan:
- Suatu Pihak 1 adalah Orang atau Organisasi
- Suatu Pihak diklasifikasi oleh tepat satu PartyType
- Sebuah PartyType mengklasifikasikan nol-satu-atau-banyak Pihak
- Suatu Organisasi mengembangkan nol-satu-atau-banyak Produk
- Sebuah produk adalah baik Sistem atau permainan
- Suatu Produk diklasifikasi oleh tepat satu Jenis Produk
- Suatu Sistem dikatalogkan oleh persisnya satu SystemType
- Sebuah permainan bisa dimainkan melalui satu-ke-banyak Sistem
- Sebuah Sistem yang digunakan untuk bermain satu-ke-banyak Permainan
- Sebuah Game diklasifikasikan oleh Genre nol-satu-atau-banyak
- Sebuah Genre mengklasifikasikan nol-satu-atau-banyak Permainan
- Sebuah Produk berasal dari Pekerjaan satu ke banyak
- Sebuah Job dipenuhi oleh nol-satu-atau-banyak Orang , yang memainkan peran dari Kolaborator
- Sebuah Orang adalah Kolaborator di nol-satu-atau-banyak Jobs
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 Orang dan Organisasi .
Diagram IDEF1X
Selanjutnya, saya membuat diagram IDEF1X 2 yang ditunjukkan pada Gambar 1 (pastikan untuk mengklik tautan untuk melihatnya dalam resolusi yang lebih tinggi), menggabungkan dalam satu perangkat grafis aturan bisnis yang disajikan di atas (bersama dengan beberapa lainnya yang tampaknya relevan):
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) bahan teoritis awal yang ditulis oleh pencetus tunggal model relasional, yaitu, Dr. EF Codd; pada (b) tampilan entitas-hubungan data, yang dikembangkan oleh Dr. PP Chen ; dan juga pada (c) Teknik Desain Basis Data Logis, yang dibuat oleh Robert G. Brown.
Seperti yang Anda lihat, saya hanya menggambarkan tiga asosiasi M: N dengan cara tipe entitas asosiatif yang sesuai , yaitu:
- Kolaborator
- SystemGame
- GameGenre
Di antara aspek-aspek lain, ada dua struktur subtipe-supertipe yang berbeda , di mana:
Orang dan Organisasi adalah subtipe entitas yang saling eksklusif dari Pihak , supertipe entitas mereka
Produk adalah supertype dari System and Game , yang pada gilirannya adalah subtipe yang saling eksklusif
Jika Anda tidak terbiasa dengan asosiasi subtipe-supertipe, Anda mungkin menemukan bantuan, misalnya, jawaban saya untuk pertanyaan yang berjudul:
Ilustrasi tata letak SQL-DDL yang logis
Secara berturut-turut, kita harus memastikan bahwa, pada level logis:
- Setiap jenis entitas diwakili oleh tabel basis individu
- Setiap properti tunggal dari tipe entitas yang berlaku dilambangkan dengan kolom tertentu
- Tipe data yang pasti diperbaiki untuk setiap kolom untuk memastikan bahwa semua nilai yang dikandungnya milik set tertentu dan didefinisikan dengan baik, baik itu INT, DATETIME, CHAR, dll. (Tentu saja, ketika menggunakan, misalnya, Firebird atau PostgreSQL , Anda mungkin ingin menggunakan DOMAIN yang lebih kuat)
- Beberapa kendala dikonfigurasikan (secara deklaratif) untuk menjamin bahwa pernyataan dalam bentuk baris yang dipertahankan di semua tabel mematuhi aturan bisnis yang ditentukan pada tingkat konseptual
Jadi saya menyatakan pengaturan DDL berikut berdasarkan diagram IDEF1X yang sebelumnya ditunjukkan:
CREATE TABLE PartyType ( -- Stands for an independent entity type.
PartyTypeCode CHAR(1) NOT NULL, -- To retain 'P' or 'O'.
Name CHAR(30) NOT NULL, -- To keep 'Person' or 'Organization'.
--
CONSTRAINT PartyType_PK PRIMARY KEY (PartyTypeCode)
);
CREATE TABLE Party ( -- Represents an entity supertype.
PartyId INT NOT NULL,
PartyTypeCode CHAR(1) NOT NULL, -- To hold the value that indicates the type of the row denoting the complementary subtype occurrence: either 'P' for 'Person' or 'O' for 'Organization'.
CreatedDateTime TIMESTAMP NOT NULL,
--
CONSTRAINT Party_PK PRIMARY KEY (PartyId),
CONSTRAINT PartyToPartyType_FK FOREIGN KEY (PartyTypeCode)
REFERENCES PartyType (PartyTypeCode)
);
CREATE TABLE Person ( -- Denotes an entity subtype.
PersonId INT NOT NULL, -- To be constrained as (a) the PRIMARY KEY and (b) a FOREIGN KEY.
FirstName CHAR(30) NOT NULL,
LastName CHAR(30) NOT NULL,
GenderCode CHAR(3) NOT NULL,
BirthDate DATE NOT NULL,
--
CONSTRAINT Person_PK PRIMARY KEY (PersonId),
CONSTRAINT Person_AK UNIQUE (FirstName, LastName, GenderCode, BirthDate), -- Composite ALTERNATE KEY.
CONSTRAINT PersonToParty_FK FOREIGN KEY (PersonId)
REFERENCES Party (PartyId)
);
CREATE TABLE Organization ( -- Stands for an entity subtype.
OrganizationId INT NOT NULL, -- To be constrained as (a) the PRIMARY KEY and (b) a FOREIGN KEY.
Name CHAR(30) NOT NULL,
FoundingDate DATE NOT NULL,
--
CONSTRAINT Organization_PK PRIMARY KEY (OrganizationId),
CONSTRAINT Organization_AK UNIQUE (Name), -- Single-column ALTERNATE KEY.
CONSTRAINT OrganizationToParty_FK FOREIGN KEY (OrganizationId)
REFERENCES Party (PartyId)
);
CREATE TABLE ProductType ( -- Represents an independent entity type.
ProductTypeCode CHAR(1) NOT NULL, -- To enclose the values 'S' and 'G' in the corresponding rows.
Name CHAR(30) NOT NULL, -- To comprise the values 'System' and 'Person' in the respective rows.
--
CONSTRAINT ProductType_PK PRIMARY KEY (ProductTypeCode)
);
CREATE TABLE Product ( -- Denotes an entity supertype.
OrganizationId INT NOT NULL,
ProductNumber INT NOT NULL,
ProductTypeCode CHAR(1) NOT NULL, -- To keep the value that indicates the type of the row denoting the complementary subtype occurrence: either 'S' for 'System' or 'G' for 'Game'.
CreatedDateTime DATETIME NOT NULL,
--
CONSTRAINT Product_PK PRIMARY KEY (OrganizationId, ProductNumber), -- Composite PRIMARY KEY.
CONSTRAINT ProductToOrganization_FK FOREIGN KEY (OrganizationId)
REFERENCES Organization (OrganizationId),
CONSTRAINT ProductToProductType_FK FOREIGN KEY (ProductTypeCode)
REFERENCES ProductType (ProductTypeCode)
);
CREATE TABLE SystemType ( -- Stands for an independent entity type.
SystemTypeCode CHAR(1) NOT NULL,
Name CHAR(30) NOT NULL,
--
CONSTRAINT SystemType_PK PRIMARY KEY (SystemTypeCode)
);
CREATE TABLE MySystem ( -- Represents a dependent entity type.
OrganizationId INT NOT NULL, -- To be constrained as (a) the PRIMARY KEY and (b) a FOREIGN KEY.
SystemNumber INT NOT NULL,
SystemTypeCode CHAR(1) NOT NULL,
ParticularColumn CHAR(30) NOT NULL,
--
CONSTRAINT System_PK PRIMARY KEY (OrganizationId, SystemNumber),
CONSTRAINT SystemToProduct_FK FOREIGN KEY (OrganizationId, SystemNumber)
REFERENCES Product (OrganizationId, ProductNumber),
CONSTRAINT SystemToSystemType_FK FOREIGN KEY (SystemTypeCode)
REFERENCES SystemType (SystemTypeCode)
);
CREATE TABLE Game ( -- Denotes an entity subtype.
OrganizationId INT NOT NULL, -- To be constrained as (a) the PRIMARY KEY and (b) a FOREIGN KEY.
GameNumber INT NOT NULL,
SpecificColumn CHAR(30) NOT NULL,
--
CONSTRAINT Game_PK PRIMARY KEY (OrganizationId, GameNumber),
CONSTRAINT GameToProduct_FK FOREIGN KEY (OrganizationId, GameNumber)
REFERENCES Product (OrganizationId, ProductNumber)
);
CREATE TABLE Genre ( -- Stands for an independent entity type.
GenreNumber INT NOT NULL,
Name CHAR(30) NOT NULL,
Description CHAR(90) NOT NULL,
--
CONSTRAINT Genre_PK PRIMARY KEY (GenreNumber),
CONSTRAINT Genre_AK1 UNIQUE (Name),
CONSTRAINT Genre_AK2 UNIQUE (Description)
);
CREATE TABLE SystemGame ( -- Represents an associative entity type or M:N association.
SystemOrganizationId INT NOT NULL,
SystemNumber INT NOT NULL,
GameOrganizationId INT NOT NULL,
GameNumber INT NOT NULL,
CreatedDateTime DATETIME NOT NULL,
--
CONSTRAINT SystemGame_PK PRIMARY KEY (SystemOrganizationId, SystemNumber, GameOrganizationId, GameNumber), -- Composite PRIMARY KEY.
CONSTRAINT SystemGameToSystem_FK FOREIGN KEY (SystemOrganizationId, SystemNumber) -- Multi-column FOREIGN KEY.
REFERENCES MySystem (OrganizationId, SystemNumber),
CONSTRAINT SystemGameToGame_FK FOREIGN KEY (SystemOrganizationId, GameNumber) -- Multi-column FOREIGN KEY.
REFERENCES Game (OrganizationId, GameNumber)
);
CREATE TABLE GameGenre ( -- Denotes an associative entity type or M:N association.
GameOrganizationId INT NOT NULL,
GameNumber INT NOT NULL,
GenreNumber INT NOT NULL,
CreatedDateTime DATETIME NOT NULL,
--
CONSTRAINT GameGenre_PK PRIMARY KEY (GameOrganizationId, GameNumber, GenreNumber), -- Composite PRIMARY KEY.
CONSTRAINT GameGenreToGame_FK FOREIGN KEY (GameOrganizationId, GameNumber)
REFERENCES Game (OrganizationId, GameNumber), -- Multi-column FOREIGN KEY.
CONSTRAINT GameGenreToGenre_FK FOREIGN KEY (GenreNumber)
REFERENCES Genre (GenreNumber)
);
CREATE TABLE Job ( -- Stands for an associative entity type or M:N association.
OrganizationId INT NOT NULL,
ProductNumber INT NOT NULL,
JobNumber INT NOT NULL,
Title CHAR(30) NOT NULL,
CreatedDateTime DATETIME NOT NULL,
--
CONSTRAINT Job_PK PRIMARY KEY (OrganizationId, ProductNumber, JobNumber), -- Composite PRIMARY KEY.
CONSTRAINT Job_AK UNIQUE (Title), -- Single-column ALTERNATE KEY.
CONSTRAINT JobToProduct_FK FOREIGN KEY (OrganizationId, ProductNumber) -- Multi-column FOREIGN KEY.
REFERENCES Product (OrganizationId, ProductNumber)
);
CREATE TABLE Collaborator ( -- Represents an associative entity type or M:N association.
CollaboratorId INT NOT NULL,
OrganizationId INT NOT NULL,
ProductNumber INT NOT NULL,
JobNumber INT NOT NULL,
AssignedDateTime DATETIME NOT NULL,
--
CONSTRAINT Collaborator_PK PRIMARY KEY (CollaboratorId, OrganizationId, ProductNumber, JobNumber), -- Composite PRIMARY KEY.
CONSTRAINT CollaboratorToPerson_FK FOREIGN KEY (CollaboratorId)
REFERENCES Person (PersonId),
CONSTRAINT CollaboratorToJob_FK FOREIGN KEY (OrganizationId, ProductNumber, JobNumber) -- Multi-column FOREIGN KEY.
REFERENCES Job (OrganizationId, ProductNumber, JobNumber)
);
Hal ini tepat untuk stres yang ada deklarasi dari komposit kendala PRIMARY KEY di beberapa meja, yang berdiri untuk hirarki koneksi yang terjadi antara jenis entitas konseptual, pengaturan yang dapat sangat bermanfaat yang berkenaan dengan data retrieval ketika, misalnya, mengungkapkan SELECT operasi yang menyertakan klausa GABUNG untuk mendapatkan tabel turunan .
Ya, (i) setiap asosiasi M: N dan (ii) setiap jenis entitas terkait dilambangkan dengan (iii) tabel terkait dalam struktur DDL logis, jadi berikan perhatian khusus pada kendala PRIMARY dan ASING KUNCI (dan catatan yang saya tinggalkan sebagai komentar) dari tabel yang mewakili elemen-elemen konseptual ini, karena mereka membantu memastikan bahwa hubungan antara baris yang relevan memenuhi rasio kardinalitas yang berlaku.
Penggunaan kunci komposit diperkenalkan oleh Dr. EF Codd dari awal paradigma relasional, seperti yang ditunjukkan dalam contoh-contoh yang ia masukkan dalam makalah seminal tahun 1970-nya yang berjudul A Model Relasional untuk Bank Data Bersama Besar (yang, tepatnya, juga menyajikan metode paling elegan untuk menangani asosiasi M: N konseptual).
Saya memasang db <> biola dan SQL Biola , keduanya berjalan di Microsoft SQL Server 2014, sehingga struktur dapat diuji "dalam tindakan".
Normalisasi
Normalisasi adalah prosedur tingkat logis yang menyiratkan, pada dasarnya berbicara:
Menghilangkan kolom non-atomik melalui bentuk normal pertama sehingga manipulasi dan penyempitan data jauh lebih mudah untuk diatasi dengan penggunaan bahasa terjemahan (misalnya, SQL).
Menyingkirkan dependensi yang tidak diinginkan di antara kolom tabel tertentu berdasarkan formulir normal berturut-turut untuk menghindari pembaruan anomali .
Secara alami, seseorang harus memperhitungkan makna yang dibawa oleh tabel dan kolom yang dipermasalahkan.
Saya suka menganggap normalisasi sebagai tes yang didasarkan pada sains bahwa seorang desainer berlaku untuk elemen-elemen terkait begitu ia telah melukiskan pengaturan level logis yang stabil untuk menentukan apakah item-itemnya memenuhi setiap bentuk normal atau tidak. Kemudian, jika perlu, perancang mengambil tindakan koreksi yang tepat.
Redundansi
Dalam model relasional, sementara duplikasi nilai yang terkandung dalam kolom tidak hanya dapat diterima tetapi diharapkan , baris duplikat dilarang . Sejauh itu, sejauh yang saya bisa lihat, baris duplikat dan jenis redundansi berbahaya lainnya dicegah di semua tabel yang terdiri dari tata letak logis yang diungkapkan sebelumnya, mungkin Anda ingin mengklarifikasi keprihatinan Anda dalam hal ini.
Bagaimanapun, Anda tentu saja dapat (a) mengevaluasi pada struktur Anda sendiri dengan memberikan formulir normal untuk menentukan apakah memenuhi persyaratan dan (b) memodifikasinya jika perlu.
Sumber terkait
- Dalam seri posting ini saya menyajikan beberapa pertimbangan tentang asosiasi M: N langsung yang dapat menghubungkan contoh dua jenis entitas yang berbeda .
- Dalam satu lain ini saya mengusulkan sebuah pendekatan untuk menangani terjadinya “Bill of Material” atau “Bagian Ledakan” membangun, di mana saya menjelaskan bagaimana menghubungkan berbeda contoh dari yang sama jenis badan.
Asosiasi ternary
Ada aspek penting lain yang Anda kemukakan melalui komentar (diposting dalam jawaban yang sekarang dihapus):
Setiap kali saya mencoba membuat jembatan elemen-elemen di jembatan itu juga memiliki Banyak ke Banyak, saya mendapat kesan yang tidak diperbolehkan atau setidaknya berkecil hati.
Keadaan itu tampaknya mengindikasikan bahwa salah satu kekhawatiran Anda berkaitan dengan asosiasi ternary konseptual . Pada dasarnya, asosiasi semacam ini muncul ketika ada (1) hubungan yang melibatkan (2) dua hubungan lain, dengan kata lain "hubungan antar hubungan" —sebuah situasi yang khas juga, karena suatu hubungan adalah suatu entitas dalam dirinya sendiri. -.
Pengaturan ini, bila dikelola dengan tepat, juga tidak membawa redudansi berbahaya. Dan, ya, jika ada kasus penggunaan tertentu di mana Anda mengidentifikasi bahwa hubungan tersebut menghadirkan diri di antara jenis entitas "dunia nyata", Anda harus (i) memodelkan dan (ii) menyatakannya dengan akurat di tingkat logis.