1. 程式人生 > >雲風開發筆記(2) Redis資料庫結構設計

雲風開發筆記(2) Redis資料庫結構設計

使用者系統使用 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))
end

function emailEncode(str)
    return string.gsub(str,"([^%
[email protected]
])",_encode) end

當然,解碼回來也很簡單

local function _decode(str)
    return string.char(tonumber(str,16))
end

function 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資料庫結構設計

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

redis資料庫結構設計

    之前遊戲開發服務端都是用純c++來寫,現在很多寫遊戲伺服器越來越傾向指令碼語言,因為用c++來寫一些邏輯的確是痛苦之極,當然如果追求效率的還是用c/c++實現更好。 最近時間自己通過研究瞭解雲風寫的skynet框架學習了lua,研究skynet其實是想把這框架用到公

Vue-cli開發筆記一----------項目的結構

web node lin sch scrip base via 裏的 ack 配置文件package.json: 搜索了配置的原理:https://segmentfault.com/a/1190000000344102 裏面講到:npm會在package.json文件中找s

python 全棧開發筆記 2

定義 dir 操作 lte 映射 密碼錯誤 fun 改密 dom 函數 函數式:將某功能代碼封裝到函數中,日後便無需重復編寫,僅調用函數即可 面向對象:對函數進行分類和封裝,讓開發“更快更好更強...” 函數式編程最重要的是增強代碼的重用性和可讀性 def xx():

微信小程式開發筆記2——自定義導航欄元件

本文主要是熟悉微信小程式自定義元件的開發,以一個常見的導航欄(Tabbar)需求為例。 官方文件:https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/ 首先我們先看一

redis資料庫結構

一 全域性命令 1.1 檢視所有的key keys * 1.2key的總數 dbsize 1.3 檢查key是否存在 exists username 1.4 刪除key del password 1.5key過期,超過時間自動刪 expi

Redis資料庫結構與讀寫原理

此文已由作者趙計剛薪授權網易雲社群釋出。 歡迎訪問網易雲社群,瞭解更多網易技術產品運營經驗。 1、資料庫結構 每一個redis伺服器內部的資料結構都是一個redisDb[],該陣列的大小可以在redis.conf中配置("database 16",預設為16),而我們所有的快取操作

Unity5 Survival Shooter開發筆記2

相機跟隨人物移動 先介紹一個屬性: public static float deltaTime; 這是一個只讀的屬性,返回上一幀到這一幀的時間。如果你想要在每一幀增加或者減少資料,需要用資料乘以deltaTime這個資料,比如: using UnityEngi

Redis學習筆記(2)-redis的啟動與關閉

啟動redis 1. 直接啟動 $ redis-server # 預設埠6379 $ redis-server --port 6380 # 指定埠啟動 2. 通過初始化指令碼啟動 第一種啟動方式,在測試環境中用的比較多,實際在生產環境中,大多數

go學習筆記(2):資料結構

Go語言不是一門面向物件的語言,沒有物件和繼承,也沒有面向物件的多型、重寫相關特性。 Go所擁有的是資料結構,它可以關聯方法。Go也支援簡單但高效的組合(Composition),請搜尋面向物件和組合。 雖然Go不支援面向物件,但Go通過定義資料結構的方式,也能實現與Class相似的功能。 一個簡單的例子,

圖形學學習筆記2 網格資料結構

1 網格資料應用 渲染 集合查詢(某個面的頂點有哪些,兩個點是否相連等) 幾何操作(新增、刪除某個點/線/面;網格化簡;頂點分裂,邊緣摺疊) 2 網格資料的儲存 一般的網格儲存(很難有效實現) 什麼是好的資料儲存?(空間複雜度,時間(構建時間,查詢時間,修改時間),

Redis資料庫學習筆記02--Redis資料庫簡單型別命令

目錄 1.redis資料庫內對於string型別的相關操作 1.1 新增/讀取/修改 單一string型別鍵值對 1.2 新增/讀取 多個string型別鍵值對 1.3 設定 string鍵值對的過期時間 1.4 向string鍵值對的value中追

android模組化app開發筆記-2外掛間佈局檔案共享

  android程式設計時佈局檔案,圖片資源等都是放在同一個資料夾下,這樣照成一個問題就是我們想重用UI佈局檔案和圖片時就還需要其分離這些資料,相信大部分android程式設計師都遇到過這樣的問題,其痛苦程度不亞於世紀末日趕不上諾亞方舟。    今天我用apkplug框

騰訊 Centos7.4 安裝配置 redis 資料庫

一、安裝redis    1、設定redis的倉庫地址, 執行命令:yum install epel-release    出現下圖即設定成功    2、安裝redis       執行命令如下: yum install redis3、啟動redisservice redi

微信小程式支付開發筆記2--生成簽名-統一下單-二次簽名

使用者選擇商品發起購買請求,後端接收到請求後,先生成本地訂單,以得到一個本地訂單的商戶訂單號。同時從表中讀取該使用者的openID。 我是用一個物件pay來存統一下單需要傳的引數,pay的欄位如下(部

Django+xadmin開發筆記(四) mysql資料庫資料展示到前段頁面

(一)展示到前端前,我們先從把資料從資料庫拿到後臺。通過我們之前的方法。message = Noneall_name = UserMessage.object.fillter("資料字欄位"="條件")if all_name:    message = all_name[0]

開發筆記Redis 3.0 Windows x64版本的安裝

1,目標環境 Windows 7 64位 2,材料 (1)Redis 3.0.504 Windows x64位版本(注意:Windows的版本要比其他平臺的版本舊一些) 下載地址:【https://github.com/MSOpenTech/redis/releases】

CocosCreator開發筆記(2)-Linux系統用Nginx搭建Web釋出伺服器

上文介紹了用簡單的Python命令搭建CocosCreator的Web釋出伺服器,這一般在開發除錯中使用。如果是用於正式伺服器,則還是需要用專業的Web伺服器軟體,以滿足高效能、靈活、穩定的商用需求。 Nginx簡介 Nginx是一款高效能、輕量級的HT

Redis資料庫結構介紹

首先Redis是採用字典結構以健值對形式進行存取的 當我們查詢2的時候就查出了對應的 color,name,price屬性所對應的值, 如果這裡我們要想多加一個屬性怎麼辦? id為1的增加了date的值,那麼對於2和3來說date欄位值是冗餘的,可想而知當不同的資料需要

Redis資料庫結構和持久化

Redis資料庫,持久化 資料庫 Redis伺服器將所有的資料庫都儲存在伺服器狀態redis.h/redisServer結構的