fix(数据库): 为菜单表添加唯一键支持,适配 MySQL 5.7

This commit is contained in:
吴昊天 2026-10-23 09:59:48 +08:00
parent 997659de67
commit 2b3f30d057
2 changed files with 17 additions and 3 deletions

View File

@ -1608,14 +1608,27 @@ abstract class BaseModuleInstaller implements ModuleInstallerInterface
);
$database = (string)config('database.connections.mysql.database');
// MySQL 5.7 不支持函数索引,改用 STORED 生成列 + 普通唯一索引。
// NULLIF 生成 NULL,允许空 key 重复;非空 key 仍由唯一索引约束。
$generatedColumn = Db::query(
'SELECT 1 FROM information_schema.columns'
. ' WHERE table_schema = ? AND table_name = ? AND column_name = ? LIMIT 1',
[$database, $fullTable, 'menu_key_unique']
);
if (empty($generatedColumn)) {
Db::execute(
"ALTER TABLE `{$fullTable}` ADD COLUMN `menu_key_unique` varchar(190) "
. "GENERATED ALWAYS AS (NULLIF(`menu_key`, '')) STORED "
. "COMMENT '菜单稳定标识唯一键(空值不参与唯一约束)' AFTER `menu_key`"
);
}
$index = Db::query(
'SELECT 1 FROM information_schema.statistics'
. ' WHERE table_schema = ? AND table_name = ? AND index_name = ? LIMIT 1',
[$database, $fullTable, 'uk_menu_key']
);
if (empty($index)) {
// NULLIF 允许极端中断场景暂存空 key,所有正常写入仍受唯一约束。
Db::execute("ALTER TABLE `{$fullTable}` ADD UNIQUE KEY `uk_menu_key` ((NULLIF(`menu_key`, ''))) ");
Db::execute("ALTER TABLE `{$fullTable}` ADD UNIQUE KEY `uk_menu_key` (`menu_key_unique`)");
}
}

View File

@ -1799,6 +1799,7 @@ CREATE TABLE IF NOT EXISTS `eb_system_menus` (
`is_header` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否顶部菜单1是0否',
`unique_auth` varchar(150) NOT NULL DEFAULT '' COMMENT '前台唯一标识',
`menu_key` varchar(190) NOT NULL DEFAULT '' COMMENT '菜单稳定标识,系统生成且不可修改',
`menu_key_unique` varchar(190) GENERATED ALWAYS AS (NULLIF(`menu_key`, '')) STORED COMMENT '菜单稳定标识唯一键(空值不参与唯一约束)',
`is_del` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否删除',
`mark` varchar(500) NOT NULL DEFAULT '' COMMENT '备注',
`owner_plugin_id` varchar(96) NOT NULL DEFAULT '' COMMENT '所属插件复合标识,空为核心菜单',
@ -1807,7 +1808,7 @@ CREATE TABLE IF NOT EXISTS `eb_system_menus` (
KEY `is_show` (`is_show`) USING BTREE,
KEY `access` (`access`) USING BTREE,
KEY `idx_owner_plugin_id` (`owner_plugin_id`),
UNIQUE KEY `uk_menu_key` ((NULLIF(`menu_key`, '')))
UNIQUE KEY `uk_menu_key` (`menu_key_unique`)
) ENGINE=InnoDB AUTO_INCREMENT=4961 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='菜单表';
-- eb_system_pem:证书表