Menerapkan subtipe dari subtipe dalam tipe / pola desain subtipe dengan subclass yang saling eksklusif

20

pengantar

Agar pertanyaan ini bermanfaat bagi pembaca masa depan, saya akan menggunakan model data umum untuk menggambarkan masalah yang saya hadapi.

Model data kami terdiri dari 3 entitas, yang akan diberi label sebagai A, Bdan C. Untuk menjaga hal-hal sederhana, semua atribut mereka akan intbertipe.

Entitas Atelah berikut atribut: D, Edan X;

Entitas Btelah berikut atribut: D, Edan Y;

Entity Cmemiliki atribut berikut: Ddan Z;

Karena semua entitas memiliki atribut yang sama D, saya telah memutuskan untuk menerapkan desain tipe / subtipe .

Penting: Entitas saling eksklusif! Ini berarti bahwa entitas adalah A atau B atau C.

Masalah:

Entitas Adan Bmemiliki atribut umum lainnya E, tetapi atribut ini tidak ada dalam entitas C.

Pertanyaan:

Saya ingin menggunakan karakteristik yang dijelaskan di atas untuk lebih mengoptimalkan desain saya, jika memungkinkan.

Sejujurnya, saya tidak tahu bagaimana melakukan ini, atau di mana harus mulai mencoba, maka posting ini.

AlwaysLearningNewStuff
sumber

Jawaban:

6

Sejauh Pertanyaan ini merupakan kelanjutan dari apakah penerapan pola desain jenis / subtipe saya (untuk subkelas yang saling eksklusif) benar? , yang merupakan kelanjutan dari Tidak tahu bagaimana mengubah entitas variabel menjadi tabel relasional , saya akan bertanya: apa sebenarnya yang Anda coba optimalkan? Penyimpanan? Model objek? Kompleksitas kueri? Performa permintaan? Ada trade-off ketika mengoptimalkan satu aspek vs yang lain karena Anda tidak dapat mengoptimalkan semua aspek secara bersamaan.

Saya sepenuhnya setuju dengan poin Remus mengenai:

  • Ada pro dan kontra untuk setiap pendekatan (yaitu faktor "itu tergantung" yang selalu ada), dan
  • Prioritas pertama adalah efisiensi model data (model data yang tidak efisien tidak dapat diperbaiki dengan kode aplikasi yang bersih dan / atau efisien)

Yang mengatakan, pilihan yang Anda hadapi adalah antara yang berikut, diatur dalam urutan paling tidak normalisasi ke paling normal:

  • mempromosikan properti Eke Tabel tipe dasar
  • menjaganya dalam beberapa sub-tipe Tabel
  • sepenuhnya normal Ekeluar ke tabel sub-kelas perantara baru pada tingkat yang sama dengan C, itu Adan Bakan langsung menjadi sub-kelas dari ( @ jawaban MDCCL )

Mari kita lihat setiap opsi:

Pindahkan properti Eke Tabel tipe dasar

PRO

  • Kompleksitas permintaan berkurang untuk query yang membutuhkan Etetapi tidak X, Yatau Z.
  • Berpotensi lebih efisien untuk query yang membutuhkan Etetapi tidak X, Yatau Z(query terutama agregat) karena tidak ada BERGABUNG.
  • Berpotensi membuat indeks aktif (D, E)(dan jika demikian, berpotensi Indeks yang Difilter di (D, E)mana EntityType <> C, jika kondisi seperti itu dibolehkan)

Kon

  • Tidak dapat menandai EsebagaiNOT NULL
  • Perlu tambahan CHECK CONSTRAINTpada tabel tipe-dasar untuk memastikan bahwa E IS NULLketika EntityType = C(meskipun ini bukan masalah besar)
  • Perlu mengedukasi pengguna model data mengapa Eharus NULL, dan bahkan harus diabaikan sepenuhnya, ketika EntityType = C.
  • Sedikit kurang efisien ketika Emerupakan tipe dengan panjang tetap, dan sebagian besar baris adalah untuk EntityType C(yaitu tidak menggunakan Ekarenanya NULL), dan tidak menggunakan salah satu SPARSEopsi pada kolom atau Kompresi Data pada Indeks Clustered
  • Berpotensi kurang efisien untuk kueri yang tidak perlu Ekarena kehadiran Edalam tabel tipe dasar akan meningkatkan ukuran setiap baris yang pada gilirannya mengurangi jumlah baris yang dapat ditampung pada halaman data. Tapi ini sangat tergantung pada tipe data yang tepat E, FILLFACTOR, berapa banyak baris dalam tabel tipe-dasar, dll.

