sql >> Database >  >> RDS >> PostgreSQL

Wat te doen met null-waarden bij het modelleren en normaliseren?

SQL behandelt NULL speciaal volgens de versie van 3VL (3-waardige logica). Normalisatie en andere relationele theorie doen dat niet. We kunnen echter SQL-ontwerpen vertalen naar relationele ontwerpen en terug. (Veronderstel hier geen dubbele rijen.)

Normalisatie gebeurt met relaties en is gedefinieerd in termen van operators die NULL niet speciaal behandelen. De term "normalisatie" heeft twee meest voorkomende verschillende betekenissen:een tabel in "1NF" en in "hogere NF's (normale vormen)" plaatsen. NULL heeft geen invloed op "normalisatie naar 1NF". "Normalisering naar hogere NF's" vervangt een tabel door kleinere tabellen die er natuurlijk weer bij aansluiten. Voor normalisatiedoeleinden zou u NULL kunnen behandelen als een waarde die is toegestaan ​​in het domein van een nullable-kolom naast de waarden van het SQL-type. Als onze SQL-tabellen geen NULL's hebben, kunnen we ze interpreteren als relaties &SQL join etc als join, etc. Maar als je ontbindt waar een nullable kolom werd gedeeld tussen componenten, realiseer je dan dat om het origineel in SQL te reconstrueren, je SQL join op gelijknamige kolommen zijn gelijk aan of beide NULL . En zulke CK's (kandidaatsleutels) wil je niet in een SQL-database. U kunt het bijvoorbeeld niet declareren als een SQL PK (primaire sleutel) omdat dat UNIQUE NOT NULL betekent. Een UNIEKE beperking met betrekking tot een nullable kolom staat meerdere rijen toe met een NULL in die kolom, zelfs als de rijen dezelfde waarden hebben in elke kolom. Bijv. NULL's in SQL FK's zorgen ervoor dat hieraan wordt voldaan (op verschillende manieren per MATCH-modus), zodat ze niet voorkomen in de tabel waarnaar wordt verwezen. (Maar DBMS'en verschillen op idiosyncratische wijze van standaard SQL.)

Helaas kan decompositie leiden tot een tabel met allen CK's die NULL bevatten, zodat we niets hoeven te declareren als SQL PK of UNIQUE NOT NULL. De enige zekere oplossing is om te converteren naar een NULL-vrij ontwerp. Na het normaliseren willen we misschien wat nullabiliteit opnieuw introduceren in de componenten.

In de praktijk slagen we erin om tabellen zo te ontwerpen dat er altijd een set NULL-vrije kolommen is die we kunnen declareren als CK, via SQL PK of UNIQUE NOT NULL. Dan kunnen we een nullable kolom verwijderen door deze uit de tabel te laten vallen en een tabel toe te voegen met die kolom en de kolommen van een NULL-vrije CK:Als de kolom niet-NULL is voor een rij in het oude ontwerp, dan is een rij met de CK-subrij en kolomwaarde gaan in de toegevoegde tabel; anders is het NULL in het oude ontwerp en staat er geen overeenkomstige rij in de toegevoegde tabel. (De originele tabel is een natuurlijke left join van de nieuwe.) Natuurlijk moeten we ook queries aanpassen van het oude ontwerp naar het nieuwe ontwerp.

We kunnen NULL's altijd vermijden via een ontwerp dat een booleaanse kolom toevoegt voor elke oude kolom met nullwaarden en waarbij de oude kolom NIET NULL is. De nieuwe kolom zegt voor een rij of de oude kolom NULL was in het oude ontwerp en wanneer waar is, heeft de oude kolom een ​​waarde die we voor dat doel voor dat type in de database kiezen. Natuurlijk moeten we ook zoekopdrachten aanpassen van het oude ontwerp naar het nieuwe ontwerp.

Of je NULL wilt vermijden is een aparte vraag. Uw database kan op de een of andere manier "beter" of "slechter" zijn voor uw toepassing met beide ontwerpen. Het idee achter het vermijden van NULL is dat het de betekenis van query's compliceert, en dus op een perverse manier query's bemoeilijkt, vergeleken met de complicatie van meer joins van meer NULL-vrije tabellen. (Die perversiteit wordt meestal beheerd door NULL's in query-expressies te verwijderen zo dicht mogelijk bij waar ze verschijnen.)

PS Veel SQL-termen, waaronder PK &FK, verschillen van de relationele termen. SQL PK betekent zoiets als superkey; SQL FK betekent meer zoiets als een buitenlandse supersleutel; maar het heeft zelfs geen zin om te praten over een "superkey" in SQL:

Vanwege de gelijkenis van SQL-tabellen met relaties, worden termen die betrekking hebben op relaties slordig toegepast op tabellen. Maar hoewel u termen kunt lenen en ze SQL-betekenissen kunt geven:waarde, tabel, FD (functionele afhankelijkheid), superkey, CK (kandidaatsleutel), PK (primaire sleutel), FK (vreemde sleutel), join en, predikaat, NF (normale vorm), normaliseren, 1NF, enz. - je kunt die woorden in RM-definities, stellingen of algoritmen niet zomaar vervangen door die SQL-betekenissen en iets zinnigs of waars krijgen. Bovendien SQL-presentaties van RM-begrippen bijna nooit u daadwerkelijk vertellen hoe u RM-begrippen op een degelijke manier kunt toepassen op een SQL-database . Ze napraten gewoon RM-presentaties, zich niet bewust van het feit of hun gebruik van SQL-betekenissen voor termen dingen onzinnig of ongeldig maakt.



  1. Hoe te repareren Ora-01427 single-rij subquery retourneert meer dan één rij in select?

  2. Query om alle rijen van de vorige maand te krijgen

  3. Matrix voor door SQL Server ondersteunde versies

  4. Wat betekent Importfout:Symbool niet gevonden:_PQencryptPasswordConn en hoe los ik dit op?