Nous construisons une application Web pour entreprise, dont l'administration n'existait jusqu'à présent que dans des feuilles Excel. Nous avons presque terminé, mais récemment, on m'a chargé d'importer toutes les données de ces feuilles dans notre nouveau système. Le système est construit en Java, mais comme cette importation n'est qu'une opération ponctuelle, j'ai décidé d'écrire les scripts en Python à la place et de l'importer directement à l'aide de requêtes SQL. Voici le problème. Les nouveaux modèles de données contiennent de nouveaux attributs, qui ne sont pas inclus dans leurs données existantes. Dans la plupart des cas, ce n'est pas un problème, je mets juste un null où je ne peux pas trouver l'information. Mais ensuite, j'ai rencontré quelques attributs, qui sont des booléens et ne peuvent pas être NULL par défaut. J'ai d'abord essayé d'autoriser l'utilisation de null pour ces champs dans notre base de données, mais mon développeur principal m'a dit de ne pas le faire, car cela causerait des problèmes dans notre système à l'avenir. Et maintenant, je ne sais pas trop quoi faire. La solution évidente consiste à définir par défaut chaque valeur booléenne inconnue sur false, mais je pense que cela est également faux, car je ne sais pas si c'est faux.
Exemple: Supposons que vous avez une entité Car qui a un paramètre hasRadio. Vous devez maintenant importer des données dans ce modèle de données, mais dans les données, il n'y a que les colonnes "Modèle" et "Couleur", rien ne dit qu'il y ait ou non radio. Que mettez-vous dans une colonne "hasRadio" si elle ne peut pas être nulle par définition?
Quelle est la meilleure approche dans cette situation? Devrions-nous simplement dire à l'entreprise de remplir manuellement les données manquantes? Ou par défaut à faux?
FileNotFound
, évidemment.Réponses:
Il s’agit principalement d’un problème d’analyse des exigences, et cela n’a rien à voir avec le fait que les données en jeu sont "booléennes". Si vous devez initialiser des tables dans une base de données ou dans un autre type de stockage de données et que vous avez des entrées incomplètes pour certaines colonnes, vous devez d'abord rechercher ce que les utilisateurs du système ou votre client pensent être la bonne valeur par défaut. pour ces colonnes, et vous devez le trouver pour chaque attribut , il n'y a pas de réponse généralement correcte.
Cela conduira généralement à l'un des cas suivants:
il y a une bonne valeur par défaut pour la colonne spécifique, les utilisateurs ne s'inquiètent pas de savoir si la valeur est initialement la même pour tous les enregistrements, ils peuvent définir les valeurs correctes facilement par la suite si nécessaire
il y a une règle pour déterminer la valeur par défaut idéale à partir d'autres informations, de sorte que vous puissiez mettre cette règle dans le code
les utilisateurs ou votre client vont étendre les données d'entrée et fournir les valeurs manquantes (peut-être manuellement), avant qu'elles ne soient importées dans la base de données
il n'y a pas de bonne valeur par défaut pour la colonne spécifique et / ou pour un enregistrement, les données doivent être importées non plus, mais les utilisateurs veulent savoir pour quels enregistrements la valeur particulière est déjà initialisée et pour laquelle pas. Ils peuvent donc entrer la valeur après , et de suivre pour qui enregistre la valeur est déjà réglée correctement et pour lesquels non.
Le dernier cas nécessite quelque chose comme NULL pour représenter l'état non initialisé ou inconnu, même pour une valeur booléenne, si votre aîné l'aime ou non. S'il existe une raison technique obscure qui interdit l'utilisation d'une valeur NULL pour une colonne spécifique, vous devez simuler l'état "inconnu" d'une manière différente, en introduisant une colonne booléenne supplémentaire (du type
hasRadioIsUnknown
) ou en utilisant un paramètre 3. énumération -Évaluées au lieu d'un booléen (commeHasNoRadio=0
,HasRadio=1
,Unknown=2
). Mais adressez-vous à votre supérieur, une fois que vous avez effectué une analyse approfondie des besoins, pour vous assurer qu’une telle solution de contournement est vraiment nécessaire.la source
Ce n'est pas une question technique; c'est une question de règles commerciales. Donc, vous devez demander "l'entreprise".
Adressez-vous au propriétaire du produit et / ou au (x) partenaire (s) et dites quelque chose comme:
Une discussion s'ensuivra probablement. Mais, c'est fondamentalement ça. La solution technique découlera naturellement de règles de gestion plus étoffées.
la source
Le problème général est toute une sous-zone de programmation appelée nettoyage des données, qui fait partie d'une plus grande sous-zone appelée intégration de données . Éviter ce genre de problèmes est probablement une des raisons principales de la migration des feuilles Excel et des raisons pour lesquelles le développeur senior ne veut pas laisser un champ devenir nul. Je ne pense pas qu'il soit déraisonnable de dire que c'est l'une des plus grandes sources de complexité des migrations de données.
Le simple fait d'utiliser NULL chaque fois que vous le pouvez est probablement une mauvaise chose à faire, sans parler de changer le modèle de données pour rendre encore plus de champs nuls. La vérification de l’intégrité d’Excel est faible ou inexistante, ce qui est probablement à l’origine de bon nombre de ces problèmes. La mauvaise chose à faire est de supprimer la vérification d'intégrité dans la nouvelle base de données et d'y déposer des déchets. Cela ne fait que perpétuer le problème et ajoute une complexité considérable aux intégrations futures, qui devront en quelque sorte traiter des données insensées.
Une partie de la différence est probablement due à l'inadéquation du modèle de données. Il s’agit en grande partie de connaître (intimement) les deux modèles de données et de savoir comment mapper l’ancien avec le nouveau. Tant que le nouveau est capable de capturer l'ancien. (Sinon, votre équipe a probablement un très gros problème.) Cela peut facilement nécessiter plus de travail que la simple copie de colonnes. Darkwing en donne un excellent exemple (ainsi que la raison pour laquelle insérer aveuglément des NULL est une mauvaise chose à faire). Si l’ancien modèle a un
ReceivedDate
et unInProgress
peu et que le nouveau modèle a unStartDate
etProcessingEndTime
, vous devrez décider si et comment définir le fichierProcessingEndTime
. En fonction de la manière dont il est utilisé, un choix raisonnable (mais arbitraire) peut être de le régler de la même manière que leStartDate
(ou peu de temps après si cela pose problème).Cependant, une partie de la différence est probablement due à des données qui "devraient" être manquantes ou corrompues. (Probablement d'erreurs de saisie de données, de migrations antérieures ou de bogues dans les systèmes de traitement de données.) Si personne dans votre équipe ne s'y attendait, alors vous vous êtes (ensemble) engagé à consacrer 20% de votre temps au projet " presque fini. (C'était un numéro inventé, mais ça peut être loinpire que cela, ou mieux. Cela dépend de la quantité de données incorrectes, de son importance, de sa complexité, de la facilité avec laquelle les responsables des données peuvent intervenir, et d'autres facteurs.) Une fois que vous avez déterminé que les données sont "supposées être "là mais manque. Généralement, vous essayez de déterminer l'étendue du problème en interrogeant les anciennes sources de données. S'il s'agit de dizaines ou de centaines d'entrées, il s'agit probablement d'erreurs de saisie de données et les clients responsables des données doivent les résoudre manuellement (c'est-à-dire vous indiquer quelles valeurs doivent être.) S'il s'agit de millions d'entrées (ou d'une fraction significative des données) , alors vous devrez peut-être reconsidérer si vous avez correctement identifié qu'il "devrait être" là. Cela pourrait indiquer une erreur de modélisation dans le nouveau système.
Par exemple, imaginons une facture comportant des quantités et des totaux par article (mais pas le prix unitaire), sauf que certaines des quantités manquaient inexplicablement. Parler à la personne qui traite de telles factures peut produire un (ou plusieurs) des scénarios suivants: 1) "oh, une quantité en blanc signifie une quantité de 1", 2) "oh, je sais que ces articles coûtent environ 1 000 $ alors, il s'agit clairement d'un ordre pour 2 ", 3)" quand cela se produit, je recherche le prix dans cet autre système et divise et arrondit ", 4)" je le recherche dans un autre système ", 5)" il ne s'agit pas de données réelles ", 6)" jamais vu ça avant ".
Comme suggéré, cela peut indiquer certaines manières de résoudre automatiquement la situation, mais vous devez faire attention à ce que la solution s'applique à tous les cas. Il est fréquent que d’autres systèmes impliqués puissent recouper les données et c’est une bonne chose. Cependant, c’est souvent une mauvaise chose dans la mesure où il peut être difficile d’avoir accès à ces systèmes et de s’intégrer à ceux-ci pour effectuer la vérification croisée, et il est souvent évident que les systèmes entrent en conflit les uns avec les autres, pas seulement par manque de données. Certaines interventions manuelles sont souvent nécessaires et, en fonction de l’échelle, peuvent nécessiter un outillage et la création d’interfaces spécifiques à la tâche de nettoyage des données. Ce qui est souvent fait, c'est que les données sont partiellement importées, mais les lignes contenant des données manquantes sont envoyées dans une table séparée où elles peuvent être révisées.
la source
Changer le modèle de données.
Vous pouvez normaliser la hasradio et vous n'aurez plus de NULL.
Si vous ne pouvez pas déterminer une valeur booléenne, n'utilisez pas de booléen.
En permettant à une valeur booléenne de devenir nulle, il cesse d'être un booléen. Un booléen peut avoir 2 états: False, True.
Vous avez besoin de 3 états: False, True, Unknown.
Avez-vous la possibilité de changer le modèle de données?
(Et une autre chose à laquelle j'ai pensé, si en python ou java vous récupérez les données de votre base de données. Vous récupérez l'enregistrement, vérifiez le champ hasradio, que se passera-t-il si vous vérifiez si c'est vrai ou faux et s'il est nul?)
la source
CarFeatures
, avec des champsCar_ID
,Feature_ID
,Has_Feature
? Cela semble être une bonne idée.bool
a a plus de deux valeurs, parce que, comme vous l'avez dit, ce n'est pas le cas. Abool
est soittrue
oufalse
. Cependant, dans le cas des OP, OP ne traite pasbool
directement, maisOption<bool>/Maybe<bool>
peut avoirSome -> true/false
ouNone
.Comme d'autres l'ont fait remarquer, vous avez ici une valeur booléenne qui n'est pas vraiment booléenne et le problème est de le forcer à être booléen ou de le gérer autrement.
Au lieu d'avoir un seul résultat booléen, vous pouvez obtenir deux résultats booléens. Ceux-ci pourraient soit d'accord ou pas d'accord. S'ils sont d'accord, vous obtenez un résultat vrai / faux simple.
Si, toutefois, ils sont en désaccord, vous obtenez un résultat indéterminé et vous avez une chance, en fonction des circonstances dans lesquelles il se produit, de décider de la manière de le gérer. Dans certains cas, un résultat indéterminé pourrait être mieux interprété comme vrai, alors que dans d'autres, le même résultat indéterminé pourrait être interprété comme faux, selon l'option la plus sûre.
Cela permettrait néanmoins de signaler le résultat comme indéterminé, de sorte que cette nuance supplémentaire de la valeur ne soit pas complètement perdue, jusqu'au point où la valeur peut être résolue et réinitialisée de manière définitive.
la source