Pour être rapide, voici mon problème, j'ai essayé de searchr StackOverflow pour la réponse mais je ne peux pas find une réponse satisfaisante.
J'ai une table InvoiceHeader avec des colonnes (simplifié):
InvoiceID : Int - PK Identity(1,1) InvoiceDate : date CustomerID : Int - FK to Customer table
Etc…
Je vais fréquemment afficher des informations sur la facture aux users. Lorsque j'affiche le numéro de facture pour les users, j'ai besoin d' append un préfixe et un remplissage de zéro à l'InvoiceID.
Par exemple :
InvoiceID : 1 Invoice Number : INV0000001
Ma question est, devrais-je faire une colonne BRAND NEW PERSISTED COMPUTED dans la table InvoiceHeader
pour save le numéro de facture formaté comme ceci:
InvoiceNumber AS 'INV' + RIGHT('000000'+cast(InvoiceID as varchar(7)),7)
ou devrais-je sélectionner le InvoiceID
et le traiter dans INV0000001
à l'exécution de mon application?
Mon dilemme :
EDIT : En pensant à beaucoup d'endroits où je devrai formater manuellement le numéro de facture chaque fois que j'en ai besoin (si je n'utilise pas la colonne calculée), je suis maintenant presque obligé d'aller avec la solution d' Esperento57 :
Faire 2 nouvelle colonne:
InvoiceID : int identity (PK) Prefix : char(3) --> INV, etc InvoiceNumber : Prefix + RIGHT('000000'+cast(InvoiceID as varchar(7)),7)
Mais je ne ferai pas PK inclure Prefix parce que InvoiceID est l' identity
sorte qu'il est unique par lui-même.
Je considère aussi toujours le sharepoint vue de Matt sur la séparation des préoccupations aussi, parce que cela fait du sens.
Ma proposition pour vos colonnes:
InvoiceID: entier non nul avec autoincrement (la séquence n'est pas nécessaire, SQL Server fait le travail)
Préfixe: varchar (10) non null FK sur PREFIXTABLE
InvoiceID et Prefix sont la key primaire
InvoiceNumber: colonne calculée et persistante = Préfixe + RIGHT ('0000000' + InvoiceID, 7)
Ajouter un index sur InvoiceNumber
Avec ma proposition, vous pouvez:
Vous devriez le garder comme une valeur numérique dans la database et le formater, cela vous empêchera de stocker inutilement des données sans valeur et améliorera les performances des requêtes. Vous pouvez appliquer le format à un niveau bas dans votre application si cela réduit le nombre de places à formater, mais en fonction de la complexité de votre application, il est peu probable que vous ayez besoin d'écrire cette logique de formatting plus d'une fois.
Il y a quelques points valables dans les autres réponses, par exemple le point sur les numéros manquants peut ou ne peut pas être important pour vous – vous seul savez si cela est pertinent.
La question de changer le préfixe dans le futur, je serais méfiant à less que vous sachiez que c'est une exigence concrète maintenant. Il existe plusieurs manières de modifier une modification de votre préfixe, que vous la stockiez dans la database, la génériez dans une vue ou dans la couche d'interface user / métier. C'est une de ces choses que je suggérerais à KISS et YAGNI !
NB Martin Fowler fait un très bon point dans l'article ci-dessus sur la distinction entre la construction de fonctionnalités présomptives et la construction de logiciels extensibles. Il s'agit de la mesure importante à utiliser systématiquement lors de l'examen des designs relatives à ces types de problèmes: faites le minimum pour vous assurer d'avoir des points d'extension, mais ne mettez en œuvre que les fonctionnalités dont vous avez besoin.
Je pense que vous devriez vraiment séparer l' ID
interne, qui est une key primaire et est utilisé pour identifier un logging, à partir d'une string que l'user voit.
L'user final ne devrait jamais voir les ID générés par IDENTITY
, car il peut facilement y avoir des lacunes.
Donc, j'ai deux colonnes normales: int InvoiceID
et char(10) InvoiceNumber
. Oui, il y aura une méthode distincte pour générer un numéro de facture suivant. Dans SQL Server 2014, j'utiliserais l'object SEQUENCE
avec l'option NO CACHE
pour cela.
Lorsque vous séparez les ID internes des numéros de facture visibles par l'user, vous pouvez facilement modifier le format de ces numéros dans le futur. Par exemple, dans deux ans, le département des finances peut décider d'introduire un autre préfixe ABC000001
. Évidemment, toutes les factures historiques existantes doivent conserver leurs numéros. Avec une colonne séparée pour le numéro de facture, il n'y a pas de problème. Avec une colonne calculée, vous aurez un problème.
Si c'est la formule pour calculer le numéro de facture,
InvoiceNumber : Prefix + RIGHT('000000'+cast(InvoiceID as varchar(7)),7)
Ici, l'écart entre le nombre de factures n'a pas d'importance.
Ensuite, je garderais onlyInvoiceID. Alors que l'affichage, je vais formater le numéro de facture de cette manière soit en bas niveau ou proc lui-même. Lorsque l'user va chercher le numéro de la facture, j'enlève le préfixe et le jette dans la variable int.
Ensuite, je vais effectuer une search sur la colonne invoiceID.
Mais si Prefix peut changer et qu'il ne devrait pas y avoir de GAP entre les numéros de facture alors,
i) Garder le préfixe dans la même table est une mauvaise idée.
ii) Le calcul du numéro de facture changera aussi parce que vous devez maintenir la continuité.
Mais je ne ferai pas PK inclure Prefix parce que InvoiceID est l'identité de sorte qu'il est unique par lui-même.
Cela dépend. Bien sûr, selon moi aussi Prefix est hors de question. Mais InvoiceID peut être PK + CI ou seulement PK ou seulement identité ou seulement CI.
vous hv pour examiner chaque option.