Hubungan Kunci Asing Bersyarat

14

Saat ini saya memiliki kunci asing antara dua entitas, dan saya ingin membuat hubungan itu bersyarat ke jenis entitas dari salah satu tabel. Inilah hierarki tabel, ini dilakukan melalui refren FK dari anak ke orang tua

                  Store
            /                \
  Employees                    \
                             TransactionalStores
                            /       |         \
                     Kiosks         |          BrickMortars
                                 Onlines

Saat ini saya memiliki hubungan FK dari Karyawan ke toko

ALTER TABLE Employees ADD CONSTRAINT Employee_Store
            FOREIGN KEY (TransStoreId)
            REFERENCES TransactionalStores(StoreId)

Saya ingin menambahkan persyaratan:

WHERE TransactionalStores.storeType != 'ONLINE_TYPE'

Apakah ini mungkin atau haruskah saya subklas TransactionalStores menjadi dua subTipe baru (misalnya PhysicalStores dan VirtualStores)

Kartu as
sumber

Jawaban:

17

Kunci asing dapat dibuat bersyarat ... semacam. Anda tidak menunjukkan tata letak setiap tabel, jadi di sini adalah desain khas yang menunjukkan hubungan Anda:

create table TransactionalStores(
    ID        int   not null auto_increment,
    StoreType char  not null,
    ..., -- other data
    constraint CK_TransStoreType check( StoreType in( 'B', 'K', 'O' )),
    constraint PK_TransactionalStores primary key( ID ),
    constraint UQ_TransStoreTypes unique( ID, StoreType ) -- for FK references
);
create table Kiosks(
    ID         int   not null,
    StoreType  char  not null,
    ..., -- other Kiosk data
    constraint CK_KioskStoreType check( StoreType = 'K' ), -- kiosks only
    constraint PK_Kiosks primary key( ID, StoreType ),
    constraint FK_Kiosks_TransStores foreign key( ID, StoreType )
        references TransactionalStores( ID, StoreType )
);

Onlines dan BrickMorters akan memiliki struktur dasar yang sama tetapi dengan StoreType dibatasi hanya 'O' atau 'B' yang sesuai.

Sekarang Anda ingin referensi dari tabel lain ke TransactionalStores (dan melaluinya ke berbagai tabel toko) tetapi terbatas pada Kios dan BrickMorter. Satu-satunya perbedaan adalah kendala:

create table Employees(
    ID         int       not null,
    StoreID    int,
    StoreType  char,
    ..., -- other Employee data
    constraint PK_Employees primary key( ID ),
    constraint CK_Employees_StoreType check( coalesce( StoreType, 'X' ) <> 'O' )), -- Online not allowed
    constraint FK_Employees_TransStores foreign key( StoreID, StoreType )
        references TransactionalStores( ID, StoreType )
);

Dalam tabel ini, referensi FK memaksa StoreType menjadi 'K', 'O' atau 'B' tetapi batasan bidang selanjutnya membatasi hanya pada 'K' atau 'B'.

Sebagai ilustrasi, saya telah menggunakan batasan cek untuk membatasi jenis toko di tabel TransactionStores. Dalam kehidupan nyata, tabel pencarian StoreTypes dengan StoreType menjadi FK ke meja itu mungkin akan menjadi pilihan desain yang lebih baik.

TommCatt
sumber
9

Kunci asing tidak dapat dibuat kondisional sehingga keluar dari pertanyaan. Aturan bisnis tampaknya adalah bahwa seorang karyawan dapat bekerja untuk satu dan hanya satu toko fisik . Karena itu, tipe toko super memiliki dua sub-tipe seperti yang Anda sarankan: Fisik dan Online . Setiap toko fisik dapat dikelola oleh satu atau lebih karyawan, dan setiap karyawan harus ditugaskan ke satu dan hanya satu toko fisik. Toko fisik kemudian memiliki dua sub-tipe, Brick dan Mortar dan Kios . Memiliki tiga sub-tipe langsung - Kios , Online , dan Brick and Mortar- Menyembunyikan properti yang dimiliki oleh setiap toko - apakah itu dapat ditemukan di lokasi fisik atau tidak. Sekarang desainnya bergantung pada manusia untuk memahami semantik yang melekat pada sub-tipe nama untuk memahami bahwa toko online tidak memiliki karyawan. Ini tidak mudah terlihat dalam skema yang dinyatakan dan kode dalam bentuk pemicu harus ditulis untuk menyatakan bahwa pemahaman dengan cara yang dapat diterapkan oleh DBMS. Mengembangkan, menguji, dan mempertahankan pemicu yang tidak memengaruhi kinerja adalah solusi yang jauh lebih sulit untuk diterapkan seperti yang ditunjukkan dalam buku Matematika Terapan untuk Profesional Basis Data .

Sub-typing Store pertama pada jenis lokasi dan kemudian pada jenis struktur toko fisik adalah desain yang lebih benar sehubungan dengan aturan bisnis dan menghilangkan kebutuhan untuk menulis kode untuk menegakkan aturan. Setelah properti jelas dimasukkan sebagai jenis lokasi toko yang dapat digunakan sebagai pembeda untuk sub-jenis, hubungan dapat dibuat antara karyawan dan toko fisik secara langsung dan dengan demikian sepenuhnya menerapkan aturan hanya dengan batasan kunci asing. ere adalah model data yang dibuat dengan Oracle SQL Developer Data Modeler yang menunjukkan super dan sub-mengetik menggunakan Barker-Elliskotak dalam kotak notasi untuk super dan sub-jenis, yang saya lebih suka untuk presentasi yang elegan. Diagram sekarang dapat dengan jelas menunjukkan aturannya juga.

masukkan deskripsi gambar di sini

Todd Everett
sumber