项目架构和模块
项目架构图
Web 框架
本项目使用 Gin 作为 Web 框架,提供 HTTP 服务。 其中,将 Gin 的路由和 handler 封装成 gateway, 用于统一接入网关。 路由包括用户服务、好友服务、消息服务等。 网关会对请求通过用户服务使用 Bearer Token 进行鉴权,并将请求转发到对应的服务中。
微服务框架
项目中使用 Go-Zero 作为微服务框架,提供服务注册与发现等功能。 每个单独的服务分别对应 service 目录下的一个子目录,每个子目录下包含了对应的服务配置、服务逻辑、数据访问层、数据模型等。
数据库
数据库使用 MySQL, 用于存储用户信息、好友信息、消息记录等。
项目中使用Gorm 作为 ORM 框架,进行数据库操作。
Redis 作为缓存中间件,Minio 作为 bucket 存储组件。
user 服务数据库定义

User 表结构
| 字段名 | 类型 | 属性 | 说明 |
|---|---|---|---|
| UID | bigint | primaryKey, autoIncrement, index | 用户唯一标识符 |
| Username | varchar(64) | uniqueIndex | 用户名 |
| Password | varchar(128) | 用户密码 | |
| CreatedAt | timestamp | 创建时间 | |
| UpdatedAt | timestamp | 更新时间 | |
| DeletedAt | timestamp | index | 删除时间 |
说明:
UID是主键,且自动递增,类型为bigint,并且有索引。Username是唯一索引,确保每个用户的用户名唯一。Password存储用户密码,长度限制为 128 字符。CreatedAt,UpdatedAt自动记录创建和更新的时间。DeletedAt是一个逻辑删除字段,提供软删除功能,并且有索引。
UserProfile 表结构
| 字段名 | 类型 | 属性 | 说明 |
|---|---|---|---|
| ID | bigint | primaryKey, autoIncrement | 主键 |
| UID | bigint | uniqueIndex, not null | 用户唯一标识符 |
| Avatar | varchar(256) | 用户头像 URL | |
| Nickname | varchar(64) | 用户昵称 | |
varchar(128) | 用户邮箱 | ||
| Status | tinyint | default:1 | 用户状态 |
| CreatedAt | timestamp | 创建时间 | |
| UpdatedAt | timestamp | 更新时间 | |
| DeletedAt | timestamp | index | 删除时间 |
说明:
UID是外键,唯一索引,指向User表中的UID,确保一对一关系。Avatar字段用于存储用户头像的 URL。Nickname字段存储用户的显示昵称。Email字段存储用户邮箱地址。Status字段默认值为1,表示用户的当前状态,暂时未使用到。CreatedAt,UpdatedAt,DeletedAt记录对应的时间信息。
关系设计说明
User表与UserProfile表之间是 一对一 关系。通过UID字段连接,UserProfile表中的UID字段是外键,指向User表中的UID。- GORM 通过
foreignKey:UID和references:UID来定义这两个表的外键关系。UserProfile中每条记录都唯一对应User表中的一条记录。
friend 服务数据库定义

Friend 表结构
| 字段名 | 类型 | 属性 | 说明 |
|---|---|---|---|
| ID | bigint | primaryKey, autoIncrement | 主键 |
| UserID | bigint | index, not null | 用户 ID |
| FriendID | bigint | index, not null | 好友 ID |
| Status | tinyint | not null | 好友状态 |
| InitiatorID | bigint | not null | 发起好友请求的用户 |
| CreatedAt | timestamp | 创建时间 | |
| UpdatedAt | timestamp | 更新时间 | |
| DeletedAt | timestamp | index | 删除时间 |
说明:
UserID和FriendID用于存储好友关系的用户和他们的好友,两个字段都有索引。Status是一个枚举类型,定义了好友关系的不同状态(如未添加、已添加等)。InitiatorID记录发起好友请求的用户 ID,用于区分谁发起了好友关系。
FriendGroup 表结构
| 字段名 | 类型 | 属性 | 说明 |
|---|---|---|---|
| ID | bigint | primaryKey, autoIncrement | 主键 |
| UID | bigint | index, not null | 分组所属用户 ID |
| Name | varchar(64) | not null | 分组名称 |
| CreatedAt | timestamp | 创建时间 | |
| UpdatedAt | timestamp | 更新时间 | |
| DeletedAt | timestamp | index | 删除时间 |
说明:
UID表示分组所属用户。Name是分组的名称,长度限制为 64 字符,不能为空。GroupMembers定义了与FriendGroupMember表的关联关系,通过外键GroupID关联分组成员。
FriendGroupMember 表结构
| 字段名 | 类型 | 属性 | 说明 |
|---|---|---|---|
| GroupID | bigint | primaryKey, not null | 分组 ID |
| FriendID | bigint | primaryKey, not null | 好友 ID |
| CreatedAt | timestamp | 创建时间 | |
| UpdatedAt | timestamp | 更新时间 | |
| DeletedAt | timestamp | index | 删除时间 |
说明:
- 复合主键:
GroupID和FriendID共同组成复合主键,确保每个好友在每个分组中只出现一次,避免重复记录。 GroupID:表示好友所属分组的 ID。FriendID:表示被分配到该分组的好友 ID。CreatedAt,UpdatedAt,DeletedAt:分别用于记录创建时间、更新时间和删除时间,其中DeletedAt提供软删除功能并有索引。
功能
- 唯一性约束:通过复合主键,确保在每个分组中同一个好友只能存在一次。
- 多对多关系:该表用于管理
FriendGroup和Friend之间的多对多关系,一个分组可以包含多个好友,一个好友也可以属于多个分组。
关系设计说明
- 好友关系 (
Friend):每条记录表示用户与另一个用户(好友)的关系,包含好友状态和请求发起者信息。 - 好友分组 (
FriendGroup):用户可以创建多个好友分组,每个分组属于特定用户。 - 好友分组成员 (
FriendGroupMember):用于记录分组中的好友,通过GroupID字段与FriendGroup表关联,通过FriendID字段关联Friend表中的好友。
关系设计
FriendGroup和FriendGroupMember之间是一对多关系,通过GroupID连接,每个分组可以包含多个好友。Friend表和FriendGroupMember表通过FriendID关联,确保分组成员是用户的好友。
message 服务数据库定义

