[SQL SERVER] Primary key de type char/varchar

Primary key de type char/varchar [SQL SERVER] - SQL/NoSQL - Programmation

Marsh Posté le 24-02-2005 à 11:11:52    

[:atsuko]  
 
J'suis en train de faire une migration de données d'un prog qui tournait sous une base Pervasive  [:totozzz] vers une nouvelle base SQL SERVER  [:super chinois]  
 
Le truc, c'est qu'il y a une table sous Pervasive dont la clé primaire est un varchar, et qui contient des données du genre 'FOURNISSEUR' et 'FOURNISSEUR ' (vous remarquerez le superbe espace qui fait toute la différence).
Et ça, ça passe pas sous SQL SERVER. J'ai le droit à une violation de primary key.
J'ai beau bidouiller avec les options ANSI_PADDING, les types de données char/varchar, apparemment, si ça touche une clé primaire, c'est kekette, pour le reste, ça marche.
 
Quelqu'un a un idée de comment que j'peux faire ?
 

Reply

Marsh Posté le 24-02-2005 à 11:11:52   

Reply

Marsh Posté le 24-02-2005 à 16:36:03    

en CHAR ça doit fonctionné, c'est clair qu'en VARCHAR c'est peut probable que ça marche...
 
c'est pas intelligent de distingué deux tuples rien qu'avec un espace...
 
a la limite, c'est peut etre mieux de mettre un nombre derriere alors
ex:
FOURNISSEUR1
FOURNISSEUR2
 
mais pas d'espace, évite ça

Reply

Marsh Posté le 24-02-2005 à 16:41:16    

moi23372 a écrit :

en CHAR ça doit fonctionné, c'est clair qu'en VARCHAR c'est peut probable que ça marche...
 
c'est pas intelligent de distingué deux tuples rien qu'avec un espace...
 
a la limite, c'est peut etre mieux de mettre un nombre derriere alors
ex:
FOURNISSEUR1
FOURNISSEUR2
 
mais pas d'espace, évite ça


 
Le monsieur te dit que c'est déjà comme ça et qu'il a des données à récupérer, il te demande pas comment il aurait fallu faire pour que ça arrive pas...[:itm]


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 24-02-2005 à 16:48:25    

Tu remplaces la primary key foireuse par un vrai ID :o
(bon évidemment ça va faire plus de boulot mais ça sera beaucoup moins laid)

Reply

Marsh Posté le 24-02-2005 à 16:54:51    

skeye a écrit :

Le monsieur te dit que c'est déjà comme ça et qu'il a des données à récupérer, il te demande pas comment il aurait fallu faire pour que ça arrive pas...[:itm]


 [:super chinois]  [:ddr555]  
 
Effectivement j'ai pas trop le choix :D
 
Et surtout que remplacer le varchar par un char, ben c'est carrément pas la bonne idée :??:
Vu que mon 'fournisseur', en char de 20 par exemple, va être stocké comme un 'fournisseur         '.
 
Bon, sinon j'avais bien une solution, qui est de stocker aussi la longueur du champ dans la base, et faire une clé primaire sur le champ varchar + la longueur de la clé.
Le coup de l'ID, c'est à voir aussi.
 
En fait j'voulais savoir s'il y avait une solution 'normale' (parce que pour moi c'est SQL SERVER qui chie un peu là) vu que mon chef d'équipe revient pas avant demain après midi [:ocube]
 
Bref, merci pour vos réponses :D

Reply

Marsh Posté le 24-02-2005 à 19:34:20    

skeye a écrit :

Le monsieur te dit que c'est déjà comme ça et qu'il a des données à récupérer, il te demande pas comment il aurait fallu faire pour que ça arrive pas...[:itm]


 
je sais bien ce qu'il a dit, mais s'il ne veut pas que posposer le problème, autant faire ça convenablement, désolé mais c'est pas si compliqué que ça, suffit d'écrire une petite procédure pour cela...

Reply

Marsh Posté le 24-02-2005 à 19:38:58    

moi23372 a écrit :

je sais bien ce qu'il a dit, mais s'il ne veut pas que posposer le problème, autant faire ça convenablement, désolé mais c'est pas si compliqué que ça, suffit d'écrire une petite procédure pour cela...


Convenablement? Tu devrais vite effacer ton premier post parce que ta solution est loin d'être convenable! C'est une réponse de débutant!


---------------
Whichever format the fan may want to listen is fine with us – vinyl, wax cylinders, shellac, 8-track, iPod, cloud storage, cranial implants – just as long as it’s loud and rockin' (Billy Gibbons, ZZ Top)
Reply

Marsh Posté le 24-02-2005 à 20:14:23    

si tu le dis ;-)
néanmoins, jusqu'a présent, il n'y a que moi qui ai proposé un début de solution, tandis que toi, a part spamer le forum, tu ne fais rien...


