蜜恋后端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

12 KiB

Dating App 数据库表设计与关系

1. 设计范围

本次先设计注册和用户资料相关的 Function 数据库,使用 MySQL 8.0,字符集为 utf8mb4,排序规则为 utf8mb4_unicode_ci。

当前范围包括:账号注册、密码登录、微信/谷歌登录、用户资料、自我介绍视频和身份证/护照文件。

2026-08-31 MVP 更新:邮箱和手机号统一使用 users.email_or_phone 一列;MVP 不使用 OTP,新注册账号直接激活。下方旧版验证码描述不再适用于当前接口,数据库迁移见 sql/migrate_auth_mvp_no_otp.sql。

2. ER 关系图

简化关系:

users (用户主表)
  │ 1
  ├──────── 0..1 user_profiles      用户资料
  ├──────── 0..1 user_locations     用户最近位置
  ├──────── 0..N auth_identities    微信/谷歌登录绑定
  ├──────── 0..N user_media         头像、视频、身份证/护照文件
  ├──────── 0..N swipes             发出的左滑/右滑/超级喜欢
  ├──────── 0..N matches            已建立的双向匹配
  ├──────── 0..N posts              Explore 帖子
  ├──────── 0..N post_likes         帖子点赞
  ├──────── 0..N post_comments      帖子评论
  └──────── 0..N chat_messages      聊天消息

verification_codes (验证码记录)
  └── 通过 target + channel 与注册账号逻辑关联
