雲風開發筆記(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 域做版本標識。
我不想讓各種服務可以直接讀寫這份資料,所以,會單獨寫一個認證伺服器做處理。
認證伺服器提供三項服務:
-
使用者註冊
-
使用者名稱 密碼 認證 (用於 ssl 連線上的 web 服務)
-
使用者名稱 密碼 挑戰式認證 (用於 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結構的