feat(database): 添加多个玩家相关表的联合唯一约束 - 为player_talk表添加玩家+挖矿联合唯一索引 - 为player_task表添加玩家+任务联合唯一索引 - 为player_title表添加玩家+称号联合唯一索引 - 为player_pet表添加玩家+精灵联合唯一索引 - 为player_cdk_log表添加玩家+CDK联合唯一索引 - 为player_egg表添加玩家孵蛋联合唯一索引 - 为player_pvp表添加PVP索引 - 为player_sign_in_log表添加签到联合唯一索引 - 为player_room_house表添加房间索引 fix(user-talk): 修复获取聊天配置
This commit is contained in:
40
help/约束类.sql
40
help/约束类.sql
@@ -1,4 +1,42 @@
|
||||
-- 玩家+物品+VIP状态 联合唯一
|
||||
ALTER TABLE player_item
|
||||
ADD CONSTRAINT uk_player_item_player_item_vip
|
||||
UNIQUE (player_id, item_id, is_vip);
|
||||
UNIQUE (player_id, item_id, is_vip);
|
||||
|
||||
|
||||
-- 玩家+挖矿 联合唯一
|
||||
CREATE UNIQUE INDEX uk_talk_player ON player_talk (talk_id, player_id);
|
||||
|
||||
|
||||
-- 玩家+任务 联合唯一
|
||||
CREATE UNIQUE INDEX uk_player_task ON player_task (player_id, task_id);
|
||||
-- 玩家+称号 联合唯一
|
||||
CREATE UNIQUE INDEX 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;
|
||||
|
||||
-- 玩家+CDK 联合唯一
|
||||
CREATE UNIQUE INDEX 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)
|
||||
WHERE deleted_at IS NULL;
|
||||
|
||||
---PVP索引
|
||||
CREATE UNIQUE INDEX uk_player_pvp
|
||||
ON player_pvp (player_id, season)
|
||||
WHERE deleted_at IS NULL;
|
||||
|
||||
--签到
|
||||
CREATE UNIQUE INDEX 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
|
||||
ON player_room_house (player_id, is_vip)
|
||||
WHERE deleted_at IS NULL;
|
||||
@@ -30,6 +30,9 @@ func (h Controller) GetTalkCategory(data *item.TalkCateInboundInfo, c *player.Pl
|
||||
}
|
||||
//更新次数
|
||||
config := service.NewTalkConfigService().GetCache(int(data.ID))
|
||||
if config == nil {
|
||||
return result, errorcode.ErrorCodes.ErrSystemError
|
||||
}
|
||||
|
||||
//service.NewItemService().GetItemCount(config.ItemID)
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ type MineralCollectionConfig struct {
|
||||
Type uint32 `gorm:"column:type;not null;index:idx_mineral_collection_config_type;comment:类型" json:"type"`
|
||||
|
||||
// DailyCollectCount 每日可采集次数
|
||||
DailyCollectCount uint32 `gorm:"column:daily_collect_count;not null;comment:每日可采集次数" json:"daily_collect_count"`
|
||||
DailyCollectCount uint32 `gorm:"column:daily_collect_count;not null;comment:可采集次数" json:"daily_collect_count"`
|
||||
|
||||
// ItemID 物品编号(对应道具系统ID)
|
||||
ItemIDS []uint32 `gorm:"column:item_ids;type:jsonb;index:idx_mineral_collection_config_item_id;comment:物品编号(对应道具系统ID)" json:"item_ids"`
|
||||
|
||||
@@ -78,7 +78,6 @@ func (s *TalkService) Cheak(mapid uint32, flag int) (int, bool) {
|
||||
|
||||
}
|
||||
|
||||
// Update 原子更新,返回是否更新成功(true=成功 false=上限/失败/VIP)
|
||||
func (s *TalkService) Update(flag int, count int) bool {
|
||||
// VIP 直接返回失败
|
||||
if cool.Config.ServerInfo.IsVip != 0 {
|
||||
@@ -96,28 +95,27 @@ func (s *TalkService) Update(flag int, count int) bool {
|
||||
}
|
||||
maxCount := int(cfg.DailyCollectCount)
|
||||
|
||||
// 2. 原子插入(不存在则插入,存在忽略,高并发安全)
|
||||
talk := model.NewTalk()
|
||||
talk.PlayerID = userID
|
||||
talk.TalkID = talkID
|
||||
_, _ = db.Data(talk).FieldsEx("id").InsertIgnore()
|
||||
// 2. 原子操作:不存在则插入(count=0),存在则不操作
|
||||
talk := model.Talk{
|
||||
PlayerID: userID,
|
||||
TalkID: talkID,
|
||||
Count: 0, // 关键:必须初始化 count 为 0
|
||||
}
|
||||
// 唯一索引 + InsertIgnore 保证只会插入1次
|
||||
_, _ = db.Data(talk).InsertIgnore()
|
||||
|
||||
// 3. 原子条件自增:只有没超过上限才会更新
|
||||
// 核心:数据库原子判断,绝对不溢出
|
||||
// 3. 原子条件自增(只有没超上限才会增加)
|
||||
affected, err := db.
|
||||
Where("talk_id = ?", talkID).
|
||||
Where("player_id = ?", userID). // 关键:必须加 player_id 条件
|
||||
Where("count + ? <= ?", count, maxCount).
|
||||
Increment("count", count)
|
||||
|
||||
if err != nil {
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
row, _ := affected.RowsAffected()
|
||||
// 有错误 或 没有影响行数 = 更新失败(已达上限)
|
||||
if row == 0 {
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
// 0 行受影响 = 已达上限
|
||||
return row > 0
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user