446 Stimmen

Kann ein Fremdschlüssel NULL und/oder ein Duplikat sein?

Bitte klären Sie zwei Dinge für mich:

  1. Kann ein Fremdschlüssel NULL sein?
  2. Kann ein Fremdschlüssel dupliziert werden?

So fair wie ich weiß, NULL sollte nicht in Fremdschlüsseln verwendet werden, aber in einer Anwendung von mir kann ich Folgendes eingeben NULL sowohl in Oracle als auch in SQL Server, und ich weiß nicht, warum.

4voto

Mouhcine Punkte 276

Hier ist ein Beispiel mit Oracle-Syntax:
Erstellen wir zunächst eine Tabelle COUNTRY

CREATE TABLE TBL_COUNTRY ( COUNTRY_ID VARCHAR2 (50) NOT NULL ) ;
ALTER TABLE TBL_COUNTRY ADD CONSTRAINT COUNTRY_PK PRIMARY KEY ( COUNTRY_ID ) ;

Erstellen Sie die Tabelle PROVINCE

CREATE TABLE TBL_PROVINCE(
PROVINCE_ID VARCHAR2 (50) NOT NULL ,
COUNTRY_ID  VARCHAR2 (50)
);
ALTER TABLE TBL_PROVINCE ADD CONSTRAINT PROVINCE_PK PRIMARY KEY ( PROVINCE_ID ) ;
ALTER TABLE TBL_PROVINCE ADD CONSTRAINT PROVINCE_COUNTRY_FK FOREIGN KEY ( COUNTRY_ID ) REFERENCES TBL_COUNTRY ( COUNTRY_ID ) ;

Das funktioniert in Oracle einwandfrei. Beachten Sie, dass der Fremdschlüssel COUNTRY_ID in der zweiten Tabelle nicht "NOT NULL" hat.

Um nun eine Zeile in die Tabelle PROVINCE einzufügen, genügt es, nur die PROVINCE_ID anzugeben. Wenn Sie jedoch auch eine COUNTRY_ID angeben möchten, muss diese bereits in der Tabelle COUNTRY vorhanden sein.

2voto

nitin lalwani Punkte 21

Standardmäßig gibt es keine Einschränkungen für den Fremdschlüssel, der Fremdschlüssel kann ungültig und dupliziert sein.

beim Erstellen einer Tabelle / Ändern der Tabelle, wenn Sie eine Einschränkung der Eindeutigkeit oder nicht null dann nur es wird nicht zulassen, die null / doppelte Werte hinzufügen.

1voto

Fakhar Punkte 11

Einfach ausgedrückt: "Nicht identifizierende" Beziehungen zwischen Entitäten sind Teil des ER-Modells und stehen in Microsoft Visio beim Entwurf von ER-Diagrammen zur Verfügung. Dies ist erforderlich, um die Kardinalität zwischen Entitäten des Typs "null oder mehr als null" oder "null oder eins" durchzusetzen. Beachten Sie diese "Null" in der Kardinalität anstelle von "eins" in "eins zu vielen".

Ein Beispiel für eine nicht-identifizierende Beziehung, bei der die Kardinalität "Null" (nicht-identifizierend) sein kann, ist, wenn wir sagen, dass ein Datensatz/Objekt in einer Entität-A einen Wert als Verweis auf den/die Datensatz/e in einer anderen Entität-B haben "kann" oder "darf nicht".

Da die Möglichkeit besteht, dass sich ein Datensatz der Entität A mit den Datensätzen der anderen Entität B identifiziert, sollte in Entität B eine Spalte mit dem Identitätswert des Datensatzes der Entität B vorhanden sein. Diese Spalte kann "Null" sein, wenn kein Datensatz in Entität-A den Datensatz/die Datensätze (oder das Objekt/die Objekte) in Entität-B identifiziert.

Im objektorientierten (realen) Paradigma gibt es Situationen, in denen ein Objekt der Klasse B nicht notwendigerweise von einem Objekt der Klasse A abhängt (stark gekoppelt), was bedeutet, dass die Klasse B lose mit der Klasse A gekoppelt ist, so dass die Klasse A ein Objekt der Klasse A "enthalten" kann (Containment), im Gegensatz zu dem Konzept, dass ein Objekt der Klasse B ein Objekt der Klasse A haben muss (Composition), um es zu erstellen (Objekt der Klasse B).

