阅读 7294

IM 的数据库设计

本文主要是给一些开始接触IM系统,做客户端本地数据库的人员介绍的。如有错误还请指出,thx.

自己目前做过两个IM系统,接触过一般常用的IM,都是自己开发没用第三方的,所以就总结一下IM系统中客户端的数据库的基本设计的字段。

这里只是一般需要字段,针对自己的需求(很多时候需要根据UI进行修改定制),需要自己看需求添加or删除。

主要表

一般主要需要建立的表包括:

  1. 会话表

  2. 聊天详情表

  3. 群组表

  4. 群组信息表

  5. 群成员

  6. 联系人表

表字段设计

a. 会话表

一般主要的字段如下:


id->auto increament primary key 自增长主键

uid->integer/varchar 该条消息所属消息,比如我登陆了,我发送/接收到消息入库的时候写入自己的uid,他的作用是多用户登陆的时候区分回话表

chatId->integet/varchar 服务器生产回话 id当前的回话id,它作用是标识一个回话,比如我跟你聊天or 你跟我聊天,我们的回话id应该是一致的,对于群聊也是,在群中发送消息,每个人的回话id是一致的。

c_id->varchar unique,他是标记一台设备上某个用户的唯一回话,用于更新避免插入多条数据的,可以用到sqlite的update or replace,他的值可以是hash(uid+chatid)或者其他,该字段可以只是客户端具有,客户端生成并且自己维护。

from->integer/varchar 发送人id(自己发送就是自己的uid,不然就是别人的uid)

to->integer/varchar 接收人id(uid/group_id)

last_msg->varchar 最后的一条消息内容
last_msg_id->integer/varchar  最后一条消息的id,作用是用于比较,比如在聊天页面中,删除了一条消息,撤回了一条消息之类的,这时候可以根据这个msg_id进行删除修改和更新。
chat_name -> varchar 聊天者的名称,比如我与你聊天,我的表中的这个字段就是你的name,你的表中就是我的name.

last_user_name->varchar 最后的发送者名称

last_time->integer 最后消息发送时间

chat_type->integer 回话类型(群组消息/个人聊天/系统消息)

msg_type->integer 消息类型(文字/图片/文件/音乐等)

unread_count->integer 改回话未读数目

复制代码

该表注意的问题:同一个回话不要插入多条数据,利用c_id来进行replace数据,比如收到一个新的回话消息存在就更新就好了。可以用触发器也可以用sql语句。

b. 聊天详情表

字段设计:


id->integer auto increament primary key 自增长主键

msg_id 消息唯一id,一般服务器生成,或者客户端本地使用UUID生成

uid->Interger/varchar 所属者uid

is_me->Integer 是否是自己发送的(UI显示区分)

from->Interger/varchar  发送者uid(可以是自己)

from_avatar->Interger/varchar 发送者头像

from_name-> varchar 发送者名称

to-> Interger/varchar 接受者(uid/group_id)

chat_type 会话类型

msg_type 消息类型

msg-> 消息内容

file_info->文件信息json格式

send_time->发送时间

send_status->发送状态 发送中,发送完成,发送失败

extra->把人插入 一般可以为null,预留的额外字段,使用JOSN字符串存储

复制代码

c. 群组表

字段设计


id->integer auto increament primary key 自增长主键

group_id Integer/varchar unique

group_name varchar 群组名称

group_name 群组头像

group_type 群组类型

group_num 群组数量

group_create_uid 群组创建者uid

复制代码

d. 群组信息表

群组信息的字段可以继承群列表的字段。字段设计


id->integer auto increament primary key 自增长主键

group_id Integer/varchar unique

group_name varchar 群组名称

group_name 群组头像

group_type 群组类型

group_num 群组数量

create_time 创建时间

group_create_uid 群组创建者uid

group_intrduce 群组简介

nick_name 个人的群昵称字段。

group_role 群组角色字段,比如你是管理员/群主/普通成员等 该字段的作用是可以用来做一个权限控制,比如在一些群里面,需要特定的人才可以拉人,需要群主才可以删除成员等,该字段是server下发的,根据不同的uid请求返回不同的role。

group_members 部分群成员的List的JSON数据,该字段看UI设计,可能有的UI在群信息页面默认显示几个群成员,然后点击进入通过另外的接口查看全部群成员。如果是这种情况下,可以在群信息接口下发该群的一些必要显示成员既可。当然,这个字段也可以不用,用一个或者群成员接口替换,查看群信息的时候也同时请求群信息和群成员接口也可以。

复制代码

e. 群成员表

字段设计


id->integer auto increament primary key 自增长主键

group_id Integer/varchar

user_name varchar 用户名

user_avatar varchar 头像

group_role 角色

复制代码

f. 联系人列表

字段设计


id->integer auto increament primary key 自增长主键

uid Integer/varchar unique

sex integer

birthday date


user_name varchar 用户名

user_avatar varchar 头像

relation interger 关系:比如好友/陌生人

复制代码

其他

  1. 可能在有些需求中,消息还会区分平台,比如ios/andoid/mac/windos等

  2. 关于信息的更新:某一个人的个人头像or昵称发生了变化,这时候,我们对应的消息页面的UI,朋友列表等需要更新。这种类型的通知,一般是通过tcp推送,后台通过查找该用户的uid然后查找到他的会话跟好友列表然后进行推送。

  3. 关于消息的设计:目前我所见是2种,一种是类型微信的常见,具有离线消息的概念,但是一旦客户端确认接收到,服务器将不会保存,也就是不能跨设备保存用户记录,一般用tcp实现。还有一种是有一个同步消息的概念可以跨设备,这种情况下一般使用Tcp+Http实现。他们的逻辑相差还是比较大。