1.0.303.sql 3.2 KB

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