今天朋友问mysql的update set的内容是否有顺序问题

我想,数据库更新应该是拿出该数据的快照,根据快照数据做更新,本着这个思路,我们来看看那么mysql是如何工作的,同时我们还好奇的测试了sql server和oracle。

业务语句
update1

我们调整了set后面的顺序
udpate2

可以看到va_raito是不同的,也就是说mysql的update是有顺序的

我们找到了mysql的官方手册,里面也有详细的说明,跟我们想象的不同

官方说明

借用一个开发的思路:这就好像程序里面评估表达式的值一样吧,从左往右进行。看似很说的通哈,但是不知道DBA们是否能接受,反正我是不太接受:)

DBA更多的考虑数据ACID,那么我们来看看,是否是因为事物隔离级别导致

当前的事物隔离级别是:REPEATABLE-READ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
mysql> SELECT @@GLOBAL.tx_isolation;
+-----------------------+
| @@GLOBAL.tx_isolation |
+-----------------------+
| REPEATABLE-READ |
+-----------------------+
1 row in set (0.00 sec)
mysql> create table t3 (a int ,b int);
Query OK, 0 rows affected (0.00 sec)
mysql> insert into t3 values (1,2);
Query OK, 1 row affected (0.01 sec)
mysql> update t3 set a=a+10,b=a;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from t3;
+------+------+
| a | b |
+------+------+
| 11 | 11 |
+------+------+
1 row in set (0.00 sec)

修改为:READ-UNCOMMITTED

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
mysql> SELECT @@GLOBAL.tx_isolation;
+-----------------------+
| @@GLOBAL.tx_isolation |
+-----------------------+
| READ-UNCOMMITTED |
+-----------------------+
1 row in set (0.00 sec)
mysql> create table t3 (a int ,b int);
Query OK, 0 rows affected (0.02 sec)
mysql> insert into t3 values (1,2);
Query OK, 1 row affected (0.01 sec)
mysql> update t3 set a=a+10,b=a;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from t3;
+------+------+
| a | b |
+------+------+
| 11 | 11 |
+------+------+
1 row in set (0.00 sec)

通过以上测试我们可以看到,这个问题属于update语法问题,无论是从update官方手册说明,还是事物隔离级别测试,都表明update set顺序不受其他配置影响。

那么,我们来看看sql server和oracle

sql server
mssql1
mssql2

oracle

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
SQL> create table t1(a int ,b int);
Table created.
SQL> insert into t1 values(1,2);
1 row created.
SQL> commit;
Commit complete.
SQL> update t1 set a=a+10,b=a;
1 row updated.
SQL> select * from t1;
A B
---------- ----------
11 1

两个商业软件和我们想的一致,唯有mysql产生了幻读,所以我们可以说它是一个小坑,也可以说它是一个讨巧。开发用好了会很方便,用不好数据就改错了,小心为上。