如何更新复合主键的一部分?

时间:2011-05-24 15:05:25

标签: php mysql drupal

我有一个drupal站点,它使用CCK内容字段来存储大部分数据。

我想手动更改某些数据以指向不同的节点版本。

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

问题是content_field_table的复合主键为

PRIMARY KEY (`vid`,`delta`)

因此,当我运行update语句时,我收到以下错误:

错误代码:1062 密钥'PRIMARY'重复输入'52979-0'

如何根据需要更新视频?

2 个答案:

答案 0 :(得分:4)

主键必须是唯一的。因此,您无法将一条记录更改为与现有记录具有相同的PK

例如,如果您从下面的SQL获得任何记录,则无法完成您要执行的更新。您需要先进行其他更改或删除记录或删除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 :(得分:2)

请勿更改主键。也尽量不要使用复合主键。 MySQL(和其他数据库)以PK顺序将记录存储在页面中。在为新页面分配空间并在那里插入更多数据之前,MySQL会将每个页面填满15/16。

复合PK的问题或改变你的PK是碎片。我不是说磁盘碎片我的意思是索引碎片。随着PK的移动,数据必须在磁盘周围进行混洗以使其保持正确的顺序。根据数据集,MySQL可能需要移动许多物理行来执行此操作。

更新PK也是如此。更改PK会更改磁盘上的顺序,并且需要移动许多行。如果可能的话,使用自动递增PK,或者不使用PK,让MySQL为你创建一个内部PK。

你想要的是将新行附加到磁盘上的最后一个免费页面,这是快速而便宜的。