Message édité par moi23372 le 24-02-2005 à 20:14:40
Reply

Marsh Posté le 24-02-2005 à 20:43:23    

moi23372 a écrit :

a part spamer le forum


 
 :heink:


---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
Reply

Marsh Posté le 24-02-2005 à 20:45:10    


 
toi aussi la faute te choque ?


---------------
JE JE SUIS LIBERTINEEEEEEEEEEE JE SUIS UNE CATINNNNNNNNN §§§§§§§§
Reply

Marsh Posté le 24-02-2005 à 20:45:10   

Reply

Marsh Posté le 24-02-2005 à 20:45:30    

non, mais je vois pas le rapport avec le spam :o


---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
Reply

Marsh Posté le 24-02-2005 à 21:05:46    

antp a écrit :

non, mais je vois pas le rapport avec le spam :o


'tain vous voyez bien comment il maîtrise son sujet depuis sa première intervention sur le forum :o


---------------
Whichever format the fan may want to listen is fine with us – vinyl, wax cylinders, shellac, 8-track, iPod, cloud storage, cranial implants – just as long as it’s loud and rockin' (Billy Gibbons, ZZ Top)
Reply

Marsh Posté le 24-02-2005 à 21:41:06    

drasche a écrit :

Tu remplaces la primary key foireuse par un vrai ID :o
(bon évidemment ça va faire plus de boulot mais ça sera beaucoup moins laid)


+1

moi23372 a écrit :

si tu le dis ;-)
néanmoins, jusqu'a présent, il n'y a que moi qui ai proposé un début de solution, tandis que toi, a part spamer le forum, tu ne fais rien...


 
-1, tu sors.


---------------
uptime is for lousy system administrators what Viagra is for impotent people - mes unixeries - github me
Reply

Marsh Posté le 25-02-2005 à 09:44:40    

Ca devient vraiment le bordel le forum prog :/ :D

Reply

Marsh Posté le 25-02-2005 à 09:45:18    

Oué c'est le far west ici [:zaib3k]

Reply

Marsh Posté le 25-02-2005 à 10:09:44    

chrisbk a écrit :

Oué c'est le far west ici [:zaib3k]


 
(on est pas tous en charente, hein...:o)


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 25-02-2005 à 10:14:39    

skeye a écrit :

(on est pas tous en charente, hein...:o)


 
 
ste vieux coup bas :/
j'avertis un modo :o

Reply

Marsh Posté le 25-02-2005 à 13:50:56    

Ils ont l'adsl là bas :??:

Reply

Marsh Posté le 07-03-2005 à 10:34:22    

Euh...
 
La solution de moi23372 est loin d'être sexy (et la première tout du moins ne marche pas de toute façon), mais elle est néanmoins une meilleure piste que la réponse de Drasche.
 
Je travaille actuellement dans une base de données, avec pas mal de conneries dedans.
1) Aucune clé primaire sur des char/varchar. La raison évoquée est "c'est plus rapide", ce qui est absolument faut (selon les SGBD, ca peut même être parfois le contraire !)
2) Demandes débiles, du genre "ha ben faut shooter cette clé composée pour le changer en clé simple", parceque c'est lent. A nouveau, c'est faux. Force est de constater que beaucoup de gens n'ont pas compris ce qu'est un index. Par contre, vous vous êtes déjà amusé à modifier 50 tables afin d'en changer les PK et FK ? Moi oui, et c'est pour cette raison que la solution de Drasche est à mettre à la poubelle illico presto. C'est le meilleur moyen de planter totalement la base, en oubliant un champ quelque part, ou planter l'application, en oubliant une requête dans un coin.
 
