MYSQL-从“自己”中选择可能吗?

时间:2019-05-25 16:27:17

标签: mysql select xampp

我刚开始使用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>

谢谢。

2 个答案:

答案 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花费了多长时间-我预计在接下来的十年中不会允许任何子查询。

所以我想说-您的选择是:

  • 在触发器中实施支票
  • 在应用程序代码中实施支票
  • 更改要求

我希望最后一个。