character_inventory 表
角色背包系统 · 管理角色所有物品的存储位置
📖 官方文档来源表概述
character_inventory 表记录每个角色物品栏中所有物品的位置信息,包括:
- 🎒 背包物品
- ⚔️ 装备槽位
- 📦 银行存储
- 🔑 钥匙链
- 🛒 背包内物品
💡 核心概念:此表只存储物品的位置映射(哪个角色、哪个背包、哪个槽位、哪个物品),物品的详细属性存储在
item_instance 表中。item 字段是主键,同时也是唯一索引。
🎯 关联关系:
guid → characters.guid(角色),item → item_instance.guid(物品实例)。这形成了一个"角色 → 物品槽位 → 物品实例"的三级关联。
表结构
| 字段名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| guid | INT UNSIGNED | 0 | 角色GUID(关联 characters.guid) |
| bag | INT UNSIGNED | 0 | 所在容器ID(详见槽位系统) |
| slot | TINYINT UNSIGNED | 0 | 容器内的槽位编号 |
| item | INT UNSIGNED | 0 | 物品GUID(关联 item_instance.guid),主键 |
索引说明
| 索引名 | 类型 | 字段 | 说明 |
|---|---|---|---|
| PRIMARY | BTREE | item | 主键(物品唯一) |
| guid (UNIQUE) | BTREE | guid, bag, slot | 唯一索引(同一位置只能放一个物品) |
| idx_guid | BTREE | guid | 角色索引(快速查询某角色所有物品) |
槽位系统详解
bag 和 slot 共同确定物品在角色物品栏中的精确位置。
bag 字段取值
| bag值 | 位置 | 说明 |
|---|---|---|
| 0 | 主背包 | 角色初始16格背包(不可移除) |
| 19-22 | 背包栏 | 角色装备的4个背包(对应背包槽1-4) |
| 23-38 | 装备栏 | 角色穿戴的装备(详见装备槽位) |
| 39-105 | 银行 | 银行存储物品 |
| 106-137 | 银行背包 | 银行中已装备的背包 |
| 138-169 | 钥匙链 | 钥匙链物品 |
装备槽位 (bag=23-38)
| bag值 | slot值 | 装备位置 |
|---|---|---|
| 0 | 0 | 头部 |
| 0 | 1 | 颈部 |
| 0 | 2 | 肩部 |
| 0 | 3 | 衬衣 |
| 0 | 4 | 胸部 |
| 0 | 5 | 腰部 |
| 0 | 6 | 腿部 |
| 0 | 7 | 脚部 |
| 0 | 8 | 手腕 |
| 0 | 9 | 手部 |
| 0 | 10 | 手指1 |
| 0 | 11 | 手指2 |
| 0 | 12 | 饰品1 |
| 0 | 13 | 饰品2 |
| 0 | 14 | 背部 |
| 0 | 15 | 主手武器 |
| 0 | 16 | 副手/盾牌 |
| 0 | 17 | 远程武器/圣物 |
| 0 | 18 | 弹药 |
💡 装备槽位说明:装备栏使用
bag=0(主背包)但 slot 值对应具体装备位置。实际上装备本身也在角色身上,通过特殊的 slot 编号区分不同装备部位。
快速参考
核心字段
| guid | 所属角色 |
| bag | 容器位置 |
| slot | 槽位编号 |
| item | 物品实例ID |
bag 范围速查
| 0 | 主背包 |
| 19-22 | 装备的背包 |
| 23-38 | 装备栏 |
| 39-105 | 银行 |
| 106-137 | 银行背包 |
| 138-169 | 钥匙链 |
关联表
| characters | 通过 guid |
| item_instance | 通过 item |
索引
| PRIMARY | item (唯一) |
| UNIQUE | guid+bag+slot |
| idx_guid | guid |
实际案例
查询 查看角色的所有物品(含物品名称)
SELECT ci.guid, ci.bag, ci.slot, ci.item,
ii.itemEntry, ii.count
FROM character_inventory ci
JOIN item_instance ii ON ci.item = ii.guid
WHERE ci.guid = 1
ORDER BY ci.bag, ci.slot;查询 查找拥有特定装备的角色
-- 查找拥有"埃辛诺斯战刃"(itemEntry=32837)的在线角色
SELECT c.name, c.level, c.race, c.class, ci.bag, ci.slot
FROM character_inventory ci
JOIN item_instance ii ON ci.item = ii.guid
JOIN characters c ON ci.guid = c.guid
WHERE ii.itemEntry = 32837
AND c.online = 1;查询 统计各角色背包占用情况
-- 统计每个角色在各区域的物品数量
SELECT ci.guid,
c.name,
SUM(CASE WHEN ci.bag = 0 THEN 1 ELSE 0 END) AS backpack_items,
SUM(CASE WHEN ci.bag BETWEEN 19 AND 22 THEN 1 ELSE 0 END) AS bag_items,
SUM(CASE WHEN ci.bag BETWEEN 39 AND 105 THEN 1 ELSE 0 END) AS bank_items,
COUNT(*) AS total_items
FROM character_inventory ci
JOIN characters c ON ci.guid = c.guid
GROUP BY ci.guid, c.name
ORDER BY total_items DESC
LIMIT 20;清理 删除孤儿物品(库存有但 item_instance 无记录的)
-- 查找孤儿物品记录
SELECT ci.*
FROM character_inventory ci
LEFT JOIN item_instance ii ON ci.item = ii.guid
WHERE ii.guid IS NULL;
-- 删除孤儿物品记录(请先确认上面查询的结果!)
DELETE ci
FROM character_inventory ci
LEFT JOIN item_instance ii ON ci.item = ii.guid
WHERE ii.guid IS NULL;常见问题
Q1: character_inventory 和 item_instance 有什么区别?
character_inventory 只存储物品的位置信息(谁、在哪、哪个槽位),item_instance 存储物品的属性信息(是什么、耐久、附魔等)。两者通过 item 字段关联。
Q2: 为什么同一个物品不能同时在两个位置?
因为 item 是主键(唯一),每个物品实例只能出现在一个位置。这是数据库层面的约束保证。
Q3: 如何判断物品是否被装备?
检查 bag 值:如果 bag 在 0-22 范围内,说明物品在角色身上(背包或装备栏)。bag=0 且 slot 在装备槽范围内表示已装备。
Q4: 角色背包最多能放多少物品?
主背包16格 + 最多4个装备背包(每个最大32格等)= 最多约144格背包空间。银行最多98格 + 最多7个银行背包。