Bref, changer de VARCHAR à CHAR, c'est pas la solution rêvée, mais ça reste une excellente solution. Par contre, il reste un problème :
 
"FOURNISSEUR " => "FOURNISSEUR      "
"FOURNISSEUR" => "FOURNISSEUR      "
 
=> Les deux valeurs sont à nouveau égales.
A ce moment, reste la soltution brutale de faire, avant la conversion, un "REPLACE(champ, ' ', '_')" sur la clé. Si les paramètres SQL Server sont corrects, le cascade va se déclencher, et donc mettre à jour les fils sans problème. La solution sera alors résolue tout simplement, sans changer ni le type, ni les valeurs de la PK (enfin, à peine changées).
 
Maintenant, évidement, s'il y a des "VALEUR_A_LA_CON" et "VALEUR A LA CON" dans la base, cette solution est à modifier.
 
Dans tous les cas, je suis très surpris que deux lignes de référence aient une clé si similaire. Ca ressemble plus à une erreur de saisie qu'autrechose. Avant de migrer, je pense qu'il serait préférable de s'assurer que les incohérences actuelles ne soient pas répliquées (une migration, c'est le moment rêvé pour remettre d'aplomb des données foireuses).
 
Bref, la solution de changer de PK me semble la piste "de la dernière chance", car à la fois inutile d'un point de vue performances, et lourde d'un point de vue mise en place (quand on bosse comme ici avec 12 Mo de procédures stockées, on s'amuse pas à changer une PK pour le plaisir, sauf quand le directeur informatique qui comprend rien à un SGBD - pour lui ça s'arrête au wizard "créer une table" dans Access) te l'impose.

Reply

Marsh Posté le 07-03-2005 à 10:42:12    

Ajurna> ben c'est des encodages de end-users, c'est pour ça que ça a l'air foireux :o  Donc pas vraiment surprenant :/


---------------
Whichever format the fan may want to listen is fine with us – vinyl, wax cylinders, shellac, 8-track, iPod, cloud storage, cranial implants – just as long as it’s loud and rockin' (Billy Gibbons, ZZ Top)
Reply

Marsh Posté le 07-03-2005 à 10:44:24    

Ayant déjà traiter ce genre de problème, j'ai une bien mauvaise nouvelle à annoncer. Une solution est la création d'une moulinette afin de vérifier et transférer les informations. C'est chiant à mourir, c'est long, mais c'est le seul moyen.
 
Pour exemple, je me suis taper la migration des informations de la DRIRE d'Amiens (pour ceux qui connaissent DDIT), et franchement, migrer des données ou il n'y a eu aucun controle d'entrée est une vrai plaie.


Message édité par Gfreeman le 07-03-2005 à 10:48:32
Reply

Marsh Posté le 07-03-2005 à 10:57:42    

C clair. Heureusement que sous SQL Server il y a DTS, ça simplifie pas mal le boulot :)

Reply

Marsh Posté le 07-03-2005 à 11:55:03    

Merci Arjuna pour ta réponse :)
 
Mais bon, j'ai fini le truc depuis 1 semaine. J'ai, comme tu l'as dit, remit d'aplomb tout ça. Les fournisseurs avec les trailing blank sont, en fait, pas une erreur de saisie, mais plutôt un problème de moulinette du programme duquel je transfère les données.  
 
J'ai eu aussi quelques autres surprises assez violentes, du genre des clefs primaires identiques, si si :D
Quoique non surprenant quand on a bossé deux ans avec Pervasive...
 

Citation :


Dans tous les cas, je suis très surpris que deux lignes de référence aient une clé si similaire.