Simpan properti Edi setiap sub-jenis Tabel

PRO

  • Model data yang lebih bersih (yaitu tidak perlu khawatir tentang mendidik orang lain mengapa kolom Edalam tabel tipe dasar tidak boleh digunakan karena "itu benar-benar tidak ada")
  • Mungkin lebih mirip dengan objek-model
  • Dapat menandai kolom seolah- NOT NULLolah ini adalah properti yang diperlukan entitas
  • Tidak perlu tambahan CHECK CONSTRAINTpada tabel tipe-dasar untuk memastikan bahwa E IS NULLketika EntityType = C(meskipun ini bukan keuntungan besar)

Kon

  • Perlu BERGABUNG ke sub-tipe Tabel untuk mendapatkan properti ini
  • Berpotensi sedikit kurang efisien saat membutuhkan E, karena BERGABUNG, tergantung pada berapa banyak baris A+ yang BAnda miliki dibandingkan dengan berapa banyak baris yang Cada.
  • Sedikit lebih sulit / rumit untuk operasi yang hanya berurusan dengan entitas Adan B(dan tidak C ) sebagai "tipe" yang sama. Tentu saja, Anda bisa mengabstraksi ini melalui tampilan yang melakukan a UNION ALLantara SELECTtabel JOINed untuk Adan tabel JOINed lain SELECTuntuk B. Itu akan mengurangi kompleksitas kueri SELECT tetapi tidak begitu membantu untuk INSERTdan UPDATEkueri.
  • Bergantung pada permintaan spesifik dan seberapa sering dieksekusi, ini bisa menjadi inefisiensi potensial dalam kasus di mana memiliki indeks (D, E)akan sangat membantu satu atau lebih sering digunakan query, karena mereka tidak dapat diindeks bersama.

Normalisasi Eke Tabel perantara antara kelas dasar dan A&B

(Harap dicatat bahwa saya suka jawaban @ MDCCL sebagai alternatif yang layak, tergantung pada keadaan. Berikut ini tidak dimaksudkan sebagai kritik ketat terhadap pendekatan itu, tetapi sebagai cara menambahkan beberapa perspektif - milik saya, tentu saja - dengan mengevaluasi itu dalam konteks yang sama dengan dua opsi yang telah saya usulkan. Ini akan membuatnya lebih mudah untuk memperjelas apa yang saya lihat sebagai perbedaan relatif antara normalisasi penuh dan pendekatan normalisasi parsial saat ini.)

PRO

  • model data sepenuhnya dinormalisasi (tidak mungkin ada yang salah dengan ini, mengingat itu adalah apa yang RDBMS dirancang untuk dilakukan)
  • mengurangi kompleksitas kueri untuk kueri yang membutuhkan Adan B, tetapi tidak C(yaitu tidak perlu dua kueri yang digabungkan melalui UNION ALL)

