【问题标题】:Is this correct to write sql query inside loop在循环内编写sql查询是否正确
【发布时间】:2018-04-17 06:16:13
【问题描述】:

假设数据库中有大约 200,000 条记录。 这里 do-while 最多可以执行 200,000 次。这意味着它将调用 DB 200,000 次。

我的问题:这是正确的方法吗?有没有更好的办法?

function get_new_key() {
    do {
        $new_key = 'some_xyz';
    } while ( function_call_to_check_newKey_exists_in_db );

    return $new_key;
}

【问题讨论】:

  • 为什么你使用循环来检查数据库中是否存在新键?你的逻辑的实时场景是什么?
  • 并非如此,它的效率非常低;但是如果没有更多关于你真正想要做什么的信息,很难建议你应该采取什么方法......例如new_key 是从哪里来的?
  • 在循环中调用 db 操作几乎永远不会有效。也许使用UUID 创建ID? php.net/manual/en/function.uniqid.php
  • 这里新密钥的意思是:$new_key = hash('sha256', time() . mt_rand()); (PHP 代码)
  • 如果你的 MySQL 表中的键列设置为唯一,你会得到一个重复的错误,你可以像 if (mysqli_errno() == 1062) { // generate new key } 那样处理它,我希望你使用像 stackoverflow.com/a/31460273/342740 这样的东西来生成您的随机密钥或类似的安全但独特的方法。您需要多少次重新生成密钥取决于生成密钥的算法有多好/独特/安全。

标签: php sql


【解决方案1】:

选项 1) 使用代理键。自然键有其用途,但代理键有很多好处,其中之一是灵活的。 Som sql-servers 可能会生成非顺序的自动生成的代理键。

选项 2) 使用 http://php.net/manual/en/function.uniqid.php 并相信尝试和捕获方案。

总体而言,由于您要抽取 200.000 条记录(?),您最好将它们放在文本文件中并在 db 中使用导入功能。

【讨论】:

    【解决方案2】:

    您最好确定new_key 是如何生成的。如果没有这些信息,您将无能为力。

    例如,如果它是一个递增的数字,那么最好选择MAX(columnkey)+1(锁定表以防止冲突),或者更好的是,将其声明为 PRIMARY KEY AUTO_INCREMENT 并插入 NULL 值钥匙。这将自动设置密钥。使用LAST_INSERT_ID() 恢复其价值:

    INSERT INTO ... (all columns except key) VALUES (all values)
    SELECT LAST_INSERT_ID() AS newkey;
    

    或者您可以使用足够粒度的时间戳。

    如果您想避免编号中的“漏洞”(不一定是不好的做法,但请有一个比“看起来更好”更好的理由!),您可以@987654324 @ 表自身,条件是右侧的表 ID 比左侧大一。右侧为 NULL 的那些行表明它们的对应 ID 可用(再次锁定表 - 在这种情况下,使用 MySQL,锁定两次):

    -- You need an index on mykey
    SELECT a.mykey+1 AS available 
        FROM mytable AS a 
        LEFT JOIN mytable AS b ON (a.mykey+1 = b.mykey)
        WHERE b.mykey IS NULL
        ORDER BY a.mykey LIMIT 20
    

    【讨论】:

      猜你喜欢
      • 2015-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-24
      • 1970-01-01
      • 2014-04-17
      • 2015-11-07
      • 1970-01-01
      相关资源
      最近更新 更多