[轉至雲風的部落格]開發筆記 (2) :redis 資料庫結構設計

來源:互聯網
上載者:User

標籤:

接上回,按照我們一期項目的需求,昨天我簡單設計了資料庫裡的資料格式。資料庫採用的是 Redis ,我把它看成一個遠端的資料結構儲存裝置。它提供基本的 Key-Value 儲存功能,沒有層級表。如果需要兩層結構,可以在 Value 裡儲存一組 Hashes 。

這是我第一次實戰使用 Redis ,沒有什麼經驗。不過類似的設施幾年前自己實現過,區別不大。經過這幾年,有了 Redis 這個開源項目,就不需要重造輪子了。但其模式還是比較熟悉的。也就是說,是按我曆史經驗來使用 Redis 。

一期項目需要比較簡單,不打算把資料拆分到不同的資料服務器上。但為日後的拆分需求做好設計準備。以後有需要,可以按 Key 的首碼把資料分到不同的位置。例如,account 資訊是最可能獨立出去的,因為它和具體遊戲無關。

使用者系統使用 email 來做使用者名稱,但在資料庫中的唯一標識是一個 uid 。使用者應該允許修改登陸名(使用者很可能更換 email)。使用者的身份識別是用 id 來定位的。所以,在資料庫中就應該有如下幾組 Key :

  • account:count id
  • account:userlist set(id)
  • account:email:[email] id

這裡,account:userlist 對應的 value 是一個 set ,裡面存放了所有存在的 user id 。用於遍曆所有的 user 。這個暫時可能用不上,而且當使用者量相當大的時候可能有問題。不過暫時不用考慮這麼多問題,等以後改進。

account:count 是一個計數器,可以用來產生唯一 id 。

account:email:[email] 用來標示每個註冊的 account 的登陸名。[email] 指登陸用 email 地址。

這裡,email 內可能也存在符號 ":" ,為了迴避這個問題,許多對 email 進行編碼。我的方案是,將字母數字 @ . _ 之外的字元編碼為 %XX 的形式。用 lua 幹這件事情非常簡單:

local function _encode(str)    return string.format("%%%02X",string.byte(str))endfunction emailEncode(str)    return string.gsub(str,"([^%[email protected]])",_encode)end

當然,解碼回來也很簡單

local function _decode(str)    return string.char(tonumber(str,16))endfunction emailDecode(str)    return string.gsub(str,"%%(%w%w)",_decode)end

之後,就是 account 下每個 id 的資料:

  • account:[id]:version number
  • account:[id]:email string
  • account:[id]:password string // md5(password..salt)
  • account:[id]:nickname string
  • account:[id]:lastlogin hashes
    • ip string
    • time string
  • account:[id]:history list(string)
  • account:[id]:available enum(open/locked/delete)

其中,密碼不想儲存為明文。因為任何可能的資料泄露都會導致使用者的損失,我也不想任何人看到使用者的密碼。所以採用 md5(password .. salt) 的風格。

md5 運算前,加一個 salt 尾碼,是因為單純的文本 md5 值也是有資料庫可查的。

lastlogin 下儲存了使用者最後一次登陸的資訊,使用了一張 hashes 表,因為這些資訊在未來會進一步擴充。

history 儲存了使用者登陸的所有記錄,用一個 string 鏈表記錄。

使用者刪除自己的賬戶時,不想把資料從資料庫刪除,只想在 available 下做一個標記。

考慮到資料庫內資料結構有可能發生變化,所以加了 version 域做版本標識。

我不想讓各種服務可以直接讀寫這份資料,所以,會單獨寫一個證明伺服器做處理。

證明伺服器提供三項服務:

  1. 使用者註冊

  2. 使用者名稱 密碼 認證 (用於 ssl 串連上的 web 服務)

  3. 使用者名稱 密碼 挑戰式認證 (用於 client 的認證服務)

下面是基本的情境服務用的資料:

  • account:[id]:avatars set(id)
  • avatar:count id
  • avatar:[id]:version number
  • avatar:[id]:account id
  • avatar:[id]:scene string
  • avatar:[id]:available enum(open/delete)
  • avatar:[id]:data hashes
    • name string
    • figure string
  • world:scene hashes
    • [name] id
  • scene:count id
  • scene:[id]:name string
  • scene:[id]:available enum(open/close/delete)
  • scene:[id]:info hashes
    • time string
    • pc number
  • scene:[id]:pc hashes
    • [id] enum[online/offline]
  • scene:[id]:pc:[id] hashes
    • status string

使用者帳號下可以有許多遊戲角色,列表放在 account:[id]:avatars 下。

每個角色也擁有一個唯一 id 。這個 id 原則上和 account id 是獨立體系,但是為了人類好區格,avatar:count 的起點和 account:count 不同。

角色所在情境記錄一個字串的情境名 avatar:[id]:scene ,角色的其它各種資料放在一個 hashes 裡。

所有的情境索引方在 world:scene 下。如果日後有多個世界,可以採用 world:[id]:scene 。但目前不必考慮。

scene 下面的所有 pc 的線上狀態放在 scene:[id]:pc hashes 中,pc 離線也把它的 id 記錄在內,只有 pc 轉移情境才移除。

每個 PC 的位置狀態資訊記錄在 scene:[id]:pc:[id] 中,第一個 id 是 scene 的 id ,第二個則是 PC 的 avatar id 。

btw. 這是一份草稿,雖然思考不周,但足夠滿足項目一期的需求。當然許多欠考慮的地方也並非是考慮不到,而是希望盡量簡單,以滿足一期需求為目的。這個日後修改的代價並不大。

最後吐槽一下 Redis 的 Windows 版。辦公室的 Linux 伺服器還沒有裝好,我暫時在 Windows 下做開發。取了一份 google 搜到的 非官方 Redis 的 Windows 版 。為了圖方便,使用的是 luajit ffi 去調用 hiredis 的 dll 。一開始怎麼都搞不定。建立不了 socket 串連,出錯碼也取不到。

對比了原始碼,發現修改版把 C Struct 結構改了,前面增加了幾個域,而我以 hiredis 官方標準來定義的介面。

改好後,能夠正確取出出錯碼了。發現萬惡的 Windows socks api 需要調用 WSAStartup 才可以用。而 hiredis 的 Windows 修改版居然沒有去調用。讓我大費周折才改好,前後折騰了一個多小時。

再吐槽一下 hiredis 的 API 設計,居然依賴 C Struct 的布局。良好的 C 庫的介面設計不會這麼乾的吧。比如 lua ,又比如 zmq 。唉,用這種東西有點小不爽。不過比 C++ 庫還是好太多了。

[轉至雲風的部落格]開發筆記 (2) :redis 資料庫結構設計

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.