Ich denke nur, dass die Antwort falsch ist, weil der Fremdschlüssel keine uniqueness
Eigenschaft hat.
Aber einige Leute sagten, dass es im Falle eines Selbsteintritts in den Tisch sein kann. Ich bin neu in SQL
. Wenn es wahr ist, erklären Sie bitte wie und warum?
Employee table
| e_id | e_name | e_sala | d_id |
|---- |------- |----- |--------|
| 1 | Tom | 50K | A |
| 2 | Billy | 15K | A |
| 3 | Bucky | 15K | B |
department table
| d_id | d_name |
|---- |------- |
| A | XXX |
| B | YYY |
Jetzt ist d_id ein Fremdschlüssel, also wie es ein Primärschlüssel sein kann. Und etwas darüber erklären join
. Was nützt es?
sql
foreign-keys
primary-key
Eines Mannes
quelle
quelle
Antworten:
Ich finde die Frage etwas verwirrend.
Wenn Sie meinen "Kann sich ein Fremdschlüssel auf einen Primärschlüssel in derselben Tabelle beziehen?", Lautet die Antwort ein festes Ja, wie einige geantwortet haben. Beispielsweise kann in einer Mitarbeitertabelle eine Zeile für einen Mitarbeiter eine Spalte zum Speichern der Mitarbeiternummer des Managers enthalten, in der der Manager auch ein Mitarbeiter ist, und daher eine Zeile in der Tabelle wie eine Zeile eines anderen Mitarbeiters.
Wenn Sie meinen "Kann eine Spalte (oder ein Satz von Spalten) sowohl ein Primärschlüssel als auch ein Fremdschlüssel in derselben Tabelle sein?", Lautet die Antwort meiner Ansicht nach ein Nein. es scheint bedeutungslos. Die folgende Definition ist jedoch in SQL Server erfolgreich!
create table t1(c1 int not null primary key foreign key references t1(c1))
Aber ich denke, es ist sinnlos, eine solche Einschränkung zu haben, wenn nicht jemand ein praktisches Beispiel findet.
AmanS kann in Ihrem Beispiel d_id unter keinen Umständen ein Primärschlüssel in der Employee-Tabelle sein. Eine Tabelle kann nur einen Primärschlüssel haben. Ich hoffe, das klärt Ihren Zweifel. d_id ist / kann nur in der Abteilungstabelle ein Primärschlüssel sein.
quelle
Sicher warum nicht? Angenommen , Sie haben einen habenPerson
Tisch, mitid
,name
,age
, undparent_id
, woparent_id
ein Fremdschlüssel für die gleiche Tabelle. Sie müssten diePerson
Tabelle nicht aufParent
undChild
Tabellen normalisieren , das wäre übertrieben.Person | id | name | age | parent_id | |----|-------|-----|-----------| | 1 | Tom | 50 | null | | 2 | Billy | 15 | 1 |
Etwas wie das.
Ich nehme an, um die Konsistenz aufrechtzuerhalten, müsste es jedoch mindestens 1 Nullwert für gebenparent_id
. Die eine "Alpha-Männchen" -Reihe.EDIT: Wie die Kommentare zeigen, hat Sam einen guten Grund gefunden, dies nicht zu tun. Es scheint, dass in MySQL, wenn Sie versuchen, Änderungen am Primärschlüssel vorzunehmen, die Bearbeitung
CASCADE ON UPDATE
nicht ordnungsgemäß weitergegeben wird , selbst wenn Sie angeben . Obwohl Primärschlüssel (normalerweise) für die Bearbeitung in der Produktion gesperrt sind, ist dies dennoch eine Einschränkung, die nicht ignoriert werden darf. Daher ändere ich meine Antwort auf: - Sie sollten diese Vorgehensweise wahrscheinlich vermeiden, es sei denn, Sie haben eine ziemlich strenge Kontrolle über das Produktionssystem (und können garantieren, dass niemand eine Kontrolle implementiert, die die PKs bearbeitet). Ich habe es nicht außerhalb von MySQL getestet.quelle
update
. Überprüfen Sie sqlfiddle.com/#!9/445052/1/0 und versuchenUpdate menus set id = 6 WHERE id = 1;
Sie dann hinzuzufügen, dass Sie erhalten#1451 - Cannot delete or update a parent row
ON UPDATE CASCADE
wird in der Bearbeitung erwähnt. Ich würde davon abraten,[ON UPDATE CASCADE] [ON DELETE CASCADE]
generell zu verwenden, da die Kaskadenaktion keine Trigger auslöst . Wenn Sie Trigger haben, die bei einer Aktualisierung in Tabelle A ausgelöst werden sollen, und Sie eine Aktualisierung in Tabelle B durchführen, die zu einer kaskadierenden Änderung in A führt, werden Trigger in Tabelle A nicht ausgelöst. Verwenden SieON UPDATE RESTRICT
stattdessen und behandeln Sie das erforderliche Löschen manuell in der Anwendungslogik.Dies kann ein gutes Erklärungsbeispiel sein
CREATE TABLE employees ( id INTEGER NOT NULL PRIMARY KEY, managerId INTEGER REFERENCES employees(id), name VARCHAR(30) NOT NULL ); INSERT INTO employees(id, managerId, name) VALUES(1, NULL, 'John'); INSERT INTO employees(id, managerId, name) VALUES(2, 1, 'Mike');
- Erläuterung: - In diesem Beispiel. - John ist Mikes Manager. Mike verwaltet niemanden. - Mike ist der einzige Mitarbeiter, der niemanden verwaltet.
quelle
Beispiel: n Unterkategorieebene für Kategorien. Die Primärschlüssel- ID der folgenden Tabelle wird durch die Fremdschlüssel- Unterkategorie_ID bezeichnet
quelle
Ein gutes Beispiel für die Verwendung von IDs anderer Zeilen in derselben Tabelle wie Fremdschlüssel sind verschachtelte Listen.
Durch Löschen einer Zeile mit untergeordneten Elementen (dh Zeilen, die sich auf die ID des Elternteils beziehen), die auch untergeordnete Elemente haben (dh auf IDs von untergeordneten Elementen verweisen), wird eine Kaskade von Zeilen gelöscht.
Dies erspart viel Schmerz (und viel Code, was mit Waisen zu tun ist - dh Zeilen, die sich auf nicht vorhandene IDs beziehen).
quelle