接上回,按照我们一期项目的需求,昨天我简单设计了数据库里的数据格式。数据库采用的是 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))
end function emailEncode(str)
return string.gsub(str,"([^%w_@.])",_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 数据库结构设计的更多相关文章

  1. [转至云风的博客]谈谈陌陌争霸在数据库方面踩过的坑( Redis 篇)

    « 谈谈陌陌争霸在数据库方面踩过的坑(芒果篇) | 返回首页 | linode 广告时间 » 谈谈陌陌争霸在数据库方面踩过的坑( Redis 篇) 注:陌陌争霸的数据库部分我没有参与具体设计,只是参与 ...

  2. Django 博客开发教程目录索引

    Django 博客开发教程目录索引 本项目适合 0 基础的 Django 开发新人. 项目演示地址:Black & White,代码 GitHub 仓库地址:zmrenwu/django-bl ...

  3. 亚马逊云架设WordPress博客

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 这篇文章介绍如何在亚马逊云架设WordPress博客.最强的云,加上最流行的建站工 ...

  4. Padrino 博客开发示例

    英文版出处:http://www.padrinorb.com/guides/blog-tutorial 楼主按 拿作者自己的话说:Padrino(谐音:派骓诺)是一款基于Sinatra的优雅的Web应 ...

  5. Django博客开发实践,初学者开发经验

    python,Django初学者,开发简易博客,做了一下笔记,记录了开发的过程,功力浅薄,仅供初学者互相 交流,欢迎意见建议.具体链接:Django博客开发实践(一)--分析需求并创建项目 地址:ht ...

  6. Django个人博客开发 | 前言

    本渣渣不专注技术,只专注使用技术,不是一个资深的coder,是一个不折不扣的copier 1.前言 自学 Python,始于 Django 框架,Scrapy 框架,elasticsearch搜索引擎 ...

  7. django 简易博客开发 5 markdown支持、代码高亮、gravatar头像服务

    上一篇博客介绍了comments库使用及ajax支持,现在blog已经具备了基本的功能,但是只能发表文字,不支持富文本编辑.今天我们利用markdown添加富文本支持. markdown语法说明: h ...

  8. django 简易博客开发 4 comments库使用及ajax支持

    首先还是贴一下源代码地址  https://github.com/goodspeedcheng/sblog 上一篇文章我们介绍了静态文件使用以及如何使用from实现对blog的增删改,这篇将介绍如何给 ...

  9. django 简易博客开发 3 静态文件、from 应用与自定义

    首先还是贴一下源代码地址  https://github.com/goodspeedcheng/sblog 上一篇博客我们介绍了 django 如何在views中使用templates以及一些常用的数 ...

随机推荐

  1. 学习活动管理系统:LAMS

    学习活动管理系统:LAMS 一.总结 基于java的cms 二.LAMS Learning Activity Management System,学习活动管理系统. 数字化学习已经具有完整的发展方法来 ...

  2. HTML基础第九讲---表单

    转自:https://i.cnblogs.com/posts?categoryid=1121494 最基本的留言版应该大家都用过吧!没错这就是一个表单运用很好的例子.表单提供了一个管道让读者发表心声, ...

  3. solr索引创建流程

    solr索引创建流程: 分词组件Tokenizer 分词组件(Tokenizer)会做以下几件事情(这个过程称为:Tokenize),处理得到的结果是词汇单元(Token). 1.将文档分成一个一个单 ...

  4. Win7下IE11点击无反应的解决方法

    平台:win7 sp1 32bit 问题:点击Internet Explorer在开始菜单.快捷栏的图标和安装目录下的程序均没有反应,鼠标在变成漏斗后恢复原状再无反应.但搜狗浏览器和360浏览器下使用 ...

  5. Flask项目之手机端租房网站的实战开发(十二)

    说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家! 接着上一篇博客继续往下写 :https://blog.csdn.net/qq_41782425/article/details/8 ...

  6. ANSI转UTF-8中文无乱码解决方案

    近期做的项目需要使用Doxygen生成文档,由于前期代码不是本人完成,他使用的是ANSI格式的文件,后来我用Notepad++写其他文件时,默认保存为UTF-8 无BOM编码格式,因此整个项目文件中既 ...

  7. [Angular] Style HTML elements in Angular using ngStyle

    We will learn how to make use of the ngStyle directive to directly add multiple style attributes to ...

  8. Python模块学习笔记— —random

    Python中的random模块用于生成随机数. random.random 函数原型 random.random() 生成一个范围在[0,1)的随机浮点数. import random print ...

  9. js闭包作用(避免使用全局变量)

    js闭包作用(避免使用全局变量) 一.总结 1.优点::可以把局部变量驻留在内存中,可以避免使用全局变量; 2.缺点:也有占用更多内存的缺点,用完要及时让垃圾回收器回收  fn=null //应及时解 ...

  10. (转)把Sublime Text 2 加入右键菜单(带图标),Edit with Sublime Text

    转自 http://www.turen.me/archives/509 Sublime Text 2 是现在很受大家欢迎的编辑器了,不仅是在web前端,在书定简单的php.Js等代码时,也是相当的好用 ...