mysql - 如何随机化单个 mysql 列?

标签 mysql random

我有一个由字符串和数字概率组成的数据库(还有其他列,但它们与问题无关)。简化的架构是

+-----------------------+----------------------+
| gopair                | P_high               |
+-----------------------+----------------------+
| GO:0000398_GO:0030540 |    0.275997567007171 |
| GO:0015198_GO:0016846 | 5.24489289777325e-06 |
| GO:0034649_GO:0072141 |  0.00338367340340417 |
| GO:0004303_GO:0031053 |    0.110417921058026 |
+-----------------------+----------------------+

在我的工作中,我运行一个脚本来查询数据库以获取与特定 GO 对关联的值。我需要证明我的结果与随机获得的结果不同。因此,我想要运行的测试之一是打乱 P_high 列,然后运行我的脚本并分析结果。

我尝试过打乱输入文件并重新加载数据库,但这很复杂,因为有问题的输入文件是一个 7GB 的文本文件,在只有 3GB RAM 的机器上很难处理。

那么,有没有一种方法可以随机化数据库中的特定列,同时保持其余列静态?

注意事项:

  • 相关表很大(60,164,966 行)。
  • 我不需要严格的数学随机性
  • 我需要保持相同的频率。如果在真实数据库中 N 对的概率为 P,我需要 N 对的概率为 P> 在随机的一个中。
  • 我需要持久的解决方案。我的脚本可以多次查询数据库中的同一对,因此简单地选择随机对是不够的。
  • 我需要重复执行所有这些操作,因此首选可编写脚本(最好是 Perl)的解决方案。
  • 我正在 Ubuntu 服务器上使用 readline 6.1 运行 mysql Ver 14.14 Distrib 5.1.41,适用于 debian-linux-gnu (x86_64)。

最佳答案

该表的主键是什么样的?如果您使用整数代理键,您可以:[假设 4 字节整数]

  1. 转储所有键的列表。 $list[] [240MB 给予或接受]
  2. 复制列表。 $shuf[] [另外 240MB +/-]
  3. 打乱重复列表。 [shuffle 函数可能会返回一个副本,在这种情况下跳过 #2]
  4. 向表中添加另一列[即:shuffle_key],暂时没有索引。
  5. 我不太熟悉 Perl 语法,但它与 PHP 类似,所以:

    $cnt = count($list);
    for($i=0; $i<$cnt; $i++) {
        $query = sprintf(
            'UPDATE table SET shuffle_key = %d WHERE primary_key = %d',
            $shuf[$i], $list[$i] );
        $dbh->doQuery($query);
    }
    
  6. 在新列上创建 UNIQUE 索引。

  7. 现在,您可以在主键和混洗键上自连接表,并使用一侧的 gopair 和另一侧的 P_high。

    SELECT t1.gopair, t2.P_high
    FROM table t1 INNER JOIN table t2
      ON t1.primary_key = t2.shuffle_key
    

这需要的内存量大约是主键大小 * 行数的 2 倍,但即使在较大的一侧,我也认为它占用的内存不会超过几 GB。

注意:每次您想要打乱索引时,您需要将索引删除到 shuffle_index 列上,这样您就不会在操作过程中收到重复的键警告。之后重新添加索引。

关于mysql - 如何随机化单个 mysql 列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14485636/

相关文章:

MySQL评论表结构问题

php - 当模型具有数据库中不存在的脏属性时, Eloquent 更新方法会抛出错误

javascript - 将 JavaScript 值传递给 PHP 或其他 PHP 类 (codeigniter)

php - Url() 基于产品选择

MySQL 全文搜索主题标签(包括索引中的 # 符号)

visual-studio - 我的 Visual Studio 自动递增内部版本号语法有什么问题?

mysql - 从数组返回随机的mysql函数?

c - 生成 8 位唯一随机数

unit-testing - 使用随机输出测试函数

c++ - 在具有特定均值的 2 个数字之间获取一组随机数。