PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Was tun mit Nullwerten beim Modellieren und Normalisieren?

SQL behandelt NULL speziell gemäß seiner Version von 3VL (3-wertige Logik). Normalisierung und andere relationale Theorien nicht. Wir können jedoch SQL-Designs in relationale Designs und zurück übersetzen. (Nehmen Sie hier keine doppelten Zeilen an.)

Normalisierung geschieht mit Beziehungen und ist in Bezug auf Operatoren definiert, die NULL nicht speziell behandeln. Der Begriff „Normalisierung“ hat am häufigsten zwei unterschiedliche Bedeutungen:eine Tabelle in „1NF“ und in „höhere NFs (Normalformen)“ einfügen. NULL wirkt sich nicht auf die "Normalisierung auf 1NF" aus. "Normalisierung auf höhere NFs" ersetzt eine Tabelle durch kleinere Tabellen, die sich natürlich wieder daran anschließen. Zu Zwecken der Normalisierung könnten Sie NULL wie einen Wert behandeln, der in der Domäne einer Nullable-Spalte zusätzlich zu den Werten ihres SQL-Typs zulässig ist. Wenn unsere SQL-Tabellen keine NULL-Werte haben, können wir sie als Beziehungen und SQL-Join usw. als Join usw. interpretieren. Wenn Sie jedoch zerlegen, wo eine Nullable-Spalte von Komponenten gemeinsam genutzt wurde, müssen Sie feststellen, dass Sie zum Rekonstruieren des Originals in SQL einen SQL-Join durchführen müssen gleichnamige Spalten sind gleich oder beide NULL . Und Sie werden solche CKs (Kandidatenschlüssel) nicht in einer SQL-Datenbank haben wollen. Sie können es zB nicht als SQL PK (Primärschlüssel) deklarieren, weil das UNIQUE NOT NULL bedeutet. Beispielsweise erlaubt eine UNIQUE-Beschränkung, die eine Nullable-Spalte betrifft, mehrere Zeilen, die eine NULL in dieser Spalte haben, selbst wenn die Zeilen in jeder Spalte dieselben Werte haben. ZB NULLen in SQL-FKs bewirken, dass sie erfüllt werden (auf verschiedene Weise pro MATCH-Modus), nicht scheitern, weil sie nicht in der referenzierten Tabelle erscheinen. (Aber DBMSs unterscheiden sich eigenwillig von Standard-SQL.)

Leider kann die Dekomposition zu einer Tabelle mit all führen CKs, die NULL enthalten, sodass wir nichts als SQL PK oder UNIQUE NOT NULL deklarieren müssen. Die einzig sichere Lösung ist die Konvertierung in ein NULL-freies Design. Nach der anschließenden Normalisierung möchten wir vielleicht wieder etwas Null-Zulässigkeit in die Komponenten einführen.

In der Praxis schaffen wir es, Tabellen so zu entwerfen, dass es immer eine Reihe von NULL-freien Spalten gibt, die wir als CK deklarieren können, über SQL PK oder UNIQUE NOT NULL. Dann können wir eine Nullable-Spalte loswerden, indem wir sie aus der Tabelle löschen und eine Tabelle mit dieser Spalte und den Spalten eines NULL-freien CK hinzufügen:Wenn die Spalte für eine Zeile im alten Design nicht NULL ist, dann eine Zeile mit seine CK-Unterzeile und sein Spaltenwert gehen in die hinzugefügte Tabelle; andernfalls ist es im alten Design NULL und es gibt keine entsprechende Zeile in der hinzugefügten Tabelle. (Die ursprüngliche Tabelle ist ein natürlicher linker Join der neuen.) Natürlich müssen wir auch Abfragen vom alten Design auf das neue Design umstellen.

Wir können NULLen immer über ein Design vermeiden, das eine boolesche Spalte für jede alte Nullable-Spalte hinzufügt und die alte Spalte NOT NULL enthält. Die neue Spalte sagt für eine Zeile, ob die alte Spalte im alten Design NULL war, und wenn wahr, hat die alte Spalte einen Wert, den wir zu diesem Zweck für diesen Typ in der gesamten Datenbank auswählen. Natürlich müssen wir auch Abfragen vom alten Design auf das neue Design umstellen.

Ob Sie NULL vermeiden wollen, ist eine andere Frage. Ihre Datenbank kann für Ihre Anwendung mit beiden Designs in irgendeiner Weise "besser" oder "schlechter" sein. Die Idee hinter dem Vermeiden von NULL ist, dass es die Bedeutung von Abfragen verkompliziert und somit das Abfragen auf perverse Weise verkompliziert, verglichen mit der Komplikation von mehr Joins aus mehr NULL-freien Tabellen. (Diese Perversität wird normalerweise dadurch gehandhabt, dass NULLs in Abfrageausdrücken so nah wie möglich an der Stelle entfernt werden, an der sie erscheinen.)

PS Viele SQL-Begriffe einschließlich PK &FK unterscheiden sich von den relationalen Begriffen. SQL PK bedeutet eher so etwas wie Superkey; SQL FK bedeutet eher so etwas wie fremder Superschlüssel; aber es macht nicht einmal Sinn, in SQL von einem "Superkey" zu sprechen:

Aufgrund der Ähnlichkeit von SQL-Tabellen mit Relationen werden Begriffe, die Relationen beinhalten, nachlässig auf Tabellen angewendet. Aber obwohl Sie Begriffe ausleihen und ihnen SQL-Bedeutungen geben können – Wert, Tabelle, FD (funktionale Abhängigkeit), Superschlüssel, CK (Kandidatenschlüssel), PK (Primärschlüssel), FK (Fremdschlüssel), Join und, Prädikat, NF (Normalform), normalisieren, 1NF usw. - Sie können diese SQL-Bedeutungen nicht einfach durch diese Wörter in RM-Definitionen, Theoremen oder Algorithmen ersetzen und etwas Vernünftiges oder Wahres erhalten. Außerdem SQL-Darstellungen von RM-Begriffen fast nie Ihnen tatsächlich sagen, wie man RM-Begriffe vernünftig auf eine SQL-Datenbank anwendet . Sie plappern nur RM-Präsentationen nach, ohne zu wissen, ob ihre Verwendung von SQL-Bedeutungen für Begriffe die Dinge unsinnig oder ungültig macht.