一、游戲物品/道具系統數據模型設計特點
為了讓游戲更加的豐富,我們1201團隊的新手機游戲設計了道具系統。於是豐富了游戲、取悅了玩家,哭了開發——道具/物品數據子系統是簡單的、復雜的、不確定的:
- 簡單,說起來不就是選擇一個或多個數據庫產品,然后定義一種數據模型,然后增、刪、改、查。
復雜,物品/道具可以在細分為裝備、時裝、坐騎、寶石、buff等等,每類物品有不同的屬性需求,於是:
- 首先物品數據是游戲核心數據里數據量最大、操作最頻繁、數據結構最多元化的數據
- 如果用一種數據表結構,那么會浪費很多的字段或數據空間(而物品表超大);
- 如果用不同的數據表結構,那么游戲邏輯就要麻煩一些了,比如物品在玩家中轉移的時候、修改、丟棄的時候。
- 是否進行應用邏輯層水平切分?切分了就可以將數據庫分布到多個數據庫服務器上,那么理論上數據規模就不會成為瓶頸了;但如果切分了,道具數據分析、后期的合區邏輯就會很復雜。
- 裝備、時裝是會有多個屬性的,且每件裝備的屬性值、屬性類型都不一樣,如何設計數據字段(當然如果用nosql數據庫就不存在這個問題了)?
不確定:
- 隨着游戲開發及運營的進行,各種新的道具的需求會不斷涌現出來,有可能就會需要增加新的屬性和功能需求
- 到底每一個玩家最終會有多少的物品?
- 最終單個區服的數據規模有多大這個其實很難預計。我們做的很完善(當然開發代價也大)的設計與開發會不會有些多余,甚至被老板認為想多了?
二、游戲物品/道具系統數據模型設計目標及解決思路
上面分析做了,槽也吐了,還是要做事嘛,呵呵。根據我們的新游戲的具體需求,對物品數據庫表的設計定義了如下要求和解決思路:
序號 | 要求 | 解決思路 |
---|---|---|
1 | 確保數據操作的性能 | 充分利用緩存服務器 |
2 | 降低程序開發和后期客服工作的復雜度 | 各類道具不分表 |
3 | 必須可以方便、靈活的支持道具新功能需求的開發 | 將多變的裝備屬性以json格式存於一個字段 |
4 | 保留充分的可擴展性 | 根據玩家id進行數據庫表水平切分 |
5 | 盡量降低合區操作時數據處理邏輯的難度和效率 | 用自增長ID、玩家id、區服id做聯合主鍵 |
三、具體開發設計方案
根據以上的分析結果,我們在總結了以前的游戲開發經驗並參考了網上的一些文章后形成了我們新手機游戲的物品數據子系統的設計、開發方案。
所有數據訪問都封裝在model層。
- 在程序的model層里定義公共函數GetDb(playerid,areaid),用於物品數據及其它需要進行按用戶水平分割的數據獲取數據庫(連接)
- 每一個物品的主鍵由itemid,playerid,areaid三個字段組成
- 將裝備buff及某道具特有屬性統一以json字符串形式保存在一個varchar字段里
- 道具表定義 失效時間 字段,這個字段同時表示道具有效期的三種情況:
- =0 ,表示是不限時的永久性道具
- 小於等於600000,表示有效時間段,如雙倍經驗卡有效時長3小時,那么着個字段值為 180 (分鍾),使用此道具時,用當前時間加上這個字段值得到失效時間戳修改此字段或做其他處理
- 大於600000,表示該道具的失效時間戳(unix時間戳格式)
- 玩家道具數據查詢流程:
- 首先檢查redis里有沒有
- 如果有,返回
- 如果沒有從數據庫里查詢並存到redis,返回
- 修改/或增加道具數據流程:
- 首先檢查redis里有沒有
- 如果沒有,從數據庫里查詢並存到redis
- 如果有,繼續
- 修改/增加redis數據,同時在key為“item_update_list”的redis list 數據里記錄下該道具的主鍵
- 定時根據“item_update_List”數據寫回mysql,並清除“item_update_list”
- 刪除一個道具數據流程:
- 在redis 里key為“item_delete_list” 的redis list 數據里記錄下該道具的主鍵
- 刪除redis里記錄
- 定時根據item_delete_list”數據刪除mysql里記錄,並清除“item_delete_list”
8.注意: - 配置redis 為 在每次更新操作后進行日志記錄
- 緩存定時同步mysql處理程序可以作為一個獨立的進程運行
- 這個解決方案可以針對其它用戶私有數據,如技能、buff。
四、總結
數據庫表水平分割和緩存應用基本上已經是服務器端程序員的常識,在google上查相關技術資料時,大多數博文也是寫的這些。
本文先是對游戲道具/物品數據模型的進行了簡單的需求分析,然后講了思路和方案,其實我最想表達的是我的三個設計細節或idea: + 道具數據記錄主鍵設計(方便合區) + 裝備buff及道具特有的屬性字段設計(為道具豐富的功能需求提供靈活、便捷的數據基礎) + 所有道具類別不區分存儲(方便后期的客服查詢和數據統計)
最后聲明:
其實我是一個程序員,呵呵!