Si tu savais...[:ddr555]
Le "master" programme dont sont tirées toutes ces aneries utilise les SGBD de façon un peu spéciale...
En gros, dans les tables, y a un champ, un blob, et tout est foutu en vrac dans ce blob. :D
Ensuite, grâce à une classe, remasterisée en fonction de la version du logiciel, le blob est parsé, et les valeurs lues dans le code source.  
C'est donc même assez récurrent de trouver des clés primaires égales dans le logiciel. Par exemple un code produit doit être unique, mais il ne l'est pas. Et quand toi tu récupères les infos via un txt ou une api, t'en chies pour faire quelque chose de correct :D

Reply

Marsh Posté le 07-03-2005 à 12:24:21    

Arf :D Ca m'a l'air sympa comme tout ton truc :D
 
Bon courrage ;)

Reply

Marsh Posté le 07-03-2005 à 17:02:09    

Citation :

1) Aucune clé primaire sur des char/varchar. La raison évoquée est "c'est plus rapide", ce qui est absolument faut (selon les SGBD, ca peut même être parfois le contraire !)


 
 
 :heink:  
 
Sous sql server, c'est fortement deconseillé ! Et effectivement pour des raisons de rapidité. L'unicité est très importantes pour les index clusters. Un index cluster doit être petit, stable et si possible unique. Et Ils sont très conseillés pour optimiser une base sql server.
 
Plus ta clef est petite plus tu en auras par noeud d'index et donc moins tu auras d'entrées/sorties.
 
Donc un compteur d'entiers pour la clef primaire interne, et roulaize. Que tu affiches ensuite à ton client une reference en varchar avec un index non-cluster dessus, ok. Mais une clef primaire en char ou varchar : beurk !
 
Le jour où tu as à modifier le système de référencement de tes clients, ça sera d'autant plus simple que ta clef primaire interne ne change pas...


Message édité par ipahc le 07-03-2005 à 17:19:04

---------------
"Kattthyyyyy, r'garde comment je prends trop bien de l'angle sa mère !" - Sat08 2004
Reply

Marsh Posté le 07-03-2005 à 17:32:58    

Le type des données n'impacte en rien l'index, puisque l'index a lui-même sa propre représentation interne sous forme d'entier (ou plus, selon la taille de la table).
 
Le type de données n'a donc rigoureusement aucune incidence.
 
Ensuite, lorsque ta table est très grande, l'index sera alors constitué en interne soit de NUMERIC soit de GUID (je pense que c'est plutôt ce second type), qui est de 80 bits, soit 10 octets, ce qui est à la fois énorme, et inadapté aux processeurs, qui ne savent faire des calculs que sur 32 ou 64 bits (et pas sur 80...)
Et même si SQL Server ne travaillait pas de la sorte, "FOURNISSEUR" ça fait 11 caractères, donc de toute façon, la différence avec un type de 80 bits est tellement faible qu'elle n'a aucun impact sur la vitesse de traîtement.
 
Ensuite, imagine une clé sur un CHAR(4) (c'est cette valeur ou plus petite que je préconise généralement), la représentation mémoie, c'est 4 octets, soit rigoureusement la même qu'un entier (32 bits).
Bref, une clé à base de CHAR est infiniement plus lisible, et pourtant, ne fait absoluement rien perdre à la vitesse de traîtement. [:spamafote]

Reply

Marsh Posté le 07-03-2005 à 17:35:11    

PS: montre-moi l'article que l'aide SQL Serveur où ils déconseillent l'utilisation de ce type. J'ai jamais trouvé dans SQL Server. Sous Oracle, en tout cas, sûr et certain, ça n'a rigoureusement aucune incidence, les CHAR et les entiers étant de toute façon au final gérés de la même façon dans les index (4 char, tu peux très bien en faire un int(32) et faire tes calculs dessus)
 
A la limite, je dis pas pour les types nchar et nvarchar, qui sont lourds à traîter, de par le fait qu'un caractère peut s'étaller de 1 à 4 byte.


Message édité par Arjuna le 07-03-2005 à 17:35:56
Reply

Marsh Posté le 07-03-2005 à 17:57:16    

Si tu parles de char(4), on est d'accord (cela dit, je ne vois pas en quoi c'est plus lisible ?), puisque cela reste un petit index.
 
un noeud, c'est une page de 8ko, plus ta clef est petite...plus tu en as par noeud ;)
 
