Relacyjne bazy danych nie są budowane, aby doskonale poradzić sobie z tą sytuacją. Musisz zdecydować, co jest dla Ciebie najważniejsze, a następnie dokonać kompromisu. Masz kilka celów:
- Zachowaj trzecią normalną formę
- Zachowaj integralność referencyjną
- Zachowaj ograniczenie, że każde konto należy do korporacji lub osoby fizycznej.
- Zachowaj możliwość łatwego i bezpośredniego pobierania danych
Problem polega na tym, że niektóre z tych celów konkurują ze sobą.
Rozwiązanie do podtypowania
Możesz wybrać rozwiązanie do podtytułu, w którym tworzysz supertyp, który obejmuje zarówno korporacje, jak i osoby. Ten nadtyp prawdopodobnie miałby klucz złożony z klucza naturalnego podtypu plus atrybut partycjonowania (np customer_type.). Jest to w porządku, o ile chodzi o normalizację, i pozwala egzekwować integralność referencyjną, a także ograniczenie wzajemnego wykluczania się korporacji i osób. Problem polega na tym, że utrudnia to pobieranie danych, ponieważ zawsze musisz rozgałęzić się na podstawie customer_typemomentu dołączenia konta do właściciela konta. Prawdopodobnie oznacza to używanie UNIONi powtarzanie zapytania w zapytaniu.
Rozwiązanie z
dwoma kluczami obcymi Możesz wybrać rozwiązanie, w którym przechowujesz dwa klucze obce w tabeli rachunków, jeden dla korporacji i jeden dla osoby. To rozwiązanie pozwala również zachować integralność referencyjną, normalizację i wzajemną wyłączność. Ma również tę samą wadę pobierania danych, co rozwiązanie do podtypów. W rzeczywistości to rozwiązanie jest podobne do podtytułu, z tą różnicą, że masz problem z rozgałęzieniem logiki łączenia „wcześniej”.
Niemniej jednak wielu modelarzy danych uznałoby to rozwiązanie za gorsze od rozwiązania podtypów z uwagi na sposób egzekwowania ograniczenia wzajemnej wyłączności. W rozwiązaniu do podtypowania tekstu używasz kluczy do egzekwowania wzajemnej wyłączności. W dwóch rozwiązaniach z kluczem obcym używasz CHECKograniczenia. Znam niektórych ludzi, którzy mają nieuzasadnione uprzedzenia wobec ograniczeń czekowych. Ci ludzie wolą rozwiązanie, które utrzymuje ograniczenia w kluczach.
Rozwiązanie „zdenormalizowanego” atrybutu partycjonowania
Istnieje jeszcze jedna opcja, w której trzymasz jedną kolumnę klucza obcego w tabeli kont sprawdzających i używasz innej kolumny, aby powiedzieć ci, jak interpretować kolumnę klucza obcego (RoKa'sOwnerTypeIDkolumna). To zasadniczo eliminuje tabelę supertypu w rozwiązaniu podtypowania przez denormalizowanie atrybutu partycjonowania do tabeli potomnej. (Należy zauważyć, że zgodnie z formalną definicją nie jest to ściśle „denormalizacja”, ponieważ atrybut partycjonowania jest częścią klucza podstawowego.) To rozwiązanie wydaje się dość proste, ponieważ unika się konieczności posiadania dodatkowej tabeli w celu wykonania mniej więcej tej samej rzeczy i to zmniejsza liczbę kolumn klucza obcego do jednego. Problem z tym rozwiązaniem polega na tym, że nie unika rozgałęzienia logiki pobierania, a ponadto nie pozwala zachować deklaratywnej integralności referencyjnej. Bazy danych SQL nie mają możliwości zarządzania jedną kolumną klucza obcego dla jednej z wielu tabel nadrzędnych.
Wspólne rozwiązanie domeny klucza podstawowego
Jednym ze sposobów, w jaki ludzie czasami radzą sobie z tym problemem, jest użycie pojedynczej puli identyfikatorów, aby nie było pomyłki dla dowolnego identyfikatora, niezależnie od tego, czy należy on do jednego podtypu, czy innego. Prawdopodobnie działałoby to całkiem naturalnie w scenariuszu bankowym, ponieważ nie zamierzasz wydawać tego samego numeru konta bankowego zarówno korporacji, jak i osobie fizycznej. Ma to tę zaletę, że pozwala uniknąć potrzeby atrybutu partycjonowania. Możesz to zrobić z tabelą supertypu lub bez niej. Korzystanie z tabeli typu super pozwala na stosowanie ograniczeń deklaratywnych w celu wymuszenia unikatowości. W przeciwnym razie musiałoby to być egzekwowane proceduralnie. To rozwiązanie jest znormalizowane, ale nie pozwoli ci zachować deklaratywnej integralności referencyjnej, chyba że utrzymasz tabelę supertypu. Nadal nic nie robi, aby uniknąć złożonej logiki pobierania.
Widać zatem, że tak naprawdę nie jest możliwe stworzenie przejrzystego projektu zgodnego ze wszystkimi zasadami, a jednocześnie prostego pobierania danych. Musisz zdecydować, gdzie będą twoje kompromisy.
OwnerTypeIDPrzyChecquingAccountstole z,1=Corporationi2=NaturalPerson? W ten sposób potrzebujesz tylko jednegoOwnerIDwChecquingAccounttabeli, który możesz indeksować wraz zOwnerTypeID.