Kon

  • sedikit lebih banyak ruang yang digunakan ( Bartabel menduplikasi ID, dan ada kolom baru, BarTypeCode) [dapat diabaikan, tetapi sesuatu yang harus diperhatikan]
  • sedikit peningkatan dalam kompleksitas kueri karena tambahan JOINdiperlukan untuk mendapatkan salah satu AatauB
  • peningkatan luas permukaan untuk penguncian, sebagian besar pada INSERT( DELETEdapat ditangani secara implisit melalui penandaan Kunci Asing sebagai ON CASCADE DELETE) karena Transaksi akan diadakan terbuka sedikit lebih lama pada tabel kelas dasar (yaitu Foo) [dapat diabaikan, tetapi sesuatu yang harus diperhatikan]
  • tidak ada pengetahuan langsung dari jenis yang sebenarnya - Aatau B- dalam Tabel basis kelas, Foo; hanya tahu dari jenis Bryang dapat berupa Aatau B:

    Artinya, jika Anda perlu melakukan kueri atas informasi basis umum tetapi perlu mengategorikan berdasarkan tipe entitas atau memfilter satu atau lebih tipe entitas, maka tabel kelas dasar tidak memiliki informasi yang cukup, dalam hal ini Anda perlu LEFT JOINyang Barmeja. Ini juga akan mengurangi efektivitas pengindeksan FooTypeCodekolom.

  • tidak ada pendekatan yang konsisten untuk berinteraksi dengan A& Bvs C:

    Berarti, jika setiap entitas berhubungan langsung dengan tabel kelas-dasar sedemikian sehingga hanya ada satu yang BERGABUNG untuk mendapatkan entitas penuh, maka setiap orang dapat lebih cepat dan mudah membangun keakraban dalam hal bekerja dengan model data. Akan ada pendekatan umum untuk kueri / Prosedur Tersimpan yang membuatnya lebih cepat berkembang dan kecil kemungkinannya memiliki bug. Pendekatan yang konsisten juga membuatnya lebih cepat dan lebih mudah untuk menambahkan sub-tipe baru di masa depan.

  • berpotensi kurang dapat beradaptasi dengan aturan bisnis yang berubah seiring waktu:

    Artinya, segala sesuatu selalu berubah, dan cukup mudah untuk Enaik ke Tabel kelas dasar jika menjadi umum untuk semua sub-tipe. Juga cukup mudah untuk memindahkan properti umum ke sub-tipe jika perubahan sifat entitas membuat perubahan bernilai sementara. Cukup mudah untuk membagi sub-tipe menjadi dua sub-tipe (cukup buat SubTypeIDnilai lain ) atau menggabungkan dua atau lebih sub-tipe menjadi satu. Sebaliknya, bagaimana jika Enanti menjadi milik bersama semua sub-tipe? Maka lapisan perantara dari Bartabel akan menjadi tidak berarti, dan kompleksitas yang ditambahkan tidak akan sia-sia. Tentu saja, tidak mungkin untuk mengetahui apakah perubahan seperti itu akan terjadi dalam 5 atau bahkan 10 tahun, jadi Bartabelnya belum tentu, atau bahkan sangat mungkin, ide buruk (itulah sebabnya saya katakan " berpotensi kurang beradaptasi"). Ini hanya beberapa hal yang perlu dipertimbangkan; itu pertaruhan di kedua arah.

  • pengelompokan yang berpotensi tidak pantas:

    Berarti, hanya karena Eproperti dibagi antara jenis entitas Adan Btidak berarti itu Adan B harus dikelompokkan bersama. Hanya karena hal-hal "terlihat" sama (yaitu sifat yang sama) tidak berarti bahwa mereka sama.

Ringkasan

Seperti halnya memutuskan apakah / kapan melakukan denasionalisasi, cara terbaik mendekati situasi khusus ini tergantung pada pertimbangan aspek-aspek penggunaan model data berikut ini dan memastikan bahwa manfaatnya lebih besar daripada biayanya:

  • berapa banyak baris yang akan Anda miliki untuk setiap EntityType (lihat setidaknya 5 tahun ke depan, dengan asumsi pertumbuhan di atas rata-rata)
  • berapa GB masing-masing tabel ini (tipe dasar dan sub-tipe) dalam 5 tahun?
  • apa tipe data spesifik properti E
  • apakah hanya satu properti atau ada beberapa, atau bahkan beberapa, properti
  • pertanyaan apa yang Anda perlukan yang membutuhkan Edan seberapa sering mereka akan dieksekusi
  • pertanyaan apa yang Anda perlukan yang tidak perlu Edan seberapa sering mereka akan dieksekusi

Saya pikir saya cenderung default untuk menjaga Edalam tabel sub-tipe yang terpisah karena, paling tidak, "bersih". Saya akan mempertimbangkan pindah Eke tabel tipe dasar JIKA: sebagian besar baris bukan untuk EntityType C; dan jumlah baris setidaknya dalam jutaan; dan saya lebih sering mengeksekusi kueri yang membutuhkan Edan / atau kueri yang akan mendapat manfaat dari indeks pada (D, E)pelaksanaan yang sangat sering dan / atau memerlukan sumber daya sistem yang cukup sehingga memiliki indeks mengurangi pemanfaatan sumber daya secara keseluruhan, atau setidaknya mencegah lonjakan konsumsi sumber daya yang melampaui tingkat yang dapat diterima atau bertahan cukup lama untuk menyebabkan pemblokiran yang berlebihan dan / atau peningkatan deadlock.


