Il ne fait aucun doute que les NULL doivent être évités lorsque cela est possible, en raison des problèmes qu'ils peuvent introduire plusieurs problèmes d'indexation et de syntaxe de requête.
En raison des problèmes que peuvent poser les NULL, des pressions ont été exercées pour qu'ils ne soient plus utilisés. Cependant, comme la plupart des mouvements de ce type, il est devenu incontrôlable, au point que certaines personnes insistent fanatiquement pour que les NULL ne soient jamais utilisés dans les bases de données. J'ai fait partie de ce camp pendant de nombreuses années, avant de trouver qu'il était un peu trop zélé.
La réponse se situe quelque part entre les deux. Les NULL doivent être évités autant que possible, mais il existe effectivement des raisons commerciales valables pour les stocker.
Souvent, vous avez besoin de stocker une valeur numérique facultative, et beaucoup de gens vous diront de simplement stocker un zéro pour indiquer "aucune valeur", mais c'est un anti-modèle encore pire de stocker une valeur magique qui signifie vraiment autre chose. Et si vous ne pouvez pas utiliser le zéro pour un champ, parce que le zéro est également considéré comme une valeur significative, ou parce que cette valeur est utilisée comme multiple d'un diviseur, vous devez donc utiliser une autre valeur magique (-1 ?) pour ce champ dans ce cas précis, et maintenant vous avez un problème encore plus grave, parce que tous vos champs numériques facultatifs se comportent maintenant différemment. Oye.
Les dates sont un candidat encore plus convaincant pour les champs annulables. La "valeur nulle" standard que les gens utilisent dans .NET est la valeur par défaut non attribuée de DateTime, qui est DateTime.MinValue, ou plus précisément le 1er janvier 0001. Cependant, vous ne pouvez pas écrire cette valeur magique dans la base de données SQL car la valeur minimale par défaut pour un champ DATETIME du serveur SQL est le 1er janvier 1973. Vous devez maintenant vérifier que vous convertissez correctement ces valeurs lorsqu'elles sont écrites et lues dans la base de données, et vous devez disposer d'un codage défensif qui vérifie partout si vos champs de date sont inférieurs à SqlDateTime.MinValue, au lieu de simplement vérifier s'ils sont égaux à DateTime.MinValue. Double Oye.
Je préfère traiter les valeurs telles qu'elles sont réellement, et ne pas construire un grand nombre de constructions artificielles pour cacher la véritable signification et l'utilisation du champ. Si un champ peut très bien ne pas avoir de valeur, rendez-le annulable, et rendez-le également annulable dans vos objets d'application (si votre langage supporte une telle chose). Ensuite, à chaque fois que vous utilisez ce champ, vous êtes obligé de réfléchir à ce qu'il faut faire dans le cas où il est NULL, mais c'est en fait une bonne chose. En règle générale, je suis opposé à ce que les développeurs gaspillent leurs neurones dans la complexité inutile du code, mais c'est parce que cela détourne l'attention du véritable problème à résoudre ; cependant, dans ce cas, l'absence de valeur fait partie du véritable problème et doit être prise en compte. Si vous vous contentez de définir ces valeurs par défaut, le développeur qui écrit une formule ou un algorithme sera moins enclin à réfléchir aux conditions limites dans lesquelles les valeurs sont manquantes, et il ne se rendra peut-être même pas compte à ce moment-là qu'il est possible que ces valeurs soient manquantes.