Ton index_cluster tu le places generalement sur ta clef primaire (petite...et unique) et comme lorsque tu vas passer par un non_cluster, il va traverser l'index cluster autant qu'il ait un minimum de noeuds à parcourir :)
 
 
je n'ai pas d'article à ce sujet...seulement un classeur de formation sur les bases sql server performantes :D
 
 


---------------
"Kattthyyyyy, r'garde comment je prends trop bien de l'angle sa mère !" - Sat08 2004
Reply

Marsh Posté le 07-03-2005 à 18:07:42    

Forcément, on va pas faire une clé unique sur un nvarchar(8192) faudrait être marteau (et pkoi pas une clé composée de 128 champs de ce type pendait qu'on y est ;))
 
Sinon, pour une table de référence "type" par exemple, tu peux faire :
 
1 Commande
2 Proforma
3 Devis
4 etc.
 
Ou alors :
 
CDE Commande
PRF Proforma
DEV Devis
ETC Etc.
 
Par exemple ;) L'intérêt d'avoir un code lisible, c'est que lorsque tu consultes ta table des évènements, t'auras pas exemple :
 
DEV 125 06/08/2001 897.25 Monsieur Dupond avec un D
PRF 389 16/06/1999 125.56 Monsieur Dupont avec un T
 
Bah entre "DEV" et "PRF", on isole vachement mieu les devis et les proforma ;)

Reply

Marsh Posté le 07-03-2005 à 18:13:37    

Et comment fais-tu pour garantir l'unicité pour ce type de clef ? ;) Comment tu les génères ? C'est à l'utilisateur de le faire ?
 
 


---------------
"Kattthyyyyy, r'garde comment je prends trop bien de l'angle sa mère !" - Sat08 2004
Reply

Marsh Posté le 07-03-2005 à 20:02:59    

:??: ben c'est une bête clé primaire pour la table "TYPE", et une bête clé étrangère sur la table "EVENEMENT", exactement comme si c'était un type numérique. Comprend pas ta question (??)

Reply

Marsh Posté le 07-03-2005 à 20:54:31    

Les clefs primaires de la table type, tu les génères comment ? A la mano ?  
 
Cela dit j'ai utilisé ce type de clef pour mes commerciaux. Ils sont repérés par leurs initiales :D

Reply

Marsh Posté le 07-03-2005 à 21:28:03    

Ben... Ca de déclare comme les PK sur les nombres... Comprends pas la question... Soit tu fais un script, soit dans l'éditeur de table, tu sélectionnes la ligne et tu cliques sur le clé. Vois pas de différence !

Reply

Marsh Posté le 07-03-2005 à 23:06:26    

Si tu mets un nombre, tu vas probablement utiliser un compteur. Unicité sans faille. Transparence totale pour l'utilisateur qui ne verra jamais ce code.
 
Là, ce sont tes users qui vont choisir la clef primaire (pas le champ, le contenu du champ), il va falloir que tu assures son unicité avant la saisie dans la base. (genre pour Developpement, s'assurer que l'user ne prenne pas DEV..sinon baoum :D )
 
De plus, si un jour ton clients te dit qu'il change le libellé commande par ...order, par exemple, ta clef devient tout de suite moins lisible. Tu fais quoi ? Tu fais une mise à jour en cascade ?
 
Avec une clef numerique aucun soucis..
 
Cle(PK)     Prefixe     Libellé
1            CDE         Commande
2            DEV          Devis
...etc
 
 
Je n'affiche à l'utilisateur que le préfixe. Il ne voit jamais ma clé.  
Et quand on me demande de passer le prefixe à ORD et le libellé à ORDER....aucun soucis, nul besoin de faire une maj en cascade et de verifier l'integrité :)
 
 
J'ai justement rencontré ce problèmes avec les initiales en PK pour mes commerciaux. Des qu'une commerciale se marie...c'est le bordel car ses initiales changent. Du coup, j'ai bricolé une moulinette pour rajouter une clef numerique.. Je t'assure que j'aurais préféré prévenir que guérir
 


---------------
"Kattthyyyyy, r'garde comment je prends trop bien de l'angle sa mère !" - Sat08 2004
Reply