Aus Sicht der SQL-Abfrage können Sie alle Datensätze in Entität-B abfragen, die für den für Entität-B reservierten Fremdschlüssel "nicht null" sind. Dadurch werden alle Datensätze mit einem bestimmten entsprechenden Wert für Zeilen in Entität-A abgefragt. Alternativ dazu werden alle Datensätze mit dem Wert "null" die Datensätze sein, die keinen Datensatz in Entität-A in Entität-B haben.

1voto

Lukasz Szozda Punkte 137580

Kann ein Fremdschlüssel NULL sein?

Die bisherigen Antworten konzentrierten sich auf ein einspaltiges Szenario. Wenn wir einen mehrspaltigen Fremdschlüssel betrachten, haben wir mehr Möglichkeiten, indem wir MATCH [SIMPLE | PARTIAL | FULL] Klausel, die im SQL-Standard definiert ist:

PostgreSQL-CREATE TABLE

Ein in die referenzierende(n) Spalte(n) eingefügter Wert wird mit den Werten der referenzierten Tabelle und der referenzierten Spalten unter Verwendung des angegebenen Übereinstimmungstyps abgeglichen. Es gibt drei Abgleichsarten: MATCH FULL, MATCH PARTIAL und MATCH SIMPLE (dies ist die Standardeinstellung). MATCH FULL lässt nicht zu, dass eine Spalte eines mehrspaltigen Fremdschlüssels Null ist, es sei denn, alle Fremdschlüsselspalten sind Null; wenn sie alle Null sind, muss die Zeile keine Übereinstimmung in der referenzierten Tabelle haben. MATCH SIMPLE lässt zu, dass eine der Fremdschlüsselspalten Null ist; wenn eine von ihnen Null ist, muss die Zeile keine Übereinstimmung in der referenzierten Tabelle haben. TEILWEISE ÜBEREINSTIMMEN ist noch nicht implementiert.

(Natürlich können NOT NULL-Beschränkungen auf die referenzierende(n) Spalte(n) angewendet werden, um diese Fälle zu vermeiden).

Beispiel:

CREATE TABLE A(a VARCHAR(10), b VARCHAR(10), d DATE , UNIQUE(a,b));
INSERT INTO A(a, b, d) 
VALUES (NULL, NULL, NOW()),('a', NULL, NOW()),(NULL, 'b', NOW()),('c', 'b', NOW());

CREATE TABLE B(id INT PRIMARY KEY, ref_a VARCHAR(10), ref_b VARCHAR(10));

-- MATCH SIMPLE - default behaviour nulls are allowed
ALTER TABLE B ADD CONSTRAINT B_Fk FOREIGN KEY (ref_a, ref_b) 
REFERENCES A(a,b) MATCH SIMPLE;

INSERT INTO B(id, ref_a, ref_b) VALUES (1, NULL, 'b');  

-- (NULL/'x') 'x' value does not exists in A table, but insert is valid
INSERT INTO B(id, ref_a, ref_b) VALUES (2, NULL, 'x');  

ALTER TABLE B DROP CONSTRAINT IF EXISTS B_Fk; -- cleanup

-- MATCH PARTIAL - not implemented
ALTER TABLE B ADD CONSTRAINT B_Fk FOREIGN KEY (ref_a, ref_b) 
REFERENCES A(a,b) MATCH PARTIAL;
-- ERROR:  MATCH PARTIAL not yet implemented

DELETE FROM B; ALTER TABLE B DROP CONSTRAINT IF EXISTS B_Fk; -- cleanup

-- MATCH FULL nulls are not allowed
ALTER TABLE B ADD CONSTRAINT B_Fk FOREIGN KEY (ref_a, ref_b) 
REFERENCES A(a,b) MATCH FULL;

-- FK is defined, inserting NULL as part of FK
INSERT INTO B(id, ref_a, ref_b) VALUES (1, NULL, 'b');
-- ERROR:  MATCH FULL does not allow mixing of null and nonnull key values.

-- FK is defined, inserting all NULLs - valid
INSERT INTO B(id, ref_a, ref_b) VALUES (1, NULL, NULL);

db<>fiddle demo

-1voto

user9274383 Punkte 1

Ich denke, es ist besser, die mögliche Kardinalität zu berücksichtigen, die wir in den Tabellen haben. Wir können eine Mindestkardinalität von Null haben. Wenn es optional ist, könnte die Mindestbeteiligung von Tupeln aus der Bezugstabelle Null sein, Jetzt stehen Sie vor der Notwendigkeit von Fremdschlüsselwerten, die Null sein dürfen.

Aber die Antwort ist, dass es auf das Geschäft ankommt.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X