Message 表结构
| 字段名 | 类型 | 属性 | 说明 |
|---|---|---|---|
| MsgID | bigint | primaryKey, autoIncrement | 消息唯一标识符 |
| SenderId | bigint | index, not null | 发送者用户 ID |
| ReceiverId | bigint | index, not null | 接收者用户 ID |
| Content | text | not null | 消息内容 |
| Timestamp | timestamp | not null | 消息发送时间 |
说明:
MsgID是主键,自动递增,用于唯一标识每条消息。SenderId和ReceiverId表示消息发送者和接收者的用户 ID,都有索引以优化查询性能。Content字段存储消息的文本内容,类型为text,长度没有限制。Timestamp字段记录消息发送的时间,确保每条消息有一个时间戳。
关系设计说明
- 发送者和接收者:
SenderId和ReceiverId都表示用户之间的点对点消息通信,这两个字段使用了索引以提高检索发送或接收消息的效率。 - 消息内容:
Content字段类型为text,适合存储长文本内容,能够支持较长的消息。
GroupMessage 表结构
| 字段名 | 类型 | 属性 | 说明 |
|---|---|---|---|
| MsgID | bigint | primaryKey, autoIncrement | 消息唯一标识符 |
| SenderId | bigint | index, not null | 发送者用户 ID |
| GroupId | bigint | index, not null | 群组 ID |
| Content | text | not null | 消息内容 |
| Timestamp | timestamp | not null | 消息发送时间 |
说明:
MsgID是群消息的唯一标识符,自动递增,作为主键。SenderId表示发送消息的用户,有索引以优化查询。GroupId表示消息所属的群组,有索引以加速消息的查询。Content字段为消息的文本内容,类型为text,无长度限制。Timestamp记录消息的发送时间。
ChatGroup 表结构
| 字段名 | 类型 | 属性 | 说明 |
|---|---|---|---|
| GID | bigint | primaryKey, autoIncrement | 群组唯一标识符 |
| Name | varchar(64) | uniqueIndex | 群组名称 |
| Avatar | varchar(256) | 群组头像 URL | |
| OwnerID | bigint | index, not null | 群主用户 ID |
| CreatedAt | timestamp | 创建时间 | |
| UpdatedAt | timestamp | 更新时间 | |
| DeletedAt | timestamp | index | 删除时间 |
说明:
GID是群组的唯一标识符,自动递增,作为主键。Name是群组名称,有唯一索引以确保每个群组的名称唯一。Avatar是群组的头像 URL,最多允许 256 字符。OwnerID是群主的用户 ID,有索引以优化查询。CreatedAt,UpdatedAt,DeletedAt记录群组的创建、更新和删除时间。
ChatGroupMember 表结构
| 字段名 | 类型 | 属性 | 说明 |
|---|---|---|---|
| GroupID | bigint | primaryKey, not null | 群组 ID |
| UserID | bigint | primaryKey, not null | 用户 ID |
| CreatedAt | timestamp | 创建时间 | |
| UpdatedAt | timestamp | 更新时间 |
说明:
GroupID和UserID组成复合主键,确保用户在每个群组中的唯一性。CreatedAt,UpdatedAt用于记录记录的创建和更新时间。
关系设计说明
- 群组与群成员 (
ChatGroup和ChatGroupMember):ChatGroupMember表通过GroupID连接到ChatGroup表,表示群组与成员之间的多对多关系。每个用户可以加入多个群组,每个群组也可以有多个用户。 - 群组消息与群成员 (
GroupMessage和ChatGroupMember):GroupMessage表通过SenderId和GroupId连接到相应的群组和发送消息的用户。每条消息属于一个特定群组,并由一个特定的群成员发送。