MEMPERBARUI

OP mengomentari jawaban ini bahwa:

Majikan saya mengubah logika bisnis, menghapus E sama sekali!

Perubahan ini sangat penting karena persis apa yang saya prediksikan mungkin terjadi di sub "CONs" dari bagian "Normalisasi Eke tabel perantara antara kelas-dasar dan A& B" di atas (poin ke-6). Masalah khusus adalah betapa mudah / sulitnya untuk memperbaiki model data ketika perubahan tersebut terjadi (dan selalu terjadi). Beberapa akan berpendapat bahwa model data apa pun dapat di-refactored / diubah, jadi mulailah dengan yang ideal. Tetapi sementara itu benar pada tingkat teknis bahwa apa pun dapat di refactored, realitas situasi adalah masalah skala.

Sumber daya tidak terbatas, tidak hanya CPU / Disk / RAM, tetapi juga sumber daya pengembangan: waktu dan uang. Bisnis secara konstan menetapkan prioritas pada proyek karena sumber daya tersebut sangat terbatas. Dan cukup sering (setidaknya dalam pengalaman saya), proyek untuk mendapatkan efisiensi (bahkan kinerja sistem maupun pengembangan lebih cepat / lebih sedikit bug) diprioritaskan di bawah proyek yang meningkatkan fungsionalitas. Walaupun hal ini membuat frustasi bagi kami orang-orang teknis karena kami memahami apa manfaat jangka panjang dari proyek-proyek refactoring, itu hanya sifat bisnis bahwa orang-orang bisnis yang kurang teknis, lebih mudah melihat hubungan langsung antara fungsi baru dan baru. pendapatan. Intinya adalah: "kami akan kembali untuk memperbaikinya nanti" == "

Dengan mengingat hal itu, jika ukuran data cukup kecil sehingga perubahan dapat dibuat sangat kueri, dan / atau Anda memiliki jendela pemeliharaan yang cukup panjang untuk tidak hanya melakukan perubahan tetapi juga memutar kembali jika terjadi sesuatu salah, lalu menormalkan Eke Tabel perantara antara tabel kelas dasar dan tabel A& Bsub-kelas bisa berfungsi (meskipun itu masih membuat Anda tidak memiliki pengetahuan langsung tentang jenis tertentu ( AatauB) di tabel kelas dasar). TETAPI, jika Anda memiliki ratusan juta baris dalam tabel ini, dan sejumlah besar kode merujuk pada tabel (kode yang harus diuji ketika perubahan dilakukan), maka biasanya membayar lebih pragmatis daripada idealis. Dan ini adalah lingkungan yang harus saya tangani selama bertahun-tahun: 987 juta baris & 615 GB di tabel kelas dasar, tersebar di 18 server. Dan begitu banyak kode mengenai tabel ini (tabel kelas dasar dan kelas sub-kelas) sehingga ada banyak hambatan - kebanyakan dari manajemen tetapi kadang-kadang dari anggota tim lainnya - untuk membuat perubahan apa pun karena jumlah pengembangan dan Sumber daya QA yang perlu dialokasikan.

Jadi, sekali lagi, pendekatan "terbaik" hanya dapat ditentukan situasi demi situasi: Anda perlu mengetahui sistem Anda (yaitu seberapa banyak data dan bagaimana semua tabel dan kode berhubungan), bagaimana menyelesaikan refactoring, dan orang-orang Anda bekerja dengan (tim Anda dan mungkin manajemen - dapatkah Anda menerima dukungan mereka untuk proyek semacam itu?). Ada beberapa perubahan yang telah saya sebutkan dan rencanakan untuk 1 - 2 tahun, dan mengambil beberapa sprint / rilis untuk mendapatkan mungkin 85% dari mereka diimplementasikan. Tetapi jika Anda hanya memiliki <1 juta baris dan tidak banyak kode yang terikat pada tabel ini, maka Anda mungkin dapat memulai dari sisi yang lebih ideal / "murni".

