2009-07-25 5 views
1

Imaginez que j'ai une table Orders avec les colonnes OrderID (PK), CustomerID, CustomerOrderN et ainsi de suite. Maintenant, je dois ajouter une possibilité de "fermer" les commandes en spécifiant une raison pour laquelle la commande est fermée (par exemple "prix offert est trop élevé pour le client", "non disponible", "client demandé de fermer la commande").Comment modéliser les états Open/Closed dans une base de données?

Question 1. Quelle serait la meilleure et la plus correcte façon de l'implémenter dans la conception de base de données?

Je pense que le meilleur moyen est de créer une colonne fermée qui peut être nulle (si l'ordre est ouvert) et sinon null (c'est-à-dire si l'ordre est fermé) alors la valeur pointe vers une autre table OrderCloseReasons. Et si j'ai déjà :) une colonne booléenne Fermée dans la table Commandes, et maintenant je dois implémenter la possibilité de spécifier des raisons de fermeture. Je ne peux pas refactoriser beaucoup parce que le système n'est pas si petit déjà, donc il est difficile de refactoriser le schéma de base de données. Quel serait le meilleur moyen d'ajouter la possibilité de spécifier les raisons de la fermeture dans un tel cas?

Je pense que si j'ajoute juste la colonne CloseReasonID à la table Orders, ce ne sera pas bon. Mais je ne suis pas sûr.

Merci d'avance.

+0

Bonne question, mais je vous invite à réviser le titre de votre question. Peut-être, quelque chose comme "Comment modéliser les états Open/Closed dans une base de données" –

Répondre

4

Si vous avez un tas de raisons de fermeture spécifiques que vous souhaitez utiliser, et si vous devez être en mesure d'effectuer des requêtes basées sur un type spécifique de raison proche (disons tout par la raison X), alors vous suggérer est une bonne idée - null, ou un ID de raison proche. D'autre part, si vous n'avez pas besoin de chercher, etc., vous pouvez simplement avoir une colonne fermée, et une autre colonne qui explique pourquoi elle a été fermée.

+1

Cependant, je recommanderais d'utiliser par exemple. "0" pour "non fermé", puis "1" ... "999" pour des raisons de fermeture. De cette façon, vous pouvez éviter de devoir toujours traiter le cas particulier d'une valeur de colonne étant NULL. –

3

Je recommanderais une colonne StatusCode (probablement int datatype) et une table séparée contenant un StatusCode (int) et StatusCodeDescription (varchar). Cela vous donne plus de flexibilité si vous ou vos utilisateurs finaux pensez à un autre statut possible plus tard.

1

Personnellement, je voudrais faire la table de recherche comme vous le suggérez, mais appelez cela Statut. Je rendrai la clé étrangère à la table d'état dans la table Orders un int, pas null avec un défaut de 1.

Ensuite, les enregistrements dans la table d'état seraient (1) Open, (2) Closed reason one , (3) Raison fermée deux, etc. De cette façon, vous pouvez mapper à une énumération dans un calque supérieur sans avoir à faire quelque chose de spécial dans vos procédures stockées. C'est-à-dire, tout ce que vous faites est d'inclure le StatusID dans votre SELECT au lieu d'avoir à manipuler le null comme signifiant une chose et les valeurs de recherche comme une autre.

0

La fusion de null et de raison dans une colonne de texte nullable n'est pas une bonne idée car elle peut ne pas être facilement lisible par d'autres programmeurs ou même par vous après quelques jours. Ayant deux colonnes, l'un est un booléen ou un code d'état tel que spécifié par David, et sépare la colonne pour la raison. Cela donne plus de lisibilité à votre conception.

Mais je vais aller un pas en avant et les meilleures pratiques dans les logiciels au niveau des finances est d'avoir construit en piste d'audit, parce que je voudrais certainement savoir ..

« Qui a fermé l'ordre? » "À quelle heure il était fermé?" "A-t-il été rouvert?"

La piste de vérification se compose généralement d'une autre table par exemple,

OrderAudit -> AuditID -> OrderID -> ChangeMadeBy -> ChangeDateTime -> ChangeColumn -> ChangeValue

qui donnera un contrôle total sur qui a fait quoi avec cet ordre et à quel moment

0

Une table supplémentaire contenant la raison exacte pour les ordres qui sont fermés

Cela ne porte pas atteinte à 1NF parce que vous n'introduisez pas de valeurs nulles dans le schéma de la base de données, et vous avez la garantie absolue que vos modifications n'affecteront pas les éléments existants (ce que vous avez clairement indiqué).

EDIT

Voir par ex. "Ce que la première forme normale signifie vraiment" dans la date sur la base de données: Writings 2000-2006 (Springer-Verlag, 2006). Peut-être aussi trouvable comme un papier autonome sur internet.

Et de "Introduction aux systèmes de base de données", 8ed. : "Une relvar est en 1NF si et seulement si, dans chaque valeur légale de cette relvar, chaque tuple contient exactement une valeur pour chaque attribut." (et null ne peut pas être une valeur, car il n'est pas égal à lui-même).

+1

Pouvez-vous s'il vous plaît me dire pourquoi l'introduction de NULL violer 1NF? Un lien ou une citation sera également apprécié. – nightcoder

Questions connexes