erDiagram
    USERS ||--o| USER_PROFILES : "拥有一份资料"
    USERS ||--o| USER_LOCATIONS : "拥有一个最近位置"
    USERS ||--o{ AUTH_IDENTITIES : "绑定登录方式"
    USERS ||--o{ USER_MEDIA : "上传媒体/证件"
    USERS ||--o{ SWIPES : "发起滑动"
    USERS ||--o{ MATCHES : "形成匹配"
    USERS ||--o{ POSTS : "发布帖子"
    POSTS ||--o{ POST_LIKES : "收到点赞"
    POSTS ||--o{ POST_COMMENTS : "收到评论"
    MATCHES ||--o| CONVERSATIONS : "拥有会话"
    CONVERSATIONS ||--o{ CHAT_MESSAGES : "包含消息"

    USERS {
        int id PK
        varchar email UK
        varchar phone UK
        varchar password_hash
        varchar status
        boolean email_verified
        boolean phone_verified
        datetime created_at
        datetime updated_at
    }

    USER_PROFILES {
        int id PK
        int user_id FK_UK
        varchar full_name
        varchar gender
        varchar birth_date
        varchar city
        varchar country
        text bio
    }

    AUTH_IDENTITIES {
        int id PK
        int user_id FK
        varchar provider
        varchar provider_user_id
        datetime created_at
    }

    USER_MEDIA {
        int id PK
        int user_id FK
        varchar media_type
        varchar storage_path
        varchar original_name
        varchar mime_type
        varchar review_status
        datetime created_at
    }

    VERIFICATION_CODES {
        int id PK
        varchar target
        varchar channel
        varchar code_hash
        datetime expires_at
        datetime used_at
        int attempts
        datetime created_at
    }

说明:VERIFICATION_CODES 暂时不设置 user_id 外键。用户还没有注册成功时,就需要先发送验证码,因此验证码通过 target + channel(邮箱或手机号)关联注册流程;验证成功后再更新 USERS.email_verified 或 USERS.phone_verified。

3. 表结构

3.1 users:用户主表

字段 类型 约束 说明
id INT 主键、自增 用户唯一编号
email VARCHAR(320) 唯一、可为空 邮箱账号
phone VARCHAR(32) 唯一、可为空 手机号账号
password_hash VARCHAR(256) 可为空 加密后的密码;第三方登录用户可以为空
status VARCHAR(20) 非空 pending、active、suspended
email_verified BOOLEAN 默认 false 邮箱是否已验证
phone_verified BOOLEAN 默认 false 手机号是否已验证
created_at DATETIME 非空 注册时间
updated_at DATETIME 非空 最后更新时间

注册账号至少提供邮箱或手机号之一。邮箱和手机号都允许为空,是为了支持只使用第三方账号注册。

3.2 user_profiles:用户个人资料表

字段 类型 约束 说明
id INT 主键、自增 资料记录编号
user_id INT 非空、唯一、外键 关联 users.id
full_name VARCHAR(120) 可为空 姓名/昵称
gender VARCHAR(30) 可为空 性别
birth_date VARCHAR(10) 可为空 生日,格式 YYYY-MM-DD
relationship_goal VARCHAR(30) 可为空 交友目标;新注册必须从 serious_relationship、casual_dates、new_friends、marriage 中单选
city VARCHAR(120) 可为空 所在城市
country VARCHAR(120) 可为空 所在国家,用于推荐和搜索排序
bio TEXT 可为空 个人简介

关系:一个用户最多有一份个人资料;删除用户时级联删除资料。

3.3 auth_identities:第三方登录绑定表

字段 类型 约束 说明
id INT 主键、自增 绑定记录编号
user_id INT 非空、外键 关联 users.id
provider VARCHAR(30) 非空 wechat 或 google
provider_user_id VARCHAR(255) 非空 第三方平台用户编号
created_at DATETIME 非空 绑定时间

唯一约束:provider + provider_user_id,防止同一个微信或谷歌账号绑定多个用户。

关系:一个用户可以绑定多个第三方登录方式;一条第三方绑定记录只属于一个用户。

3.4 verification_codes:验证码表

字段 类型 约束 说明
id INT 主键、自增 验证码记录编号
target VARCHAR(320) 非空、索引 邮箱地址或手机号
channel VARCHAR(10) 非空 email 或 phone
code_hash VARCHAR(256) 非空 验证码哈希值,不保存明文验证码
expires_at DATETIME 非空 过期时间
used_at DATETIME 可为空 使用时间,未使用时为空
attempts INT 默认 0 验证失败次数
created_at DATETIME 非空 生成时间

关系:验证码属于一次验证请求,不直接绑定用户。验证成功后更新 users 表的验证状态。

3.5 user_media:用户媒体和身份文件表

字段 类型 约束 说明
id INT 主键、自增 文件记录编号
user_id INT 非空、外键 关联 users.id
media_type VARCHAR(20) 非空 intro_video 或 identity_document
storage_path VARCHAR(500) 非空 文件存储地址
original_name VARCHAR(255) 可为空 原始文件名
mime_type VARCHAR(100) 可为空 文件类型
review_status VARCHAR(20) 默认 pending pending、approved、rejected
created_at DATETIME 非空 上传时间

关系:一个用户可以上传多个文件。数据库只保存文件地址和审核信息,视频、身份证和护照文件本身不直接存进数据库。

4. 关系汇总

主表 从表 关系 外键 删除策略
users user_profiles 一对零或一 user_profiles.user_id 删除用户时级联删除
users auth_identities 一对多 auth_identities.user_id 删除用户时级联删除
users user_media 一对多 user_media.user_id 删除用户时级联删除
users verification_codes 逻辑关联 target + channel 验证码独立过期

5. 注册流程对应的数据变化

  1. 用户提交邮箱/手机号和密码,写入 users,初始状态为 pending。
  2. 用户填写个人信息,写入 user_profiles。
  3. 系统发送验证码,写入 verification_codes,只保存验证码哈希。
  4. 验证成功后,更新 users.email_verified 或 users.phone_verified,并将状态改为 active。
  5. 用户上传视频或证件,在 user_media 中保存文件记录,初始审核状态为 pending。
  6. 微信/谷歌登录时,在 auth_identities 保存第三方账号和对应的 user_id。

6. 当前实现文件

7. Meet 与 Search 扩展表(2026-08-25)

表 关键字段 关系与用途
user_locations user_id、latitude、longitude 与用户一对一;用于附近的人和距离排序;位置请求的城市、区县保存在 user_profiles
swipes actor_id、target_id、direction 记录 like/pass/super_like;同一用户对唯一,撤销时删除记录
matches user1_id、user2_id、matched_at 双方相互喜欢(like 或 super_like)后生成;用户编号按小到大保存,确保一对用户只有一个匹配

隐私规则:user_media 中只有 profile_image 和 intro_video 会出现在 Meet/Search 响应里;identity_document 仅文件所属用户可访问。图片内容相似搜索依赖 ML,留到 Function 阶段完成后实现。

8. Explore 信息流扩展表(2026-08-26)

表 关键字段 用途
posts user_id、content、post_type、content_format、feeling、location_name、location_latitude、location_longitude 保存帖子文字、Markdown 格式、心情和所选地点的快照
post_media post_id、media_type、storage_path、position 保存帖子图片或视频,最多 9 张图片或 1 个视频
post_likes post_id、user_id 记录用户对帖子的点赞;同一用户对同一帖子只能点赞一次
post_comments post_id、user_id、content 保存帖子评论,删除帖子时级联删除

图片/视频附件已通过 post_media 接入;帖子创建后再上传媒体。音乐、直播和 ML 帖子分类尚未接入。

9. Chat 会话扩展表(2026-08-26)

表 关键字段 用途
conversations match_id 一个互相匹配关系最多对应一个会话
chat_messages conversation_id、sender_id、content 保存文本消息;消息只能由会话双方访问

聊天权限来自 matches 表:没有互相喜欢形成的匹配关系,不能创建会话或发送消息。消息撤回采用 deleted_at 标记,历史记录仍保留但对客户端隐藏正文。

10. 登录会话表(Login_Registration.pdf 要求)

user_sessions 保存 refresh token 会话,不保存明文 token:

字段 说明
user_id 会话所属用户
refresh_token_hash refresh token 的哈希值
expires_at 30 天默认过期时间
revoked_at logout 或 token 轮换后的撤销时间

access token 默认 15 分钟,refresh token 默认 30 天。应用启动时调用 /api/v1/auth/me;refresh 接口采用轮换策略,旧 refresh token 立即失效。

11. 帖子媒体与 AI Feed 问题(2026-08-27)

表 关键字段 用途
post_media post_id、media_type、storage_path 保存帖子图片/视频的文件信息,一条帖子最多 9 张图片或 1 个视频
feed_questions code、question_text、answer_type 保存系统提供的偏好问题,支持布尔和文字回答
user_question_answers user_id、question_id、回答内容 保存用户答案;同一用户对同一问题只有一条最新答案

删除帖子时级联删除 post_media 数据库记录,同时由接口删除实际文件。删除用户或问题时级联删除对应答案。AI 阶段将使用这些结构化答案训练或计算用户兴趣与匹配特征。

12. 国家和匹配度推荐(2026-09-01)

user_profiles.country 保存用户所在国家。Meet、用户搜索和 Explore 信息流按同城、同国家、其他国家分组;同组内按匹配百分比排序。匹配百分比由现有 user_interests 和双方共同回答的 user_question_answers 实时计算,因此不新增持久化分数字段,避免用户资料变化后产生过期分数。

user_profiles.county 保存区县,和国家 country 不同;与经纬度一同通过位置接口提交。位置接口同步更新 user_profiles.city,供同城推荐使用。历史用户的区县可为空。