【问题标题】:How to assure equal update on 2 tables simultaneously on MySQL如何确保在 MySQL 中同时对 2 个表进行同等更新
【发布时间】:2018-04-08 08:12:52
【问题描述】:

我有一个我无法解决的问题。我正在尝试用相同的数据更新 2 个不同的表,但我总是会出现差异

我有 2 张桌子:usersstats

users结构:

id: int(25)
balance: decimal(18,6)

stats 结构:

date: date
userid: int(25)
balance: decimal(18,6)

我正在使用 innodb 事务来更新表,如下所示:

    mysql_query("BEGIN TRANSACTION");

    $result1 = mysql_query("INSERT INTO users(id, balance)
        VALUES ".$balance." 
        ON DUPLICATE KEY UPDATE balance = balance + VALUES(balance)");


    $result2 = mysql_query("INSERT INTO pubday (date, userid, balance) 
        VALUES ".$balance."
        ON DUPLICATE KEY UPDATE balance=balence+VALUES(balance)");



if($result1 === false || $result2 === false) {
mysql_query("ROLLBACK");
}else{
mysql_query("COMMIT");
}

我每天至少更新表格 500 万次。不管怎样,我总是在usersstats 的余额之间得到一个微小的差异:

SELECT sum(balance) from stats

SELECT balance from users

例如,我在统计数据上得到 balance=302.001731,在用户上得到 balance=302.194501。应该是一样的。

我的问题是这里的错误是什么或者我做错了什么?或者解决这个问题的最佳方法是什么?用相同的数据同时更新 2 个表。

【问题讨论】:

  • 您正在使用不受支持的“mysql_”函数并且您关心数据完整性?
  • .... 那和裸字符串连接。注意 SQL 注入!
  • 我正在使用 PDO,我只是这样写以使示例简单

标签: php mysql sql normalization data-integrity


【解决方案1】:

答案很简单:不要拥有多个权限点。如果两列应该相同,将它们设为同一列。我会删除 stats.balance,并在您需要时通过 SQL 即时计算统计信息。

毕竟,即席查询是关系数据库管理系统 (RDBMS) 在 1970 年代最初研究的核心原因之一。

与此同时,您似乎想要某种“物化视图”,以便您可以显示过去的数据。如果是这种情况,请考虑将 每个 事务保存一段时间,然后根据 SQL 计算定期插入到 stats 表中。比如:

INSERT INTO stats (date, userid, balance)
  SELECT CURDATE(), id, SUM(balance) FROM users GROUP BY 1, 2;

并且可能,根据您的需要,通过 ON DUPLICATE KEY UPDATE 使用 UPSERT。

显然,SUM(balance) 不完整或不正确,但在您更新架构之后,求和的概念才是重点。

【讨论】:

  • 非常感谢您的回答。仅作为背景,这是针对广告网络的。你的回答很有道理。我们需要显示收益的历史数据,我们还需要显示余额。我们可以按照您的说法进行制作,并且拥有单一的事实来源。假设我们将统计数据视为唯一的表。然后余额将是所有收入的总和。但是我需要计算每次印象的余额。此操作不如从表用户中选择余额作为单个数字那样高效。请记住,我们每天有 500 万以上的展示次数和 50k 以上的用户。我应该如何处理这个问题?
  • 在某些时候,鉴于您的限制,您需要平衡性能、正确性和最新性。建议一些类似 cron 的作业来经常更新物化视图,或者简单地使用缓存值,或者仅基于新行结合物化视图的输出来计算加法 - 使用适当的索引。一些基本的数学运算:每天 4 个活跃小时内的 1000 万次观看(高估)是每秒约 700 次观看。鉴于强大的服务器、巧妙的逻辑准备和组织(例如,物化视图)和缓存,这在 ~2006 年的硬件上很容易实现。现在是 2017 年。
猜你喜欢
  • 1970-01-01
  • 2018-12-29
  • 1970-01-01
  • 2018-06-25
  • 2012-08-19
  • 1970-01-01
  • 1970-01-01
  • 2016-11-01
  • 1970-01-01
相关资源
最近更新 更多