mysql在索引定义中直接使用条件语句
原始数据库表如下:
CREATE TABLE `events` (
`id`int(11) unsigned NOT NULL AUTO_INCREMENT,
`status` enum('on','off') COLLATE utf8_unicode_ci NOT NULL COMMENT '开关状态',
`type` enum('gas_fee_free') COLLATE utf8_unicode_ci NOT NULLDEFAULT'gas_fee_free' COMMENT '类型:',
`scope` enum('global','space','badge') COLLATE utf8_unicode_ci NOT NULLDEFAULT'global' COMMENT '范围',
PRIMARY KEY (`id`),
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='时间活动表';
想实现的效果是 在特定的type和scope情况下,on的个数只能有一个,off的个数可以是多个,因为活动同时只能有一个开启。
但是如果直接把他们3加索引:
UNIQUEKEY`type_scope_index` (`type`,`scope`,`status`) USING BTREE,
那么on和off各只能有一个,不符合需求;
使用虚拟列(virtual column)来实现这样的条件唯一性约束。以下是修改后的创建表语句:
CREATE TABLE `events` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`status` enum('on','off') COLLATE utf8_unicode_ci NOT NULL COMMENT '开关状态',
`type` enum('gas_fee_free') COLLATE utf8_unicode_ci NOT NULL DEFAULT 'gas_fee_free' COMMENT '类型:',
`scope` enum('global','space','badge') COLLATE utf8_unicode_ci NOT NULL DEFAULT 'global' COMMENT '范围',
`status_on` enum('on') COLLATE utf8_unicode_ci AS (CASE WHEN (`status` = 'on') THEN 'on' END) VIRTUAL,
PRIMARY KEY (`id`),
UNIQUE KEY `type_scope_status_on_unique` (`type`,`scope`,`status_on`) USING BTREE,
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='时间活动表';
在上述语句中,我们添加了一个虚拟列 status_on
,它根据 status
列的值生成一个虚拟的 status_on
列。然后,我们在唯一索引 type_scope_status_on_unique
中使用了这个虚拟列,以实现在 status
为 'on' 时的唯一性约束。
请注意,在使用虚拟列时,你需要确保你的 MySQL 版本支持此功能。这个示例假设你使用的是支持虚拟列的 MySQL 版本。
非常抱歉之前的错误带来的困扰。希望这次的回答能够解决问题。如果还有其他问题,请随时提问。