2011-05-24 2 views
1

J'ai un site drupal qui utilise des champs de contenu CCK pour stocker la majorité de ses données.Comment mettre à jour une partie d'une clé primaire composite?

Je souhaite modifier manuellement certaines données pour pointer vers une version de noeud différente.

UPDATE content_field_table SET vid = '1234' WHERE nid = '12' AND vid = '123'; 

Le problème est que content_field_table a une clé primaire composite de

PRIMARY KEY (`vid`,`delta`) 

Alors que quand je lance la déclaration de mise à jour, je reçois l'erreur suivante:

Code d'erreur: 1062 en double entrée '52979-0' pour la clé 'PRIMARY'

Comment puis-je mettre à jour la vid si nécessaire?

Répondre

4

Une clé primaire doit être unique. Par exemple, si vous obtenez des enregistrements du SQL ci-dessous, la mise à jour que vous souhaitez effectuer ne peut pas être effectuée. Par exemple, si vous obtenez des enregistrements du code SQL ci-dessous, vous ne pouvez pas modifier un enregistrement. Vous devez soit effectuer d'autres modifications en premier, soit supprimer un enregistrement, soit supprimer le fichier PK

SELECT SOURCE.delta, 
     SOURCE.vid, 
     TARGET.delta, 
     TARGET.vid 
FROM content_field_table SOURCE 
     INNER JOIN content_field_table TARGET 
     ON SOURCE.delta = TARGET.delta 
WHERE SOURCE.vid = '123' 
     AND TARGET.vid = '1234' 
+1

Cela m'a pointé dans la bonne direction. J'ai trouvé qu'il y avait un enregistrement qui est entré en collision dans les rangées, mais je n'avais pas vérifié correctement la partie delta du PK. – fafnirbcrow

2

Ne modifiez pas vos clés primaires. N'utilisez pas non plus de clés primaires composées lorsque cela est possible. MySQL (et d'autres bases de données) stockent les enregistrements dans les pages dans l'ordre PK. MySQL remplira chaque page 15/16 avant d'allouer de l'espace pour une nouvelle page, et d'y insérer plus de données.

Le problème avec les PK composés ou modifier votre PK est la fragmentation. Je ne parle pas de fragmentation de disque, je veux dire de fragmentation d'index. Lorsque le PK se déplace, les données doivent être mélangées autour du disque pour le garder dans le bon ordre. Selon l'ensemble de données, MySQL peut devoir déplacer de nombreuses lignes physiques pour cela.

La même chose vaut pour la mise à jour de votre PK. La modification du PK modifie l'ordre sur le disque et nécessite le déplacement de nombreuses lignes. Si possible, utilisez un PK auto-incrémenté, ou n'utilisez pas PK et laissez MySQL créer un PK interne pour vous.

Ce que vous voulez, c'est que de nouvelles lignes soient ajoutées à la dernière page libre sur le disque, ce qui est rapide et bon marché.

+0

Vous avez raison: les PK modifiables sont une mauvaise idée, mais si vous pardonnez certaines petites choses. Les bases de données stockent généralement les données dans l'ordre Clustered Index. Il est vrai que les PK sont souvent aussi l'index cluster, mais ils ne doivent pas l'être. Il y a aussi des scénarios où une perte de perf sur 'INSERT' ou' UPDATE' peut être un compromis raisonnable pour 'SELECT' donc ce n'est pas toujours le cas si la nouvelle vitesse de ligne doit être optimisée –

+0

Je pense à la branche MySQL 5.x les index clusterisés doivent être des PK. Je pense que pour SELECT trafic lourd, cela peut être un compromis précieux comme vous le dites. – FoneyOp

+0

Oui, vous avez raison à propos de MySQL donc +1. Les [docs say] (http://dev.mysql.com/doc/refman/5.0/en/innodb-index-types.html) si vous définissez un PK, ce sera l'index clusterisé. –

Questions connexes