修改MySQL中十进制键表的最快方法?

时间:2010-05-08 00:29:23

标签: mysql database algorithm primary-key

我正在处理一个MySQL表,这个表有点不幸。它不使用自动增量表作为键,而是使用一列小数来保持顺序(可能因此在保留主键和顺序时插入新行并不太难)。

在我完成并重新使用此表之前,我需要弄清楚如何在不破坏所有内容的情况下重新设置它。

我想要做的是获取双精度列表(当前键)并输出整数列表(可以将其转换为双精度值以进行重新键入)。

例如,输入{1.00,2.00,2.50,2.60,3.00}将输出{1,2,3,4,5}。

由于这是一个数据库,我还需要能够很好地更新行:

UPDATE table SET `key`='3.00' WHERE `key`='2.50';

有人能想到一个快速的算法吗?我目前的想法是将所有双打读入一个向量,取矢量的大小,并输出一个值为1 => doubleVector.size的新向量。这看起来很慢,因为例如,如果只需要修改最后n/100个元素,则不希望将每个值都读入向量。

我认为可能有一些我可以做到的事情,因为只有第一个非整数双精度值之后的值才需要修改,但我不能为我的生活找到任何可以让我更新到位的东西同样。例如,第一次在原始密钥列表中看到2.50时设置2.60到3.00将导致错误,因为密钥值3.00已用于表。


编辑:我猜这真正抽象的是:

我需要一种方法将一个用双精度键入的有序地图转换成一个用整数键入的有序地图,其中一个键的任何位置都不存在两个值(无论如何都违反了地图)。

2 个答案:

答案 0 :(得分:3)

我假设您可以在某个时候关闭数据库以进行此转换。

注意:我不是MySQL用户。我选择的数据库是PostgreSQL,因此在MySQL和Pg​​之间可能存在语法错误。但这应该会给你一个好主意。

首先,创建一个将旧键映射到new的键映射表:

create table keymap (
    oldkey decimal,
    newkey integer autoincrement
)

确保索引keymap,因为我们将在其上进行大量查找。

create unique index keymap_oldkey on keymap(oldkey);

然后用旧密钥填充它,让MySQL创建新密钥:

insert into keymap
    select distinct `key` from fribbles order by `key`

现在你将拥有包含所有旧密钥的keymap,并且因为你没有指定一个新密钥,你将会填充newkey列上的自动增量,并且你的表将会是这样的。

oldkey    newkey
----------------
1.5       1
1.6       2
1.93      3
3.1       4

现在,在需要它的表中添加一个newkey列

alter table fribbles add column newkey integer

不要让它自动增量,否则它会在alter时填充,我们不需要它。

现在,最后,更新fribbles表:

update fribbles f
    set newkey = ( select newkey from keymap m where m.oldkey = f.`key` )

最后,现在您已经填充了新密钥,您可以删除旧密钥。

alter table fribbles drop column `key`;
alter table fribbles alter column newkey rename to `key`;

我希望这会给你一个体面的攻击计划。

答案 1 :(得分:1)

我只是将一个int列(允许NULL值)添加到表中,然后执行基于游标或代码的运行,我按原始的whacked-out双PK列进行排序,然后遍历写入的记录将值递增到新的int列中。然后通过将PK更改为新的int列并删除旧的PK来更新表。

“这里”,正如他们在法国所说的那样。