-- 1.0.303.sql S0:NbrTypeMaster 唯一索引租户化(幂等 + 冲突前置守卫)。 -- 背景:NbrTypeMaster 现已按租户填充(797:70 / 824:71,Domain 按租户分区 8010/2410,62 个 NbrType 跨租户各存一份), -- 属租户级主数据;原全局唯一索引 IX_NbrTypeMaster(Domain, NbrClass, NbrType) 仅因 Domain 天然分区而未撞, -- 两租户若共用同一 Domain 即会误撞。改为租户内唯一,使不同租户可复用相同 (Domain,NbrClass,NbrType)。 -- 不改字段类型、不改 tenant_id 可空性、不插入/更新/删除任何业务数据。 -- 实体 AdoS0NbrTypeMaster 带 [IgnoreTable],CodeFirst 不管理其索引 → 本 DDL 为唯一来源,重启不复活旧全局唯一。 -- ============================================================================ -- ========== 一、冲突前置检测(同租户内重复则跳过创建,绝不自动清理历史数据) ========== SET @dup := (SELECT COUNT(*) FROM ( SELECT tenant_id, `Domain`, NbrClass, NbrType FROM NbrTypeMaster GROUP BY tenant_id, `Domain`, NbrClass, NbrType HAVING COUNT(*) > 1) t); SELECT @dup AS nbrtype_intratenant_dup; -- 期望 0;若非 0,下方 ADD 被守卫跳过 -- ========== 二、删除旧全局唯一索引 IX_NbrTypeMaster(存在才删) ========== SET @has_old := (SELECT COUNT(DISTINCT INDEX_NAME) FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'NbrTypeMaster' AND INDEX_NAME = 'IX_NbrTypeMaster'); SET @sql := IF(@has_old > 0, 'ALTER TABLE NbrTypeMaster DROP INDEX IX_NbrTypeMaster', 'DO 0'); PREPARE s FROM @sql; EXECUTE s; DEALLOCATE PREPARE s; -- ========== 三、创建租户内唯一索引(不存在且无同租户冲突才建) ========== SET @has_new := (SELECT COUNT(DISTINCT INDEX_NAME) FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'NbrTypeMaster' AND INDEX_NAME = 'uk_NbrTypeMaster_tenant_domain_nbrclass_nbrtype'); SET @sql := IF(@has_new = 0 AND @dup = 0, 'ALTER TABLE NbrTypeMaster ADD UNIQUE INDEX uk_NbrTypeMaster_tenant_domain_nbrclass_nbrtype (tenant_id, `Domain`, NbrClass, NbrType)', 'DO 0'); PREPARE s FROM @sql; EXECUTE s; DEALLOCATE PREPARE s; -- ========== 四、执行后验证 ========== SELECT INDEX_NAME, NON_UNIQUE, SEQ_IN_INDEX, COLUMN_NAME FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'NbrTypeMaster' AND INDEX_NAME <> 'PRIMARY' ORDER BY INDEX_NAME, SEQ_IN_INDEX; -- 期望:仅 uk_NbrTypeMaster_tenant_domain_nbrclass_nbrtype (tenant_id, Domain, NbrClass, NbrType)(唯一)。 -- ============================================================================ -- 回滚 SQL(恢复全局唯一,历史数据无跨租户同键冲突时可执行): -- ALTER TABLE NbrTypeMaster DROP INDEX uk_NbrTypeMaster_tenant_domain_nbrclass_nbrtype; -- ALTER TABLE NbrTypeMaster ADD UNIQUE INDEX IX_NbrTypeMaster (`Domain`, NbrClass, NbrType); -- 注意:回滚 ADD 若两租户已共用同一 (Domain,NbrClass,NbrType) 会失败(这正是本次要放开的场景)。 -- ============================================================================