Ingat saja, ke mana pun Anda memilih untuk pergi, perhatikan bagaimana model itu bekerja setidaknya selama 2 tahun ke depan (jika mungkin). Perhatikan apa yang berhasil dan apa yang menyebabkan rasa sakit, bahkan jika itu tampak seperti ide terbesar pada saat itu (yang berarti Anda juga perlu membiarkan diri Anda menerima mengacau - kita semua melakukannya - sehingga Anda dapat dengan jujur ​​mengevaluasi poin rasa sakit ). Dan perhatikan mengapa keputusan tertentu berhasil atau tidak sehingga Anda dapat membuat keputusan yang lebih cenderung menjadi "lebih baik" lain kali :-).

Solomon Rutzky
sumber
17

Menurut Martin Fowler, ada 3 pendekatan untuk masalah pewarisan tabel:

  • Single Table Inheritance : Satu tabel mewakili semua tipe. Atribut yang tidak digunakan NULLed.
  • Warisan Tabel Beton : Satu tabel per jenis beton, setiap kolom tabel untuk setiap atribut dari tipe tersebut. Tidak ada hubungan antar tabel.
  • Class Table Inheritance : Satu tabel per jenis, masing-masing tabel hanya memiliki atribut untuk atribut baru, tidak diwariskan. Tabel terkait mencerminkan hierarki pewarisan tipe aktual.

Anda dapat mulai dengan ini sebagai titik awal untuk mencari pro dan kontra dari setiap pendekatan. Intinya adalah bahwa semua pendekatan memiliki kelemahan besar, dan tidak ada yang memiliki keunggulan luar biasa. Lebih dikenal sebagai objek ketidakcocokan impedansi relasional , masalah ini belum menemukan solusi.

Secara pribadi saya menemukan bahwa jenis masalah yang dapat menyebabkan desain relasional buruk adalah urutan besarnya lebih serius daripada jenis masalah yang timbul dari desain tipe buruk . Desain basis data yang buruk menyebabkan permintaan lambat, memperbarui anomali, ledakan ukuran data, kebuntuan dan aplikasi tidak responsif, dan puluhan hingga ratusan Gigabytes data tenggelam dalam format yang salah . Desain tipe buruk menyebabkan sulit untuk mempertahankan dan memperbarui kode , bukan runtime. Oleh karena itu, dalam buku saya, desain relasional yang benar mengalahkan kemurnian jenis OO berulang-ulang.

Remus Rusanu
sumber
@AlwaysLearningNewStuff Saya pikir pertanyaan ini merupakan tindak lanjut dari dba.stackexchange.com/questions/139092 , benar? Dalam pelaksanaannya sana Anda lakukan memiliki warisan meja.
Remus Rusanu
Ya itu, sebelum mengajukan pertanyaan ini saya ingin memastikan saya mengerti benar bagaimana menerapkan desain tipe / subtipe terlebih dahulu. Sekarang saya menghadapi masalah yang dijelaskan di atas ketika beberapa (tapi tidak semua!) Subkelas memiliki atribut bersama. Saya bertanya-tanya apakah ada sesuatu yang dapat saya lakukan untuk mengoptimalkan model data dalam kasus itu, alih-alih mengabaikan nuansa itu ...
AlwaysLearningNewStuff
6

Menurut interpretasi saya tentang spesifikasi Anda, Anda ingin menemukan metode untuk mengimplementasikan dua struktur subtipe-subtipe supertipe yang berbeda (namun terhubung ) .

Untuk mengekspos pendekatan untuk mencapai tugas yang disebutkan, saya akan menambah skenario yang dipermasalahkan dua tipe entitas hipotetis klasik yang disebut Foodan Bar, yang akan saya jelaskan di bawah.

Peraturan bisnis

Berikut adalah beberapa pernyataan yang akan membantu saya membuat model yang logis:

  • A Foo is either one Bar or one C
  • A Foo is categorized by one FooType
  • A Bar is either one A or one C
  • A Bar is classified by one BarType

Model yang logis

Dan kemudian, model logis IDEF1X [1] yang dihasilkan ditunjukkan pada Gambar 1 (dan Anda juga dapat mengunduhnya dari Dropbox sebagai PDF ):

Gambar 1 - Model Data Hubungan Hubungan Subtipe Hipertetis

Tambahan Foo and Bar

