UNIQUE-Index und NULL

UNIQUE und NULL ist anscheinend ein altbekanntes Thema in der SQL-Welt, welches ich erst jetzt nach zuvor Oracle erlebe,
die Fronten sind wohl geklärt, aber vielleicht hat noch wer was anzumerken oder lernt es jetzt erst auch kennen

für einzelne Spalten interessiert mich das Thema nicht besonders,
wenn eine Spalte UNIQUE ist, dann bei mir zumindest auch gleich NOT NULL dazu,

obwohl (mehrere?) NULL darin zu erlauben während alles andere UNIQUE sein muss sicherlich als Thema allgemein nicht zu ignorieren ist


mein Problem ist UNIQUE-Index auf mehrere Spalten A, B, C, für die jeweils NULL erlaubt ist

einen Eintrag <‘a1’,null, null> darf ich in Postgres mehrfach eintragen, Peng, wie kann das sein?
Links habe ich gefunden a la
http://ocelot.ca/blog/blog/2013/09/11/null-and-unique/
aber ist dieses Verhalten hilfreich?

NULL ist ja für sich schon Problem genug, Sonder-Vergleichssyntax, schlimmer als in Java == vs equals, möchte ich meinen,
interessant ist der Punkt auch im Link NULLs sort together for purposes of GROUP BY, ORDER BY, or duplicate elimination.
->
[sql]select A, B, C from X group by A, B, C having count(*) > 1[/sql]
liefert Ergebnisse, trotz eingeschalter UNIQUE-Bedingung für diese drei Spalten…,
finde ich nicht in Ordnung :wink:

Oracle hatte ich bisher lange Jahre, da war es anders,
anscheinend mit dem frechen, aber effektiven Weg, alle NULL-Werte zu ignorieren,
https://community.oracle.com/thread/376915
dass <null,null, null> dann immer noch mehrfach eingefügt werden könnte ist nicht ganz ideal, aber könnte ich verkraften,
ein solcher Sondereintrag fällt auch so auf, wenigstens <‘a1’,null, null> nur 1x erlaubt, Hauptziel erreicht


viele (Text-)Spalten bei mir könnte ich auf NON NULL und Leerstring oder sonstige Dummy-Werte umstellen,
eh schon in Überlegung teilweise, ich habe z.B. Probleme mit Daten aus GUI-Textfeldern oder CSV -> Leerstring vs. anders erstellte Daten -> null,

aber quasi den Baustein NULL aus der Werkzeugkasten zu entfernen finde ich gar nicht gut,
obwohl ja in manchen Sprachen/ Programmierphilosophieren allgemein ein Thema,
aber noch gibt es NULL in SQL, warum dann Umgang damit so schwer machen?

mit normalen Problem WHERE A is null kann ich noch leben,
es funktioniert die Gruppierung,
Sortierung ist auch zumindest so gnädig, alle null nicht beliebig einzusortieren,
aber dieses Verhalten mit UNIQUE hier, ist das irgendwo als nützlich anzusehen?

besonderes Augenmerk habe ich noch auf Constraint-geschützte Fremdschlüssel-Spalten,
ich möchte und habe auch Einträge, die nicht auf etwas anderes verweisen,

falsche Fremdschlüssel-Id ist nicht erlaubt, einen Dummy-Eintrag in anderer Tabelle einzufügen wäre Wahnsinn (in NULL-freier Programmierung ähnlich),
was soll ich eintragen?

NULL erlauben und ein Index mit COALESCE( XY_ID, 0 ) bzw. NVL( XY_ID, 0 ) ist wohl die Lösung, überall zu lesen,
kein schöner Zustand, werde ich jetzt wohl als Standard-Syntax in allen derartigen UNIQUE Indexen bedenken müssen…

geht es doch besser oder sonstige schlaue Anmerkungen?

Dazu kommt bei Oracle noch, dass der leere String im alten Oracle das gleiche war/ist wie NULL…Yeah

Aber zum Thema:

*Bei der Definition mach ich UNIQUE eigentlich nur in Kombination NOT NULL - das Theater mit genau einer NULL oder mehreren NULLEN spar ich mir

*Wenn irgendwie möglich sind Spalten bei mir NOT NULL DEFAULT xyz => eben wegen des leidigen Kladerraddatsch Sortieren, Aggregieren, Vergleichen, …

Das geht natürlich nicht immer, weil NULL ja manchmal eine Bedeutung hat. Der Shit ist dann, dass man bei komplexen Abfragen manchmal Zeilen mit einer NULL verliert, weil man keine Ahnung hat, wie die diversen Funktionen/Operationen des gerade gewählten SQL-Dialekts die NULL-Values verwursten: also hängt bei mir oft hinten an der WHERE Klausel ein OR col1 IS NULL OR col2 IS NULL usw. dran

Ist ein ewiges Gewürge, für das es vermutlich keine Lösung gibt.

Auch wenn es nur halb zum Thema passt: Beim Durchlesen von “SQL Performance Explained” bin ich auch schon über das Thema gestolpert:

Vielleicht ist es ja interessant (Ich war auf jeden Fall froh, vor meinem ersten Oracle Kontakt von diesem Verhalten zu wissen, hat ein paar Überraschungen gespart)

Das NULL in SQL ist wahrscheinlich besser mit NaN als mit null in Java zu vergleichen. Das ergibt bei Vergleichen auch immer false. NULL heißt einfach unbekannt/ungültig. Würde man die als gleich betrachten, wäre das wahrscheinlich wie bei Javas Generics auf einmal alle Wildcards als gleich anzusehen: falsch. Dadurch ergibt sich natürlich auch die Situation beim UNIQUE.

Ansonsten natürlich das übliche: SQL baut stärker als übliche Programmiersprachen auf ein rigoroses mathematisches Modell auf. Dadurch erscheint eben nicht alles immer intuitiv.

Erklärungen gibt es gewiss genug, aber in irgendeiner Weise vorteilhaft ist das doch nicht, oder inwiefern?

warum funktioniert GROUP BY, aber nicht UNIQUE-Index? sollte symmetrisch sein,

was im Fremdschlüssel-Fall machen? es braucht einen Wert wie null für Leerlassen und man sollte damit auf was machen können,
is null ist eine Alibi-Möglichkeit dann doch zu prüfen,
was spricht dagegen den Normalfall = null und Vergleiche von Einträgen funktionieren zu lassen?
ohne Not und Vorteil Schwierigkeiten eingebaut


der Bogen von einen Wert auf Generic-Wildcards ist etwas zu groß für mich :wink:
null verschiedener Datentypen als unterschiedlich anzusehen wäre ja noch nichmal groß ein Problem,
wichtig ist innerhalb eines Datentyps, gar innerhalb nur derselben Spalte derselben Tabelle, vielleicht gejoint doppelt

NaN ist was anderes als null, ja,
aber deswegen ist null auch ca. 500 Mio. Mal häufiger im Gebrauch als NaN, weil halbwegs praktikabel

es wäre günstiger in SQL etwas brauchbares wie null zu unterstützen als NaN…

Der Wikipedia-Eintrag ist ziemlich informativ: http://en.wikipedia.org/wiki/Null_(SQL)

Wundere mich gerade, wie oft ich schon mit
[SQL]
SELECT *
FROM sometable
WHERE num <> 1;
[/SQL]
falsche Ergebnisse produziert habe ohne es zu merken…