IM 的資料庫設計

黎偉傑發表於2018-10-23

本文主要是給一些開始接觸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實現。他們的邏輯相差還是比較大。

相關文章