Saya tidak menambah Foodan Barmembuat model terlihat lebih baik, tetapi untuk membuatnya lebih ekspresif. Saya menganggap mereka penting karena hal berikut:

  • Saat Adan Bmembagikan atribut yang dinamai E, fitur ini menunjukkan bahwa mereka adalah tipe subentitas dari konsep , peristiwa , orang , pengukuran , dll. Yang berbeda, yang saya wakili dengan menggunakan Bartipe superentity yang, pada gilirannya, adalah tipe subentity Foo, yang menyimpan Datribut di bagian atas hierarki.

  • Sejak Chanya saham satu atribut dengan sisa jenis entitas di bawah diskusi, yaitu, D, aspek ini menyindir bahwa itu adalah jenis subentity dari jenis lain dari konsep , acara , orang , pengukuran , dll, jadi saya digambarkan keadaan ini berdasarkan yang Foosuper entitas jenis.

Namun, ini hanya asumsi, dan karena database relasional dimaksudkan untuk mencerminkan semantik konteks bisnis tertentu secara akurat, Anda harus mengidentifikasi dan mengklasifikasikan semua hal yang menarik di domain spesifik Anda sehingga Anda dapat, tepatnya, menangkap lebih banyak makna .

Faktor penting pada fase desain

Sangat berguna untuk menyadari fakta bahwa, dengan mengesampingkan semua terminologi, klaster supertipe-subtipe eksklusif adalah hubungan biasa. Mari kita gambarkan situasi dengan cara berikut:

  • Setiap kejadian jenis superentitas eksklusif terkait dengan hanya satu jenis pelengkap subentitas .

Dengan demikian, ada korespondensi (atau kardinalitas) dari satu-ke-satu (1: 1) dalam kasus ini.

Seperti yang Anda ketahui dari posting sebelumnya, atribut diskriminator (kolom, ketika diimplementasikan) memainkan peran penting ketika membuat asosiasi dari sifat ini, karena itu menunjukkan contoh subtipe yang benar dengan mana supertipe terhubung . The migrasi dari PRIMARY KEY dari (i) supertype untuk (ii) subtipe juga penting utama.

Struktur DDL beton

Dan kemudian saya menulis struktur DDL yang didasarkan pada model logis yang disajikan di atas:

CREATE TABLE FooType -- Look-up table.
(
    FooTypeCode     CHAR(2)  NOT NULL,
    Description     CHAR(90) NOT NULL, 
    CreatedDateTime DATETIME NOT NULL,
    CONSTRAINT PK_FooType             PRIMARY KEY (FooTypeCode),
    CONSTRAINT AK_FooType_Description UNIQUE      (Description)
);

CREATE TABLE Foo -- Supertype
(
    FooId           INT      NOT NULL, -- This PK migrates (1) to ‘Bar’ as ‘BarId’, (2) to ‘A’ as ‘AId’, (3) to ‘B’ as ‘BId’, and (4) to ‘C’ as ‘CId’.
    FooTypeCode     CHAR(2)  NOT NULL, -- Discriminator column.
    D               INT      NOT NULL, -- Column that applies to ‘Bar’ (and therefore to ‘A’ and ‘B’) and ‘C’.
    CreatedDateTime DATETIME NOT NULL,
    CONSTRAINT PK_Foo                 PRIMARY KEY (FooId),
    CONSTRAINT FK_from_Foo_to_FooType FOREIGN KEY (FooTypeCode)
        REFERENCES FooType (FooTypeCode)
);

CREATE TABLE BarType -- Look-up table.
(
    BarTypeCode CHAR(1)  NOT NULL,  
    Description CHAR(90) NOT NULL,  
    CONSTRAINT PK_BarType             PRIMARY KEY (BarTypeCode),
    CONSTRAINT AK_BarType_Description UNIQUE      (Description)
);

CREATE TABLE Bar -- Subtype of ‘Foo’.
(
    BarId       INT     NOT NULL, -- PK and FK.
    BarTypeCode CHAR(1) NOT NULL, -- Discriminator column. 
    E           INT     NOT NULL, -- Column that applies to ‘A’ and ‘B’.
    CONSTRAINT PK_Bar             PRIMARY KEY (BarId),
    CONSTRAINT FK_from_Bar_to_Foo FOREIGN KEY (BarId)
        REFERENCES Foo (FooId),
    CONSTRAINT FK_from_Bar_to_BarType FOREIGN KEY (BarTypeCode)
        REFERENCES BarType (BarTypeCode)    
);