Marsh Posté le 07-03-2005 à 23:08:02    

Ouais, moi mes clés sont TOUJOURS des integer. Jamais de clé significative. Toujours un truc abstrait :) Parce qu'à chaque fois que j'ai eu le malheur de mettre autre chose, tôt ou tard c'était le bordel :/

Reply

Marsh Posté le 07-03-2005 à 23:15:48    

FlorentG a écrit :

Ouais, moi mes clés sont TOUJOURS des integer. Jamais de clé significative. Toujours un truc abstrait :) Parce qu'à chaque fois que j'ai eu le malheur de mettre autre chose, tôt ou tard c'était le bordel :/


 
 
 :jap:  
 
Honnêtement, après quelques déboires, je pense que c'est la meilleure façon de travailler :)
 
 
Si j'avais le courage, je ferais péter ces %*$" de references chantier alphanumériques..que j'ai mis en pk, il ya 5 ans :D


---------------
"Kattthyyyyy, r'garde comment je prends trop bien de l'angle sa mère !" - Sat08 2004
Reply

Marsh Posté le 07-03-2005 à 23:16:22    

Bah ça dépends ce que tu gères. Evidement, si c'est des infos volatiles, faut passer par une clé calculée. Mais si c'est quelquechose de fixe, ça sert à rien, mise à part alourdir.
 
Imagine, t'as un forum. Le login est unique, tu ne peux pas en changer. Ben utiliser un auto-incrément comme clé primaire (et donc comme FK) va t'oblier à faire des jointures à toutes les sauces pour afficher l'auteur de chaque post... C'est pas très malin étant donné que tu ne veux récupérer que son login.
 
C'est ni plus ni moins la solution adoptée par Joce lorsqu'il a codé ce forum. Comme tu vois, il marche plutôt bien, y'a pas de problème de perf. Pourtant, en 1999 quand j'ai découvert ce forum, et que Joce, très présent à l'époque, m'a expliqué comment il avait codé le forum, j'ai cru avoir une attaque. Force est de constater que ces choix (auxquels je n'adhère pas tous, encore maintenant) n'était pas mauvais, loin de là.

Reply

Marsh Posté le 07-03-2005 à 23:19:56    

Dans ce cas oui. Pour le login c'est compréhensible :jap:

Reply

Marsh Posté le 07-03-2005 à 23:24:48    

Sinon, j'ai travaillé pendant des mois (deux ans en fait) sur un ERP, dont un grand nombre de clés étaient aplhanumériques. Les pays ou les monnaies par exemple, faut être buté pour ne pas reprendre les codes alphanumériques ISO, qui sont parfaitement lisibles !
Et je peux t'assurer que ces données sont loin d'être les seules alpha-numériques. Même certaines informations, telles que le numéro client, même si elles suivent, selon leur type, différentes séquences (bah ouais, t'as l'air fin avec un auto-incrément quand tu dois gérer plusieurs plages à la fois), sont en réalité des varchar(12). Ce qui est bien pratique, c'est que si un client (type "CLI" ) sera en effet numérique (avec 0 facultitatifs, à nouveau, pas terrible quand tu te bases sur un champ entier), les dépots (qui sont gérés de la même façon que les clients) sont nommé par leur nom juridique (ça change pas tous les jours).
 
En tout cas, cet ERP bouffe plusieurs dizaine de milliers de ligne par jour en écriture, et plus de 1000 personnes l'utilisent simultanément, et personne se s'est jamais plaint ni de sa lenteur ni du bordel dans les données.
 
Evidement, les écrans permettant de créer des devises ou des dépôts sont fermés aux utilisateurs... Une clé alphanumérique, tu n'en fait que pour les données de référence évidement, pour le reste, c'est une clé calculées (et rien n'empêche d'en faire une variable alphanum... Quand tu reçois un bon de commande avec marqué "CDE0158032005", ça ressemble à tout sauf à un autonumber, et pourtant, personne n'a rien tapé pour générer cette clé)

Reply

Marsh Posté le 07-03-2005 à 23:26:11    

C'est bon à savoir tout ça :)

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed