PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Que faire des valeurs nulles lors de la modélisation et de la normalisation ?

SQL traite NULL spécialement selon sa version de 3VL (logique à 3 valeurs). La normalisation et les autres théories relationnelles ne le font pas. Cependant, nous pouvons traduire les conceptions SQL en conceptions relationnelles et inversement. (Supposez qu'il n'y a pas de lignes en double ici.)

La normalisation arrive aux relations et est défini en termes d'opérateurs qui ne traitent pas NULL spécialement. Le terme « normalisation » a deux significations distinctes les plus courantes :mettre une table dans « 1NF » et dans « NFs supérieurs (formes normales) ». NULL n'affecte pas la "normalisation à 1NF". La "normalisation vers des NF supérieurs" remplace une table par des tables plus petites qui s'y joignent naturellement. À des fins de normalisation, vous pouvez traiter NULL comme une valeur autorisée dans le domaine d'une colonne nullable en plus des valeurs de son type SQL. Si nos tables SQL n'ont pas de valeurs NULL, nous pouvons les interpréter comme des relations et une jointure SQL, etc., comme une jointure, etc. les colonnes du même nom étant égales ou les deux NULL . Et vous ne voudrez pas de tels CK (clés candidates) dans une base de données SQL. Par exemple, vous ne pouvez pas le déclarer en tant que SQL PK (clé primaire) car cela signifie UNIQUE NOT NULL. Par exemple, une contrainte UNIQUE impliquant une colonne nullable autorise plusieurs lignes qui ont un NULL dans cette colonne, même si les lignes ont les mêmes valeurs dans chaque colonne. Par exemple, les valeurs NULL dans les FK SQL entraînent leur satisfaction (de diverses manières selon le mode MATCH), pour ne pas échouer en n'apparaissant pas dans la table référencée. (Mais les SGBD diffèrent idiosyncrasiquement du SQL standard.)

Malheureusement, la décomposition peut conduire à une table avec tous CK contenant NULL, de sorte que nous n'avons rien à déclarer comme SQL PK ou UNIQUE NOT NULL. La seule solution sûre est de convertir en une conception sans NULL. Après la normalisation, nous voudrons peut-être réintroduire une possibilité de valeur nulle dans les composants.

En pratique, nous parvenons à concevoir des tables de sorte qu'il y ait toujours un ensemble de colonnes sans NULL que nous pouvons déclarer comme CK, via SQL PK ou UNIQUE NOT NULL. Ensuite, nous pouvons nous débarrasser d'une colonne nullable en la supprimant de la table et en ajoutant une table avec cette colonne et les colonnes de certains CK sans NULL :si la colonne est non NULL pour une ligne dans l'ancienne conception, alors une ligne avec sa valeur de sous-ligne et de colonne CK va dans le tableau ajouté ; sinon, il est NULL dans l'ancienne conception et aucune ligne correspondante n'est dans la table ajoutée. (La table d'origine est une jointure gauche naturelle des nouvelles.) Bien sûr, nous devons également modifier les requêtes de l'ancien design au nouveau design.

Nous pouvons toujours éviter les valeurs NULL via une conception qui ajoute une colonne booléenne pour chaque ancienne colonne nullable et a l'ancienne colonne NOT NULL. La nouvelle colonne indique pour une ligne si l'ancienne colonne était NULL dans l'ancienne conception et lorsque true, l'ancienne colonne est une valeur que nous choisissons à cette fin pour ce type dans toute la base de données. Bien sûr, nous devons également modifier les requêtes de l'ancien design au nouveau design.

Que vous souhaitiez éviter NULL est une question distincte. Votre base de données peut d'une certaine manière être "meilleure" ou "pire" pour votre application avec l'une ou l'autre conception. L'idée derrière l'évitement de NULL est que cela complique la signification des requêtes, complique donc l'interrogation, d'une manière perverse, par rapport à la complication de plus de jointures à partir de plus de tables sans NULL. (Cette perversité est généralement gérée en supprimant les valeurs NULL dans les expressions de requête aussi près que possible de l'endroit où elles apparaissent.)

PS De nombreux termes SQL, y compris PK et FK, diffèrent des termes relationnels. SQL PK signifie quelque chose qui ressemble plus à une superclé ; SQL FK signifie quelque chose qui ressemble plus à une superclé étrangère ; mais cela n'a même pas de sens de parler d'une "superclé" en SQL :

En raison de la ressemblance des tables SQL avec les relations, les termes qui impliquent des relations sont appliqués de manière négligente aux tables. Mais bien que vous puissiez emprunter des termes et leur donner des significations SQL - valeur, table, FD (dépendance fonctionnelle), super-clé, CK (clé candidate), PK (clé primaire), FK (clé étrangère), jointure et prédicat, NF (forme normale), normaliser, 1NF, etc. - vous ne pouvez pas simplement substituer ces significations SQL à ces mots dans les définitions, théorèmes ou algorithmes RM et obtenir quelque chose de sensé ou de vrai. De plus les présentations SQL des notions RM presque jamais vous dire en fait comment appliquer correctement les notions de RM à une base de données SQL . Ils se contentent de répéter les présentations RM, inconscients de savoir si leur utilisation des significations SQL pour les termes rend les choses absurdes ou invalides.