1. 物品表 物品表是整个交易系统的基础,用于存储游戏中所有物品的相关信息,包括物品 ID 、物品名称、物品类型、物品属性、物品等级、物品数量等。
CREATE TABLE `items` (
`item_id` INT NOT NULL AUTO_INCREMENT,
`item_name` VARCHAR(255) NOT NULL,
`item_type` VARCHAR(255) NOT NULL,
`item_attributes` JSON NOT NULL,
`item_level` INT NOT NULL,
PRIMARY KEY (`item_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
2. 用户持有哪些物品及数量表
CREATE TABLE `user_items` (
`id` INT NOT NULL AUTO_INCREMENT,
`user_id` INT NOT NULL,
`item_id` INT NOT NULL, // 物品 id
`item_count` INT NOT NULL, // 物品数量
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
3.交易信息表 交易信息表用于存储交易的相关信息,包括交易 ID 、物品 ID 、交易价格、交易时间、交易状态等。 让其他用户可以看到 当前正在售卖的道具物品。
CREATE TABLE `trade_info` (
`trade_id` INT NOT NULL AUTO_INCREMENT,
`user_id` INT NOT NULL, // 是谁 在卖道具
`item_id` INT NOT NULL, // 卖的什么道具
`item_count` INT NOT NULL, // 当前在售数量 重点关注 在售数量为 0 的记录要不要删除
`price` DECIMAL(10,2) NOT NULL, // 价格
`create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`status` TINYINT(1) NOT NULL DEFAULT 0,
PRIMARY KEY (`trade_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
4.交易记录表 交易记录表用于存储交易的详细记录,包括交易 ID 、物品 ID 、交易价格、交易时间、交易状态、买家 ID 、卖家 ID 等。
CREATE TABLE `trade_records` (
`trade_id` INT NOT NULL,
`item_id` INT NOT NULL,
`item_count` INT NOT NULL,
`price` DECIMAL(10,2) NOT NULL,
`create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`status` TINYINT(1) NOT NULL DEFAULT 0,
`buyer_id` INT NOT NULL,
`seller_id` INT NOT NULL,
PRIMARY KEY (`trade_id`),
FOREIGN KEY (`buyer_id`) REFERENCES `players` (`player_id`),
FOREIGN KEY (`seller_id`) REFERENCES `players` (`player_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
1
mourner 364 天前
DNF 的交易系统使用体验简直一坨屎.
我觉得如果实现 DNF 的交易功能,一般来说可以使用 redis + mysql 的方式. redis 提供基础的查询购买等需求, mysql 做持久化储存使用(方便统计图表数据记录使用). 首先是用户的浏览商品页面,这个页面需要作出快速响应,展示出所有物品,这一层仅需要分页展示商品列表,具体的交易信息最好还是再分层进入查询.道具的具体目录最多几万种道具,所以查询目录速度会非常快.(这一层可以模糊查询道具,然后给出列表) 然后是用户的购买页面,当用户进入道具售卖界面时,列出当前道具的售卖商品信息. 其他的业务同理, 最多在购买和上架时要处理业务逻辑判断保证购买的有效性. 思路就是像这样拆分业务,具体内容具体处理. 感觉你用四个表来操作拍卖行,那你会比 dnf 拍卖行还要卡. |
2
kxct 364 天前
交易信息表不用删,你觉得数据量太大可以分表或者定时删除多久之前的数据。
|
3
poembre OP @mourner 大佬说的在理,改交互方式;
总结一下就是 : dnf 的交易界面是直接搜索道具名称, 列表展示的字段是 : 卖家昵称 卖的物品道具名称 数量 价格 张三 小太刀 1000 $34000 --------------------------更改为 ------------------------------------------ 改为 直接搜索道具名称 列表是道具总表 items 表: 道具 id 道具名称 类型 属性 等级 58 小太刀 武器 +30 攻击 1 然后点击 小太刀 这行后; 弹窗列表展示谁在售卖 通过 id 58 去 trade_info 表查询 列表展示的字段是 : 卖家昵称 卖的物品道具名称 数量 价格 张三 小太刀 1000 $34000 大佬的方案极好 解决了查询问题, 省去了一层 表的关联查询。 比如之前可能是 select * from items as A left join trade_info as B ON A.id = B.item_id WHERE A.item_name like "%小太刀%" 更改后是: select * from items WHERE item_name like "%小太刀%" select * from trade_info WHERE item_id = 58 更加方便加缓存了 另外我还是想问 : 关于 交易信息表(trade_info), 某物品道具已经被买空,库存字段为 0; 是否需要从交易信息表 删除; 否则 trade_info 表数据非常大 |
4
poembre OP |
6
21231sv 364 天前
老哥,我想问个题外问题。做这块相关内容的算是游戏行业里的后端开发吗?主要是用什么语言实现呢?
|
8
mourner 364 天前
@poembre #3
在拍卖行这里需要使用 redis 进行数据的交互, mysql 仅纪录未来,或者当前设计需求中要满足的数据储存. 使用 Elasticsearch 储存交易纪录就好, 实际的交易内容对于整个拍卖系统来说并没有任何意义. 例如,张三有 10000 把属性不同的太刀 , 他以不同的价格上架到太刀分类中, 那么在拍卖行中你数据中储存的就是 10000 把太刀的交易信息, 但是随着被人购买,物品正常发往购买者的库存中, 那么交易信息的 redis 数据就可以直接删掉这件道具的售卖相关信息. 只需要把详细的交易纪录储存到 Elasticsearch 中方便数据查询就好. 在我的认知里, mysql 应该是不能完成这样的高频读写更新功能.(体量比较的话可以.) |
9
poembre OP @mourner 有个问题,因为涉及到玩家的道具物品数量,如果放入 redis 没法用事物 来保证一致性。 比如 mysql 操作成功 Redis 失败 等杠精问题 ... 。 然后 DNF 那个 将物品放入拍卖行 如果一直没人买, 到期会自动退回。 这个好像避免不了更新操作, 即使放入 Elasticsearch 也要被拎出来更新 。
|
12
xuanbg 364 天前
其实这种不存在商品表。因为这本质上不是商城而是交易。交易么,就是财务那套东西,记账。根据货币/物资的借贷记录,计算出货币/物资的数量即可。也就是一次交易,双方各记两笔账:物资的增加数/减少数量,货币的增加/减少数量。只要记录没错,那玩家的钱和道具就不会错。
至于这个表的数量会不断增加的问题,其实很好解决。停服维护的时候,把历史交易记录归档,然后只留下一条汇总记录即可,这就和财务的期初余额是一个道理。 |
13
bianhui 364 天前
两点:1 ,功能可以挂一个 redis 做库存加减扣除,定期同步到 mysql 。方案网上很多不赘述
2.就这点数据不需要删。你又不是做赌博游戏的,仅仅你交易能交易多少记录。你日活达到多少才能把你数据库搞卡。如果真的有那一天,你根据用户分表就可以了。如果真的到这种程度,你也不止这张表要优化,可能其他的表都得优化。可能也不是 mysql 了。 |