【问题标题】:Inserting in two tables with a single query使用单个查询插入两个表
【发布时间】:2011-12-03 21:12:25
【问题描述】:

我正在使用 zend 框架开发一个 web 应用程序,问题是关于结合 2 个 sql 查询以提高效率。我的表结构是这样的

>table message
id(int auto incr)
body(varchar)
time(datetime)

>table message_map
id(int auto incr)
message_id(forgain key from message table's id column)
sender(int ) comment 'user id of sender'
receiver(int) comment 'user id of receiver'

为了使代码正常工作,我首先将消息正文和时间插入到消息表中,然后使用最后插入的 id,将消息发送者和接收者插入到 message_map 表中。现在我想做的是在单个查询中完成此任务,因为使用一个查询会更有效。有没有办法这样做。

【问题讨论】:

  • 如果这是关于一两个查询(而不是同时运行数千个),您可能在浪费时间尝试优化它。
  • 一个查询只是一个示例,实际上这将在一个循环中使用,可能数千次。我只是想学习优化整个代码的技巧。
  • 很公平。但是,我认为在这种情况下,没有办法使用两个查询。

标签: php mysql sql database zend-framework


【解决方案1】:

不,没有。您一次只能插入一个表格。

但我无法想象您需要插入这么多消息,以至于性能真的成为问题。即使使用这些单独的语句,任何数据库都可以轻松地在一分钟内插入数千条记录。

批量插入
当然,在同一个表中插入多条记录时,就另当别论了。这在 MySQL 中确实是可能的,它将使您的查询更快。但是,如果您需要从所有这些记录中插入_id,这会给您带来麻烦。

mysql_insert_id() 如果是批量插入,则返回最后插入语句中插入的第一个 id。所以你可以查询所有>=那个id的id。它应该为您提供刚刚插入的所有记录,尽管结果可能包含其他人在您的插入之间插入的 id 以及对这些 id 的以下查询。

【讨论】:

  • 在处理严肃的项目时,性能始终是一个问题。我正在努力寻找可以提高应用性能的所有方法。
  • @Sourabh 是的,使用单独的 INSERT 和 IGNORE 或 DELAYED 等选项(取决于您的代码)时性能会更好,因此您可以并行 INSERT 到两个不同的表中。
【解决方案2】:

如果它仅适用于这两个表。为什么不创建一个包含所有这些列的单个表

>table message
id(int auto incr)
body(varchar)
sender(int ) comment 'user id of sender'
receiver(int) comment 'user id of receiver'
time(datetime)

然后它就会像你想要的那样。

【讨论】:

  • 我不能这样做,如果我这样做,当用户将消息发送给多个接收者时,整个消息将被一次又一次地复制给每个接收者。
【解决方案3】:

我同意 GolezTrol 的观点,或者如果您希望优化查询性能,也许您可​​以选择使用存储过程

【讨论】:

    【解决方案4】:

    确实不可能将这两个插入结合起来。当您在获取查询中使用 JOIN 时,您不能组合插入查询。如果您真的担心性能,那么是否将这两个表连接在一起?据我所知,将它们分开是没有意义的。两者都关于消息。 如前所述,顺便说一句,执行第二个插入查询对服务器的负载并不大。

    【讨论】:

      【解决方案5】:

      正如其他人指出的那样,您不能真正一次更新多个表。而且,您不应该真正担心性能,除非您在短时间内插入数千条消息。

      现在,您需要担心一件事。想象一下,您首先插入消息正文,然后尝试插入接收者/发送者 ID。假设第一个成功,而第二个(无论出于何种原因)失败。那会稍微损坏您的数据。为避免这种情况,您可以使用事务,例如

      mysql_query("START TRANSACTION", $connection);
      //your code
      mysql_query("COMMIT", $connection);
      

      这将确保两个插入都进入数据库,或者两者都不进入。如果您使用的是 PDO,请查看 http://www.php.net/manual/en/pdo.begintransaction.php 的示例。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-01
        • 1970-01-01
        • 2016-08-04
        • 2019-04-19
        • 1970-01-01
        • 2015-06-16
        相关资源
        最近更新 更多