Dlaczego tabela miałaby używać swojego klucza podstawowego jako klucza obcego dla siebie


21

Przeglądając bazę danych, natknąłem się na tabelę, która używała swojego klucza podstawowego jako klucza obcego dla siebie.

Widziałem, że tabela może mieć dla siebie klucz obcy, aby zbudować strukturę hierarchiczną, ale użyłaby innej kolumny do odwołania się do klucza podstawowego.

Ponieważ klucz podstawowy jest unikalny, w tej sytuacji wiersz nie byłby w stanie skierować się tylko do siebie? To wydaje się być linkiem tautologicznym, ponieważ jeśli już mam wiersz, to już go mam.

Czy jest jakiś powód, aby to zrobić?

Stół dołączył do siebie

Jestem pewien, że ograniczenie jest zapisane w ten sposób (nie tylko patrząc na diagram), ponieważ ta sama tabela i kolumna są używane dla obu połówek definicji.


6
Prawdopodobnie dzięki użyciu projektanta w ręku jest moja teoria
Martin Smith

Odpowiedzi:


28

Tak jak powiedziałeś. FOREIGN KEYOgraniczenie przedstawieniu tej samej tabeli jest typowo dla struktury hierarchii i byłoby użyć innej kolumny odwołać klucz podstawowy. Dobrym przykładem jest tabela pracowników:

EmployeeId    Int     Primary Key
EmployeeName  String
ManagerId     Int     Foreign key going back to the EmployeeId

Tak więc w tym przypadku klucz obcy pochodzi z tabeli z powrotem do siebie. Wszyscy menedżerowie są również pracownikami, więc tak ManagerIdnaprawdę należy EmployeeIddo kierownika.

Z drugiej strony, jeśli masz na myśli, że ktoś użył tego EmployeeIdklucza obcego do tabeli pracownika, to prawdopodobnie był to błąd . Przeprowadziłem test i jest to możliwe, ale nie przydałoby się to w rzeczywistości.

CREATE TABLE Employee (EmployeeId Int PRIMARY KEY,
                        EmployeeName varchar(50),
                        ManagerId Int);


ALTER TABLE Employee ADD CONSTRAINT fk_employee 
    FOREIGN KEY (EmployeeId) REFERENCES Employee(EmployeeId);

1
W tym przypadku nałożenie ograniczenia na identyfikator menedżera odnoszące się do identyfikatora pracownika może być korzystne, gdyby kierownik został „rozdzielony”. Nie pozwoli na usunięcie wiersza, jeśli zostanie ustawiony w ten sposób. Nie mówię, że zrobiłbym to w ten sposób, ale mogłoby to przynieść pewne korzyści, gdyby twoja aplikacja opierała się na pracownikach posiadających kierowników.
zgr024

6

Właśnie znalazłem taki klucz obcy w moim własnym pliku db i musiałem go sam tworzyć. Myślę, że to się stało przez przypadek. Jeśli kliknę „Nowy klucz obcy” w menu kontekstowym tabeli z kluczem podstawowym (w Management Studio, SQL 2014 Express), to już automatycznie tworzy taki klucz obcy odnoszący się do siebie. Patrz poniżej:

wprowadź opis zdjęcia tutaj

Jeśli wtedy nie zdam sobie sprawy, że powinienem to zmienić, zamiast dodawać nowe, pozostanie tam. Lub, jeśli po prostu kliknę przycisk [Zamknij], co oznacza, że ​​byłoby to jak [Anuluj], klucz obcy nadal byłby tworzony po zapisaniu definicji tabeli.

Dla mnie taki klucz obcy nie ma sensu i można go usunąć.


Możliwe, że chciałeś utworzyć FK i podczas procesu zdajesz sobie sprawę, że drugi stół nie ustawił jeszcze swojego PK, więc anulujesz, przejdź do drugiego stołu, a następnie z jakiegoś powodu zapominasz kontynuować proces FK. Tam masz swój rekurencyjny FK.
Andrew

4

Być może projektant chciał wyłączyć korzystanie z TRUNCATE TABLE?

TRUNCATE TABLEnie można go używać w tabeli z ograniczeniem klucza obcego do innej tabeli, chociaż można go użyć, jeśli istnieją klucze referencyjne obce. Z dokumentacji TRUNCATE TABLE (Transact-SQL) :

Ekstrakt BOL

DELETEOświadczenie bez WHEREklauzuli ma podobny wpływ na A TRUNCATE TABLE(usuwanie wszystkich wierszy w tabeli), ale DELETEtwierdzenie pożary Usuwanie wyzwalaczy, co może być powodem, aby umożliwić DELETEale nie TRUNCATE TABLE.

Zrobiłbym to przy użyciu uprawnień ( DELETEwymaga uprawnień do usuwania, TRUNCATE TABLEwymaga uprawnień do zmiany tabeli), ale może istnieje jakiś powód, dla którego projektant nie mógł tego zrobić?

Uwaga: Chociaż to, co zrobił projektant, tak naprawdę nie wyłącza korzystania TRUNCATE TABLE, nadal spekuluję, że taki był ich zamiar.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.