Warunkowe relacje z kluczem obcym

14

Obecnie mam klucz obcy między dwiema jednostkami i chciałbym uzależnić tę relację od typu podmiotu jednej z tabel. Oto hierarchia tabel, odbywa się to poprzez refrencje FK od dziecka do rodzica

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

Obecnie mam relację FK od pracownika do sklepu

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

Chciałbym dodać warunek:

WHERE TransactionalStores.storeType != 'ONLINE_TYPE'

Czy jest to możliwe, czy muszę podklasować TransactionalStores w dwa nowe podtypy (np. PhysicalStores i VirtualStores)

As
źródło

Odpowiedzi:

18

Klucze obce można uzależnić ... w pewnym sensie. Nie pokazujesz układu każdej tabeli, więc oto typowy projekt pokazujący twoje relacje:

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 i BrickMorters miałyby tę samą podstawową strukturę, ale z StoreType ograniczonym tylko do „O” lub „B”, stosownie do przypadku.

Teraz chcesz mieć odniesienie z innej tabeli do TransactionalStores (i poprzez nią do różnych tabel sklepu), ale ograniczone do Kiosków i BrickMorter. Jedyną różnicą byłoby ograniczenie:

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 )
);

W tej tabeli referencja FK wymusza StoreType na „K”, „O” lub „B”, ale ograniczenie pola dodatkowo ogranicza ją tylko do „K” lub „B”.

Dla ilustracji użyłem ograniczenia sprawdzającego, aby ograniczyć typy sklepów w tabeli TransactionStores. W rzeczywistości tabela wyszukiwania StoreTypes z StoreType będącym FK dla tej tabeli prawdopodobnie byłby lepszym wyborem projektowym.

TommCatt
źródło
9

Klucz obcy nie może być warunkowy, więc nie ma o tym mowy. Reguła biznesowa wydaje się, że pracownik może pracować dla jednego i tylko jednego sklepu fizycznego . Biorąc to pod uwagę, super typ sklepu ma dwa podtypy, jak sugerowałeś: fizyczny i online . W każdym sklepie fizycznym może znajdować się jeden lub więcej pracowników, a każdy pracownik musi być przypisany do jednego i tylko jednego sklepu fizycznego. Sklepy fizyczne mają następnie dwa podtypy: Cegła i zaprawa oraz Kiosk . Posiadający trzy bezpośrednie podtypy - Kiosk , Online oraz Brick and Mortar- ukrywa własność posiadaną przez każdy sklep - niezależnie od tego, czy można ją znaleźć w fizycznej lokalizacji. Teraz projekt opiera się na człowieku, który rozumie semantykę związaną z nazwami podtypów, aby zrozumieć, że sklepy internetowe nie mają pracowników. Nie jest to łatwo widoczne w zadeklarowanym schemacie, a kod w postaci wyzwalacza musi zostać napisany, aby wyrazić to zrozumienie w sposób, który DBMS może wymusić. Opracowywanie, testowanie i utrzymywanie wyzwalacza, który nie wpływa na wydajność, jest znacznie trudniejszym rozwiązaniem do wdrożenia, jak pokazano w książce Applied Mathematics for Database Professionals .

Podtypowanie sklepu Najpierw według rodzaju lokalizacji, a następnie struktury sklepu fizycznego jest bardziej poprawnym projektem w odniesieniu do reguł biznesowych i eliminuje potrzebę pisania kodu w celu egzekwowania reguły. Gdy właściwość zostanie wyraźnie uwzględniona jako typ lokalizacji sklepu, który może być używany jako dyskryminator dla podtypów, można bezpośrednio nawiązać relację między pracownikami a fizycznymi sklepami, a tym samym w pełni wdrożyć regułę tylko z ograniczeniem klucza obcego. ere to model danych utworzony za pomocą Oracle SQL Developer Data Modeler, który pokazuje superpodpisywanie za pomocą Barker-Ellisnotacja box in box dla super i podtypów, które preferuję ze względu na elegancką prezentację. Schemat może teraz również wyraźnie przedstawiać regułę.

wprowadź opis zdjęcia tutaj

Todd Everett
źródło