基于现有值随机化主键

时间:2012-12-28 01:00:24

标签: mysql sql shuffle

我有一个较旧的数据库(在某些非常可疑和模糊的原因,我不喜欢在这里放置太多主题)我想随机化或随机播放主键。

我现在在Mysql数据库表中有自动增量字段。

我没有太多关系,那些存在的关系没有被定义为外键。这些关系不需要保留。

我正在寻找的是获取主键的当前值,并将其替换为以下值中的随机值:

ID := new(ID)

新函数从具有1:1匹配的所有OLD ID的集合返回值。 E.g。

2 := 3
3 := 2

但不是

2 := 3
3 := 3

有没有办法用(理想情况下)每个表的一个SQL查询来更改数据库中的数据?

编辑:我没有非常严格的要求。如果有帮助,可以考虑对数据库进行独占访问,包括来回更改主键的约束,例如:更改表,执行操作,将表更改为以前的模式。也可以为新(或旧)PK值添加另一列。

3 个答案:

答案 0 :(得分:5)

只是程序的一个方面。创建两个临时表

CREATE TABLE temp_old
( ai INT NOT NULL AUTO_INCREMENT
, id INT NOT NULL
, PRIMARY KEY (ai)
, INDEX old_idx (id, ai)
) ENGINE = InnoDB ;

CREATE TABLE temp_new
( ai INT NOT NULL AUTO_INCREMENT
, id INT NOT NULL
, PRIMARY KEY (ai)
, INDEX new_idx (id, ai)
) ENGINE = InnoDB ;

将不同顺序的id值复制到两个表中(在第二个表中随机):

INSERT INTO temp_old
  (id)
SELECT id
FROM tableX 
ORDER BY id ;

INSERT INTO temp_new
  (id)
SELECT id
FROM tableX 
ORDER BY RAND() ;

然后我们放弃主键:

ALTER TABLE tableX
  DROP PRIMARY KEY ; 

运行实际的UPDATE语句:

UPDATE tableX AS t
  JOIN temp_old AS o
    ON o.id = t.id
  JOIN temp_new AS n
    ON n.ai = o.ai
SET t.id = n.id ;

然后重新创建主键并删除临时表:

ALTER TABLE tableX
  ADD PRIMARY KEY (id) ; 

DROP TABLE temp_old ;
DROP TABLE temp_new ;

SQL-Fiddle

中进行测试

答案 1 :(得分:3)

这是一种按表顺序创建id列表的技术,以及1中的序号,它还以随机顺序创建id列表,以及1中的序号。然后更新ids基于匹配序号。

rand()的顺序性能存在问题,(并且它是随机的)。

如果您的密钥已从1开始按顺序排列,则可以简化此操作。

Update
  Test as t
    Inner Join (
    Select 
      @rownum2 := @rownum2 + 1 as rank,
      t2.id
    From
      Test t2,
      (Select @rownum2:= 0) a1
  ) as o on t.id = o.id
    Inner Join (
      Select
        @rownum := @rownum + 1 as rank,
        t3.id
      From
        (Select id from Test order by Rand()) t3,
        (Select @rownum:= 0) a2
  ) as n on o.rank = n.rank
Set
  t.id = n.id

http://sqlfiddle.com/#!2/3f354/1

答案 2 :(得分:1)

您可以创建一个存储过程来创建一个包含所有id的临时表,然后您可以遍历每个记录,用临时表中的id替换id,然后从临时表中删除该id。我不相信有一种方法可以在一个查询中执行您所说的内容。