MySQL中是否支持创建引用关联外键表数据的CHECK约束?
问题说明
你最初的写法无法直接执行的核心原因是:MySQL的CHECK约束不支持子查询,也不允许引用其他表的字段,所以无法直接在表定义的CHECK中调用其他表存储的schema做校验,但可以通过其他方案实现同等需求。
实现前提
要求MySQL版本 >= 8.0.17,该版本开始原生支持JSON_SCHEMA_VALID()函数用于JSON schema校验。
推荐实现方案:触发器(最稳妥)
触发器可以在数据插入、更新前自动执行校验逻辑,完全可以满足跨表取schema做校验的需求。
第一步:先创建基础表
CREATE TABLE modules( id INTEGER NOT NULL PRIMARY KEY, schema JSON NOT NULL ); CREATE TABLE licenses( id INTEGER NOT NULL PRIMARY KEY, config JSON NOT NULL, module_id INTEGER NOT NULL, FOREIGN KEY (module_id) REFERENCES modules(id) );
第二步:创建插入前校验触发器
DELIMITER // CREATE TRIGGER check_license_config_before_insert BEFORE INSERT ON licenses FOR EACH ROW BEGIN DECLARE target_schema JSON; -- 获取关联模块的schema SELECT schema INTO target_schema FROM modules WHERE id = NEW.module_id; -- 校验不通过则抛出错误终止写入 IF NOT JSON_SCHEMA_VALID(target_schema, NEW.config) THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'config字段不符合对应模块的JSON Schema要求'; END IF; END // DELIMITER ;
第三步:创建更新前校验触发器
避免更新数据时绕过校验规则:
DELIMITER // CREATE TRIGGER check_license_config_before_update BEFORE UPDATE ON licenses FOR EACH ROW BEGIN DECLARE target_schema JSON; SELECT schema INTO target_schema FROM modules WHERE id = NEW.module_id; IF NOT JSON_SCHEMA_VALID(target_schema, NEW.config) THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'config字段不符合对应模块的JSON Schema要求'; END IF; END // DELIMITER ;
可选补充
如果你的业务允许修改modules表的schema字段,且需要校验历史licenses数据是否还符合新的schema,可以额外给modules表加UPDATE触发器,schema修改时批量校验所有关联的licenses数据,具体逻辑可根据业务需求调整。
内容的提问来源于stack exchange,提问作者Exprove
相关产品推荐
相关产品推荐

