MySQL查询语句冲突
考虑以下MySQL表,让我们将其命名为MySQL查询语句冲突,mysql,Mysql,考虑以下MySQL表,让我们将其命名为MyTable: ------------------- | Id | AssignedTo | ------------------- | 1 | NULL | | 2 | NULL | | 3 | NULL | ------------------- 假设我有一个脚本,它在被访问时执行以下查询: UPDATE MyTable SET AssignedTo = '@userid' WHERE AssignedTo
MyTable
:
-------------------
| Id | AssignedTo |
-------------------
| 1 | NULL |
| 2 | NULL |
| 3 | NULL |
-------------------
假设我有一个脚本,它在被访问时执行以下查询:
UPDATE MyTable SET AssignedTo = '@userid' WHERE AssignedTo IS NULL LIMIT 1
脚本的目的是从特定表中为用户分配一个id。如果两个不同的用户在同一时间调用上述脚本,其中一个仍然没有分配ID,因为两个MySQL语句相互覆盖,这是否有可能?即使它不是在同一时间运行,该查询本身并不保证所有未分配的行都将被分配。它明确地将自身限制为仅更新一行 如果在任何情况下,您在任何给定时刻都有多行
assignedTo为空
,您将只分配其中一行(任意选择)
仅基于您在此处显示的一个查询,没有明显的解决方案。删除限制1
并分配所有未分配行是否合适?这意味着如果两个人同时更新,其中一个人(任意)将被分配到所有行。那可能不好
更好的解决方案是首先考虑将那些NULL
s写入数据库时发生的情况,或者使用一些其他逻辑来显式选择要分配的未分配行,而不仅仅是“WHERE AssignedTo IS NULL”
如果两个不同的用户在同一时间调用上述脚本,其中一个脚本可能会因为两个MySQL语句相互覆盖而没有指定ID吗
不会。SQL中的单个查询由服务器执行,就像它们被序列化一样:就像一个查询在下一个查询开始之前完成一样
但是要注意:如果使用LIMIT
而不使用orderby
,则SQL选择的行是不可预测的。它选择它想要的任何一行。“不可预测”与“随机”类似,但更糟糕的是:“随机”通常意味着它每次都可能选择不同的行。SQL世界中的不可预测性意味着它每次都选择同一行,直到应用程序投入生产后不到一年
还要注意:如果没有任何行保留
NULL
值,则问题中的SQL将不会自动执行任何操作。可能重复“如果在任何情况下,您有多行assignedTo在任何给定时刻为NULL,您将只分配其中一行(任意选择)。”这是预期的行为。如果有多行未分配,请为用户调用脚本分配一行。