CHECK约束在MySQL中不起作用。

24 浏览
0 Comments

CHECK约束在MySQL中不起作用。

首先,我创建了一个类似于下面的表格:

CREATE TABLE Customer (
  SD integer CHECK (SD > 0),
  Last_Name varchar (30),
  First_Name varchar(30)
);

然后,在该表格中插入了一些数值:

INSERT INTO Customer values ('-2','abc','zz');

MySQL并未显示错误信息,而是接受了这些数值。

0
0 Comments

MySQL中的CHECK约束不起作用的原因是因为在文档中的一个微小注释中解释了这一点:CREATE TABLE

CHECK子句被所有存储引擎解析但被忽略。

:是的,在其他正确实现CHECK约束的数据库管理系统中,如果CHECK评估为FALSE,则插入(或更新)操作将不会执行,并会引发错误。

MariaDB中已经修复了这个问题(参见这个回答stackoverflow.com/a/44333349)。

Jerome,我知道,我还有一些(更近期的)答案,包括在这个领域的改进(在MariaDB和MySQL之前,有其他方法来解决这个问题,但MariaDB在正确实现CHECK约束之前)。我不确定是否应该去编辑我所有的旧答案!

我想我的评论中附上一个链接到一个更近期的答案是可以的。或者总比没有好。也许我应该去编辑一下。我并不是要逼你做任何事情。

0
0 Comments

MySQL 8.0.16是首个支持CHECK约束的版本。在MySQL 8.0.15或更早的版本中,CHECK子句被解析但被所有存储引擎忽略。因此,如果想要在MySQL中使用CHECK约束,可以尝试使用触发器来实现。

以下是一个创建触发器的示例:

mysql> delimiter //
mysql> CREATE TRIGGER trig_sd_check BEFORE INSERT ON Customer 
    -> FOR EACH ROW 
    -> BEGIN 
    -> IF NEW.SD<0 THEN 
    -> SET NEW.SD=0; 
    -> END IF; 
    -> END
    -> //
mysql> delimiter ;

如果想要触发错误而不是忽略CHECK约束,可以参考stackoverflow.com/a/7189396/1144966中的方法。

总之,MySQL之所以不支持CHECK约束,是因为早期版本的MySQL解析CHECK子句时会忽略它们,而不会执行约束检查。这也是为什么在有选择的情况下,我会始终选择使用PostgreSQL而不是MySQL的原因之一。希望MySQL能够在解析器遇到CHECK约束时发出警告,这样开发过程会更加简单明了。

0