1
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
-- base_sys_user_role 角色授权去重
|
||||
-- 保留每组 userId + roleId 中 id 最小的一条,删除其余重复记录
|
||||
-- 只处理未软删除的有效授权;软删除历史记录不参与去重和唯一约束
|
||||
-- 保留每组有效 userId + roleId 中 id 最小的一条,删除其余重复记录
|
||||
|
||||
-- 1. 执行前查看重复数据
|
||||
SELECT
|
||||
@@ -9,6 +10,7 @@ SELECT
|
||||
MIN(id) AS keep_id,
|
||||
ARRAY_AGG(id ORDER BY id) AS ids
|
||||
FROM base_sys_user_role
|
||||
WHERE deleted_at IS NULL
|
||||
GROUP BY "userId", "roleId"
|
||||
HAVING COUNT(*) > 1
|
||||
ORDER BY cnt DESC, "userId", "roleId";
|
||||
@@ -18,6 +20,8 @@ DELETE FROM base_sys_user_role a
|
||||
USING base_sys_user_role b
|
||||
WHERE a."userId" = b."userId"
|
||||
AND a."roleId" = b."roleId"
|
||||
AND a.deleted_at IS NULL
|
||||
AND b.deleted_at IS NULL
|
||||
AND a.id > b.id;
|
||||
|
||||
-- 3. 执行后复查,应返回 0 行
|
||||
@@ -26,5 +30,16 @@ SELECT
|
||||
"roleId",
|
||||
COUNT(*) AS cnt
|
||||
FROM base_sys_user_role
|
||||
WHERE deleted_at IS NULL
|
||||
GROUP BY "userId", "roleId"
|
||||
HAVING COUNT(*) > 1;
|
||||
|
||||
-- 4. 建议约束:只限制未软删除授权唯一,允许历史软删除授权保留
|
||||
ALTER TABLE base_sys_user_role
|
||||
DROP CONSTRAINT IF EXISTS uk_base_sys_user_role_user_role;
|
||||
|
||||
DROP INDEX IF EXISTS uk_base_sys_user_role_user_role;
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uk_base_sys_user_role_user_role
|
||||
ON base_sys_user_role ("userId", "roleId")
|
||||
WHERE deleted_at IS NULL;
|
||||
|
||||
237
help/约束类.sql
237
help/约束类.sql
@@ -1,53 +1,254 @@
|
||||
-- 唯一约束修复
|
||||
-- 规则:所有带 deleted_at 的业务唯一约束,只约束未软删除记录。
|
||||
|
||||
-- 玩家+物品+VIP状态 联合唯一
|
||||
ALTER TABLE player_item
|
||||
ADD CONSTRAINT uk_player_item_player_item_vip
|
||||
UNIQUE (player_id, item_id, is_vip);
|
||||
DROP CONSTRAINT IF EXISTS uk_player_item_player_item_vip;
|
||||
DROP INDEX IF EXISTS uk_player_item_player_item_vip;
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uk_player_item_player_item_vip
|
||||
ON player_item (player_id, item_id, is_vip)
|
||||
WHERE deleted_at IS NULL;
|
||||
|
||||
|
||||
-- 玩家+挖矿 联合唯一
|
||||
CREATE UNIQUE INDEX uk_talk_player ON player_talk (talk_id, player_id);
|
||||
ALTER TABLE player_talk
|
||||
DROP CONSTRAINT IF EXISTS uk_talk_player;
|
||||
DROP INDEX IF EXISTS uk_talk_player;
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uk_talk_player
|
||||
ON player_talk (talk_id, player_id)
|
||||
WHERE deleted_at IS NULL;
|
||||
|
||||
|
||||
-- 玩家+任务 联合唯一
|
||||
CREATE UNIQUE INDEX uk_player_task ON player_task (player_id, task_id);
|
||||
ALTER TABLE player_task
|
||||
DROP CONSTRAINT IF EXISTS uk_player_task;
|
||||
DROP INDEX IF EXISTS uk_player_task;
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uk_player_task
|
||||
ON player_task (player_id, task_id)
|
||||
WHERE deleted_at IS NULL;
|
||||
|
||||
|
||||
-- 玩家+称号 联合唯一
|
||||
CREATE UNIQUE INDEX uk_player_title ON player_title (player_id, is_vip) WHERE deleted_at IS NULL;
|
||||
ALTER TABLE player_title
|
||||
DROP CONSTRAINT IF EXISTS uk_player_title;
|
||||
DROP INDEX IF EXISTS uk_player_title;
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uk_player_title
|
||||
ON player_title (player_id, is_vip)
|
||||
WHERE deleted_at IS NULL;
|
||||
|
||||
|
||||
-- 玩家+精灵 联合唯一
|
||||
CREATE UNIQUE INDEX uk_player_pet ON player_pet (player_id, is_vip, catch_time) WHERE deleted_at IS NULL;
|
||||
ALTER TABLE player_pet
|
||||
DROP CONSTRAINT IF EXISTS uk_player_pet;
|
||||
DROP INDEX IF EXISTS uk_player_pet;
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uk_player_pet
|
||||
ON player_pet (player_id, is_vip, catch_time)
|
||||
WHERE deleted_at IS NULL;
|
||||
|
||||
|
||||
-- 玩家+CDK 联合唯一
|
||||
CREATE UNIQUE INDEX uk_player_cdk_log
|
||||
ALTER TABLE player_cdk_log
|
||||
DROP CONSTRAINT IF EXISTS uk_player_cdk_log;
|
||||
DROP INDEX IF EXISTS uk_player_cdk_log;
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uk_player_cdk_log
|
||||
ON player_cdk_log (player_id, code_id, is_vip)
|
||||
WHERE deleted_at IS NULL;
|
||||
|
||||
|
||||
|
||||
-- 玩家孵蛋 联合唯一
|
||||
CREATE UNIQUE INDEX uk_player_egg
|
||||
ON player_egg (player_id, is_vip)
|
||||
ALTER TABLE player_egg
|
||||
DROP CONSTRAINT IF EXISTS uk_player_egg;
|
||||
DROP INDEX IF EXISTS uk_player_egg;
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uk_player_egg
|
||||
ON player_egg (player_id, is_vip)
|
||||
WHERE deleted_at IS NULL;
|
||||
|
||||
---PVP索引
|
||||
CREATE UNIQUE INDEX uk_player_pvp
|
||||
|
||||
-- PVP索引
|
||||
ALTER TABLE player_pvp
|
||||
DROP CONSTRAINT IF EXISTS uk_player_pvp;
|
||||
DROP INDEX IF EXISTS uk_player_pvp;
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uk_player_pvp
|
||||
ON player_pvp (player_id, season)
|
||||
WHERE deleted_at IS NULL;
|
||||
|
||||
--签到
|
||||
CREATE UNIQUE INDEX uk_player_sign_in_log
|
||||
|
||||
-- 签到
|
||||
ALTER TABLE player_sign_in_log
|
||||
DROP CONSTRAINT IF EXISTS uk_player_sign_in_log;
|
||||
DROP INDEX IF EXISTS uk_player_sign_in_log;
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uk_player_sign_in_log
|
||||
ON player_sign_in_log (player_id, sign_in_id, is_vip)
|
||||
WHERE deleted_at IS NULL;
|
||||
--房间索引
|
||||
CREATE UNIQUE INDEX uk_player_room_house
|
||||
|
||||
|
||||
-- 房间索引
|
||||
ALTER TABLE player_room_house
|
||||
DROP CONSTRAINT IF EXISTS uk_player_room_house;
|
||||
DROP INDEX IF EXISTS uk_player_room_house;
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uk_player_room_house
|
||||
ON player_room_house (player_id, is_vip)
|
||||
WHERE deleted_at IS NULL;
|
||||
|
||||
|
||||
-- 集市权限角色 联合唯一
|
||||
-- 先清理历史重复授权,保留每组 userId + roleId 中 id 最小的一条
|
||||
-- 先清理有效重复授权,保留每组 userId + roleId 中 id 最小的一条。
|
||||
DELETE FROM base_sys_user_role a
|
||||
USING base_sys_user_role b
|
||||
WHERE a."userId" = b."userId"
|
||||
AND a."roleId" = b."roleId"
|
||||
AND a.deleted_at IS NULL
|
||||
AND b.deleted_at IS NULL
|
||||
AND a.id > b.id;
|
||||
|
||||
ALTER TABLE base_sys_user_role
|
||||
DROP CONSTRAINT IF EXISTS uk_base_sys_user_role_user_role;
|
||||
DROP INDEX IF EXISTS uk_base_sys_user_role_user_role;
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uk_base_sys_user_role_user_role
|
||||
ON base_sys_user_role ("userId", "roleId");
|
||||
ON base_sys_user_role ("userId", "roleId")
|
||||
WHERE deleted_at IS NULL;
|
||||
|
||||
|
||||
-- CDK配置 编号唯一
|
||||
ALTER TABLE config_gift_cdk
|
||||
DROP CONSTRAINT IF EXISTS idx_config_gift_cdk_cdk_code;
|
||||
DROP INDEX IF EXISTS idx_config_gift_cdk_cdk_code;
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_config_gift_cdk_cdk_code
|
||||
ON config_gift_cdk (cdk_code)
|
||||
WHERE deleted_at IS NULL;
|
||||
|
||||
|
||||
-- 战斗规则 规则索引唯一
|
||||
ALTER TABLE config_fight_rule
|
||||
DROP CONSTRAINT IF EXISTS idx_rule_idx;
|
||||
DROP INDEX IF EXISTS idx_rule_idx;
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_rule_idx
|
||||
ON config_fight_rule (rule_idx)
|
||||
WHERE deleted_at IS NULL;
|
||||
|
||||
|
||||
-- 天选配置 玩家+精灵唯一
|
||||
ALTER TABLE config_peak_tianxuan
|
||||
DROP CONSTRAINT IF EXISTS idx_peak_tianxuan_player_pet;
|
||||
DROP INDEX IF EXISTS idx_peak_tianxuan_player_pet;
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_peak_tianxuan_player_pet
|
||||
ON config_peak_tianxuan (player_id, pet_id)
|
||||
WHERE deleted_at IS NULL;
|
||||
|
||||
|
||||
-- 天选投票 周期+玩家唯一
|
||||
ALTER TABLE config_peak_tianxuan_vote
|
||||
DROP CONSTRAINT IF EXISTS idx_peak_tianxuan_vote_week_player;
|
||||
DROP INDEX IF EXISTS idx_peak_tianxuan_vote_week_player;
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_peak_tianxuan_vote_week_player
|
||||
ON config_peak_tianxuan_vote (week_index, player_id)
|
||||
WHERE deleted_at IS NULL;
|
||||
|
||||
|
||||
-- 服务器冠名 同服同属主唯一
|
||||
ALTER TABLE server_show
|
||||
DROP CONSTRAINT IF EXISTS idx_server_show_server_owner;
|
||||
DROP INDEX IF EXISTS idx_server_show_server_owner;
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_server_show_server_owner
|
||||
ON server_show (server_id, owner)
|
||||
WHERE deleted_at IS NULL;
|
||||
|
||||
|
||||
-- 商店 商品ID唯一
|
||||
ALTER TABLE config_shop
|
||||
DROP CONSTRAINT IF EXISTS idx_config_shop_product_id;
|
||||
DROP INDEX IF EXISTS idx_config_shop_product_id;
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_config_shop_product_id
|
||||
ON config_shop (product_id)
|
||||
WHERE deleted_at IS NULL;
|
||||
|
||||
|
||||
-- 签到配置 签到类别+阶段唯一
|
||||
ALTER TABLE config_sign_in
|
||||
DROP CONSTRAINT IF EXISTS idx_sign_type_stage;
|
||||
DROP INDEX IF EXISTS idx_sign_type_stage;
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_sign_type_stage
|
||||
ON config_sign_in (sign_type, stage_days)
|
||||
WHERE deleted_at IS NULL;
|
||||
|
||||
|
||||
-- 签到配置 CDK唯一
|
||||
ALTER TABLE config_sign_in
|
||||
DROP CONSTRAINT IF EXISTS idx_config_sign_in_cdk_id;
|
||||
DROP INDEX IF EXISTS idx_config_sign_in_cdk_id;
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_config_sign_in_cdk_id
|
||||
ON config_sign_in (cdk_id)
|
||||
WHERE deleted_at IS NULL;
|
||||
|
||||
|
||||
-- SPT配置 任务ID唯一
|
||||
ALTER TABLE config_spt
|
||||
DROP CONSTRAINT IF EXISTS idx_config_spt_task_id;
|
||||
DROP INDEX IF EXISTS idx_config_spt_task_id;
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_config_spt_task_id
|
||||
ON config_spt (task_id)
|
||||
WHERE deleted_at IS NULL;
|
||||
|
||||
|
||||
-- 爬塔配置 层级唯一
|
||||
ALTER TABLE config_tower_1
|
||||
DROP CONSTRAINT IF EXISTS idx_config_tower_1_tower_level;
|
||||
DROP INDEX IF EXISTS idx_config_tower_1_tower_level;
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_config_tower_1_tower_level
|
||||
ON config_tower_1 (tower_level)
|
||||
WHERE deleted_at IS NULL;
|
||||
|
||||
ALTER TABLE config_tower_110
|
||||
DROP CONSTRAINT IF EXISTS idx_config_tower_110_tower_level;
|
||||
DROP INDEX IF EXISTS idx_config_tower_110_tower_level;
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_config_tower_110_tower_level
|
||||
ON config_tower_110 (tower_level)
|
||||
WHERE deleted_at IS NULL;
|
||||
|
||||
ALTER TABLE config_tower_500
|
||||
DROP CONSTRAINT IF EXISTS idx_config_tower_500_tower_level;
|
||||
DROP INDEX IF EXISTS idx_config_tower_500_tower_level;
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_config_tower_500_tower_level
|
||||
ON config_tower_500 (tower_level)
|
||||
WHERE deleted_at IS NULL;
|
||||
|
||||
ALTER TABLE config_tower_600
|
||||
DROP CONSTRAINT IF EXISTS idx_config_tower_600_tower_level;
|
||||
DROP INDEX IF EXISTS idx_config_tower_600_tower_level;
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_config_tower_600_tower_level
|
||||
ON config_tower_600 (tower_level)
|
||||
WHERE deleted_at IS NULL;
|
||||
|
||||
|
||||
-- 玩家信息 角色ID唯一
|
||||
ALTER TABLE player_info
|
||||
DROP CONSTRAINT IF EXISTS idx_player_info_player_id;
|
||||
DROP INDEX IF EXISTS idx_player_info_player_id;
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_player_info_player_id
|
||||
ON player_info (player_id)
|
||||
WHERE deleted_at IS NULL;
|
||||
|
||||
Reference in New Issue
Block a user