我刚开始使用mysql,但不知道进行检查的方法是否正确,或者我走错了方向。
我在表中有一个名为user_num的varchar。并且我需要检查一下,当我插入时,user_num_list的值必须介于[1,n]之间,即“ n”具有相同组的对象的定量范围具有新的对象。
我不是说英语,并且我确定这很难理解,而且对于我来说,这是我要表达的,所以有一些代码:
create table player(
group varchar(15),
user_num int(15),
CONSTRAINT ck_player_user CHECK( user_num > 0 AND user_num < SELECT count(*) FROM player WHERE player.group=group)
)ENGINE=InnoDB;
我不知道我是否可以在CHECK语句中“选择”,而且我也不知道如何表达“ player.group = group”,这意味着组(新INSERT player_group)必须与player.group相同/ p>
谢谢。
答案 0 :(得分:0)
你不走运。
首先,MySQL在版本8.0.16之前不验证CHECK约束。如果您使用的MySQL版本早于此版本,则MySQL将记录CHECK约束,并静默忽略它
第二,为了强制执行此约束,您将需要在其中使用子查询,而MySQL不允许子查询作为CHECK
约束的一部分。看到13.1.20.7 CHECK Constraints字面意思是:
- 不允许子查询。
答案 1 :(得分:0)
CHECK条件下的子查询存在的问题是,实际上无法实现。请考虑删除该表中的行时会发生什么。相应组的计数将减少,这可能违反另一行的CHECK约束。系统将需要重新评估每行的检查。如果现在表中有一百万行,则每次插入,删除或更新一行时都需要执行一百万个查询。如果您还允许使用交叉表语句,则对数据的任何更改都需要重新评估数据库中的所有检查。
从理论上讲,有可能产生“反向检查”。系统将需要确定哪些操作可能违反检查。在您的情况下,这将是删除行或更新组。 “反向检查”可能是
NOT EXISTS (
SELECT *
FROM player p
WHERE p.group = OLD.group
AND p.user_num > (SELECT COUNT(*) from player p WHERE p.group = OLD.group)
)
我想您会同意,这将很难实施一个能够生成这样的反向检查的系统。查询可能比您的查询复杂得多。对于某些查询,甚至可能不存在反向检查。如果您看看implement the CHECK constraint花费了多长时间-我预计在接下来的十年中不会允许任何子查询。
所以我想说-您的选择是:
我希望最后一个。