CREATE TABLE A -- Subtype of ‘Bar’.
(
    AId INT NOT NULL, -- PK and FK.
    X   INT NOT NULL, -- Particular column.  
    CONSTRAINT PK_A             PRIMARY KEY (AId),
    CONSTRAINT FK_from_A_to_Bar FOREIGN KEY (AId)
        REFERENCES Bar (BarId)  
);

CREATE TABLE B -- (1) Subtype of ‘Bar’ and (2) supertype of ‘A’ and ‘B’.
(
    BId INT NOT NULL, -- PK and FK.
    Y   INT NOT NULL, -- Particular column.  
    CONSTRAINT PK_B             PRIMARY KEY (BId),
    CONSTRAINT FK_from_B_to_Bar FOREIGN KEY (BId)
        REFERENCES Bar (BarId)  
);

CREATE TABLE C -- Subtype of ‘Foo’.
(
    CId INT NOT NULL, -- PK and FK.
    Z   INT NOT NULL, -- Particular column.  
    CONSTRAINT PK_C             PRIMARY KEY (CId),
    CONSTRAINT FK_from_C_to_Foo FOREIGN KEY (FooId)
        REFERENCES Foo (FooId)  
);

Dengan struktur ini, Anda menghindari penyimpanan tanda NULL di tabel dasar (atau relasi ) Anda, yang akan menimbulkan ambiguitas pada basis data Anda.

Integritas, konsistensi, dan pertimbangan lain

Setelah Anda menerapkan basis data Anda, Anda harus memastikan bahwa (a) setiap baris supertype eksklusif selalu dilengkapi oleh mitra subtipe yang sesuai dan, pada gilirannya, menjamin bahwa (b) baris subtipe tersebut kompatibel dengan nilai yang terkandung dalam kolom diskriminator supertype. . Oleh karena itu, cukup mudah untuk menggunakan ACID TRANSACTIONSuntuk memastikan bahwa kondisi ini terpenuhi dalam database Anda.

Anda tidak boleh menyerah pada kesehatan logis, ekspresi diri, dan akurasi database Anda, ini adalah aspek yang jelas membuat database Anda lebih solid.

Dua jawaban yang diposting sebelumnya sudah termasuk poin terkait yang tentu saja layak dipertimbangkan ketika merancang, membuat dan mengelola basis data Anda dan program aplikasinya.

Mengambil data dengan cara LIHAT definisi

Anda dapat mengatur beberapa tampilan yang menggabungkan kolom dari kelompok subtipe-supertipe yang berbeda , sehingga Anda dapat mengambil data secara langsung tanpa, misalnya, menulis klausa JOIN yang diperlukan setiap waktu. Dengan cara ini, Anda dapat PILIH langsung DARI VIEW ( relasi turunan atau tabel ) yang menarik dengan mudah.

Seperti yang Anda lihat, "Ted" Codd, tidak diragukan lagi, seorang jenius. Alat yang diwariskannya cukup kuat dan elegan, dan, tentu saja, terintegrasi dengan baik satu sama lain.

Sumber terkait

Jika Anda ingin menganalisis beberapa basis data yang luas yang melibatkan hubungan supertype-subtype, Anda akan menemukan nilai dari jawaban luar biasa yang diajukan oleh @PerformanceDBA untuk pertanyaan Stack Overflow berikut:


Catatan

1. 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 teoretis awal yang ditulis oleh Dr. EF Codd; pada (b) yang Entity-Relationship tampilan data, yang dikembangkan oleh Dr. PP Chen ; dan juga pada (c) Teknik Desain Basis Data Logis, yang dibuat oleh Robert G. Brown. Perlu dicatat bahwa IDEF1X diformalkan dengan cara logika tingkat pertama.

MDCCL
sumber
Majikan saya mengubah logika bisnis, menghapus Esemuanya! Alasan untuk menerima jawaban pengguna srutzky adalah karena memberikan poin yang baik yang membantu saya untuk membuat keputusan saya memilih rute yang paling efisien. Kalau bukan karena itu saya akan menerima jawaban Anda. Saya telah membatalkan jawaban Anda sebelumnya. Terima kasih lagi!
AlwaysLearningNewStuff