MySQL 的傻逼之处真是罄竹难书。
再一次印证,产品的好坏和成功与否是两个维度。
具体而言,弱类型允许瞎转换用户数据类型、时间类型字面量规则复杂模糊且不合理、行为不一致、该细致的地方含糊、该简单的地方弄复杂。
举两个最近被恶心的很厉害的例子。
第一个是关于 time 函数的。
select time("10:11:1212");select time("-1? 10:11:12");
猜猜上面两句 SQL 在 MySQL 里面执行的结果是啥?
从正常人的脑回路来看,第一个应该报错吧?10 小时 11 分 1212 秒不应该是个正确的时间长度。如果第一个不报错,那第二个肯定要报错吧?
答案是,这两个都只会报 warning,而结果是
mysql> select time("10:11:1212");+--------------------+| time("10:11:1212") |+--------------------+| NULL |+--------------------+1 row in set, 1 warning (0.00 sec)mysql> select time("-1? 10:11:12");+----------------------+| time("-1? 10:11:12") |+----------------------+| -00:00:01 |+----------------------+1 row in set, 1 warning (0.00 sec)
惊喜不惊喜?
MySQL 这样搞的原因我大概是理解的,希望尽量容忍用户犯错,但这种定义不清楚、结果不合理的行为最大的问题是有可能造成严重的数据错误。
此外,这个 time 函数还支持 time(201010) 这种形式,意思是 20:10:10,注意传入的是 int 字面量。
MySQL 文档中提到:
MySQL interprets abbreviated TIME values with colons as time of the day. That is, '11:12' means '11:12:00', not '00:11:12'. [...] you might think of '1112' and 1112 as meaning '11:12:00' (12 minutes after 11 o'clock), but MySQL interprets them as '00:11:12' (11 minutes, 12 seconds). Similarly, '12' and 12 are interpreted as '00:00:12'.
https://dev.mysql.com/doc/refman/5.7/en/time.html
这种无节制的纵容输入格式,已经让 time 相关的函数实现复杂度爆炸了。感兴趣可以看看 tidb 为了在这方面和 MySQL 兼容所堆出来的屎山(很荣幸我在屎山上捏着鼻子加了不少屎)。
如果说上面这个例子还算能接受,下面来个更劲爆的。
create table t2 (a year(4));insert into t2 values(2020);select * from t2 where a <= 69;
猜猜上面语句执行结果呗?
显然表中只有一行 2020。2020 比 69 大,所以应该返回空集对吧。
然而 MySQL 执行结果如下:
mysql> select * from t2 where a <= 69;+------+| a |+------+| 2020 |+------+1 row in set (0.00 sec)
如果你没仔细看过 MySQL 文档,肯定想不明白。
当然我是看过的,原因在于,对于 YEAR 类型 MySQL 会把整形的 70~99 理解为 1970~1999、把 1~69 理解为 2001~2069,那 0 是什么意思呢?0 是 0000,一个不合法的值……如果你要插入 2000,请用字符串 "00"。
我吐了。
如果你捏着鼻子读完冗长的文档,在其中找到了这一条,恭喜你,学到了毫无用处的一点也不合理的规则。
如果说,MySQL 行为和文档一致也就算了。
上述是一个 YEAR 类型的列和 int 常量比较,那么当 int 常量落入 MySQL 文档所描述的范围内被默认按规则理解成其他值也就算了。
但是如果拿一个 YEAR 类型列和 INT 类型列做比较,那么上述规则就完全不起作用。
create table t3 (y year, a int);insert into t3 values (2020, 69);select * from t3 where y <= a;
结果是空集。
MySQL,我 xxxx。
MySQL 之于数据库,就像微信之于 IM 软件,简而言之就是“阴间玩意儿”。
我最近开始对 Postgres 这种阳间数据库产生了兴趣,扒下代码大概看了下,代码结构、里面的 readme 水平,比 MySQL 不知道高到哪里去了。看了些网上对 Postgres 和 MySQL 的对比,几乎一边倒吐槽 MySQL,而 Postgres 则很少看到负面评价。
产品设计是个大学问,数据库产品也是产品,而且是 mission critical 的产品。
希望人间多些阳间产品、少些阴间玩意儿。
逃(




