sql >> Databasteknik >  >> RDS >> PostgreSQL

Vad ska man göra med nollvärden vid modellering och normalisering?

SQL behandlar NULL speciellt enligt dess version av 3VL (3-värdig logik). Normalisering &annan relationsteori gör det inte. Däremot kan vi översätta SQL-designer till relationsdesigner och tillbaka. (Anta inga dubbletter av rader här.)

Normalisering sker med relationer och definieras i termer av operatörer som inte behandlar NULL speciellt. Termen "normalisering" har två vanligaste distinkta betydelser:att sätta en tabell i "1NF" och i "högre NFs (normala former)". NULL påverkar inte "normalisering till 1NF". "Normalisering till högre NFs" ersätter en tabell med mindre tabeller som naturligt går tillbaka till den. I normaliseringssyfte kan du behandla NULL som ett värde som är tillåtet i domänen för en nullbar kolumn förutom värdena för dess SQL-typ. Om våra SQL-tabeller inte har några NULLs kan vi tolka dem som relationer &SQL join etc som join, etc. Men om du bryter ner där en nullbar kolumn delades mellan komponenter, inse att för att rekonstruera originalet i SQL måste du SQL join på kolumner med samma namn är lika med eller båda NULL . Och du vill inte ha sådana CK:er (kandidatnycklar) i en SQL-databas. Du kan t.ex. inte deklarera det som en SQL PK (primärnyckel) eftersom det betyder UNIK INTE NULL. T.ex. en UNIK begränsning som involverar en nullbar kolumn tillåter flera rader som har en NULL i den kolumnen, även om raderna har samma värden i varje kolumn. T.ex. NULL i SQL FK gör att de blir tillfredsställda (på olika sätt per MATCH-läge), inte misslyckas från att inte visas i den refererade tabellen. (Men DBMS skiljer sig idiosynkratiskt från standard SQL.)

Tyvärr kan nedbrytning leda till en tabell med alla CKs som innehåller NULL, så att vi inte har något att deklarera som SQL PK eller UNIQUE NOT NULL. Den enda säkra lösningen är att konvertera till en NULL-fri design. Efter att sedan normaliserats kanske vi vill återinföra en viss nollbarhet i komponenterna.

I praktiken lyckas vi designa tabeller så att det alltid finns en uppsättning NULL-fria kolumner som vi kan deklarera som CK, via SQL PK eller UNIQUE NOT NULL. Sedan kan vi bli av med en nollbar kolumn genom att släppa den från tabellen och lägga till en tabell med den kolumnen och kolumnerna i någon NULL-fri CK:Om kolumnen är icke-NULL för en rad i den gamla designen, då en rad med dess CK-underrads- och kolumnvärde går i den tillagda tabellen; annars är den NULL i den gamla designen och ingen motsvarande rad finns i den tillagda tabellen. (Den ursprungliga tabellen är en naturlig vänster sammanfogning av de nya.) Naturligtvis måste vi också ändra frågor från den gamla designen till den nya designen.

Vi kan alltid undvika NULLs via en design som lägger till en boolesk kolumn för varje gammal nullbar kolumn och har den gamla kolumnen NOT NULL. Den nya kolumnen säger för en rad om den gamla kolumnen var NULL i den gamla designen och när den är sann har den gamla kolumnen ett värde som vi väljer för det ändamålet för den typen i hela databasen. Naturligtvis måste vi också ändra frågor från den gamla designen till den nya designen.

Om du vill undvika NULL är en separat fråga. Din databas kan på något sätt vara "bättre" eller "sämre" för din applikation med endera designen. Tanken bakom att undvika NULL är att det komplicerar betydelsen av frågor, och därför komplicerar sökningar, på ett perverst sätt, jämfört med komplikationen av fler kopplingar från mer NULL-fria tabeller. (Denna perversitet hanteras vanligtvis genom att ta bort NULLs i frågeuttryck så nära där de visas som möjligt.)

PS Många SQL-termer inklusive PK &FK skiljer sig från relationstermerna. SQL PK betyder något mer som supernyckel; SQL FK betyder något mer som främmande supernyckel; men det är inte ens vettigt att prata om en "supernyckel" i SQL:

På grund av likheten mellan SQL-tabeller och relationer, tillämpas termer som involverar relationer slarvigt på tabeller. Men även om du kan låna termer och ge dem SQL-betydelser - värde, tabell, FD (funktionellt beroende), supernyckel, CK (kandidatnyckel), PK (primärnyckel), FK (främmande nyckel), join och, predikat, NF (normal form), normalisera, 1NF, etc - du kan inte bara ersätta dessa SQL-betydelser för dessa ord i RM-definitioner, satser eller algoritmer och få något vettigt eller sant. Dessutom SQL-presentationer av RM-begrepp nästan aldrig faktiskt berätta hur man på ett korrekt sätt tillämpar RM-begrepp på en SQL-databas . De papegojar bara RM-presentationer, omedvetna om huruvida deras användning av SQL-betydelser för termer gör saker meningslösa eller ogiltiga.



  1. Kontrollera statusen för databasens e-postköer i SQL Server (T-SQL)

  2. Använd T-SQL, returnera n:te avgränsade element från en sträng

  3. Ytterligare en anledning att undvika sp_updatestats

  4. MySQL-fel #1071 - Angiven nyckel var för lång; max nyckellängd är 767 byte