蜜恋后端
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.
 
 
 

13 KiB

Dating App Database Design and Relationships

1. Scope

This database design covers the first Function module: account registration and user profile management.

The database is designed for MySQL 8.0 using the utf8mb4 character set and the utf8mb4_unicode_ci collation.

The current scope includes:

  • Registration with a unified email-or-phone field
  • Password login
  • WeChat and Google login bindings
  • User profile information
  • Introduction videos
  • ID card or passport documents

MVP update (2026-08-31): email and phone now share users.email_or_phone. OTP is not used, and new accounts are active immediately. Legacy verification columns may remain only for non-destructive database compatibility.

2. ER Diagram

Simplified relationship overview:

users (user master table)
  | 1
  +-------- 0..1 user_profiles       User profile
  +-------- 0..1 user_locations      Latest user location
  +-------- 0..N auth_identities     WeChat/Google login bindings
  +-------- 0..N user_media          Images, videos, and identity documents
  +-------- 0..N swipes              Outgoing like/pass/super_like decisions
  +-------- 0..N matches             Mutual matches
  +-------- 0..N posts               Explore posts
  +-------- 0..N post_likes          Post likes
  +-------- 0..N post_comments       Post comments
  +-------- 0..N chat_messages       Chat messages

verification_codes (verification requests)
  +---- logically associated with registration through target + channel
erDiagram
    USERS ||--o| USER_PROFILES : "has one profile"
    USERS ||--o| USER_LOCATIONS : "has one latest location"
    USERS ||--o{ AUTH_IDENTITIES : "binds login methods"
    USERS ||--o{ USER_MEDIA : "uploads media"
    USERS ||--o{ SWIPES : "makes decisions"
    USERS ||--o{ MATCHES : "forms matches"
    USERS ||--o{ POSTS : "publishes posts"
    POSTS ||--o{ POST_LIKES : "receives likes"
    POSTS ||--o{ POST_COMMENTS : "receives comments"
    MATCHES ||--o| CONVERSATIONS : "has conversation"
    CONVERSATIONS ||--o{ CHAT_MESSAGES : "contains 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 does not have a direct user_id foreign key. A verification code may be sent before a user account has been created, so it is associated with the registration flow through target and channel (email or phone). After successful verification, the corresponding verification flag in users is updated.

3. Table Definitions

3.1 users: User Master Table

Column Type Constraints Description
id INT Primary key, auto-increment Unique user identifier
email VARCHAR(320) Unique, nullable Email account
phone VARCHAR(32) Unique, nullable Phone account
password_hash VARCHAR(256) Nullable Hashed password; can be empty for third-party-only accounts
status VARCHAR(20) Not null pending, active, or suspended
email_verified BOOLEAN Default false Whether the email has been verified
phone_verified BOOLEAN Default false Whether the phone has been verified
created_at DATETIME Not null Registration time
updated_at DATETIME Not null Last update time

At least one of email or phone is required for a normal registration. Both fields are nullable to support accounts created through third-party login providers.

3.2 user_profiles: User Profile Table

Column Type Constraints Description
id INT Primary key, auto-increment Profile record identifier
user_id INT Not null, unique, foreign key References users.id
full_name VARCHAR(120) Nullable Name or nickname
gender VARCHAR(30) Nullable Gender
birth_date VARCHAR(10) Nullable Date of birth in YYYY-MM-DD format
relationship_goal VARCHAR(30) Nullable Dating goal; new registrations require one of serious_relationship, casual_dates, new_friends, or marriage
city VARCHAR(120) Nullable Current city
country VARCHAR(120) Nullable Current country, used for discovery and search ordering
bio TEXT Nullable User biography

Relationship: one user can have zero or one profile. The profile is deleted automatically when its user is deleted.

3.3 auth_identities: Third-Party Login Binding Table

Column Type Constraints Description
id INT Primary key, auto-increment Binding record identifier
user_id INT Not null, foreign key References users.id
provider VARCHAR(30) Not null wechat or google
provider_user_id VARCHAR(255) Not null User identifier from the provider
created_at DATETIME Not null Binding time

Unique constraint: (provider, provider_user_id). This prevents one WeChat or Google account from being linked to multiple users.

Relationship: one user can have multiple third-party login bindings; each binding belongs to exactly one user.

3.4 verification_codes: Verification Code Table

Column Type Constraints Description
id INT Primary key, auto-increment Verification record identifier
target VARCHAR(320) Not null, indexed Email address or phone number
channel VARCHAR(10) Not null email or phone
code_hash VARCHAR(256) Not null Hashed verification code; plaintext is not stored
expires_at DATETIME Not null Expiration time
used_at DATETIME Nullable Time the code was used
attempts INT Default 0 Number of failed verification attempts
created_at DATETIME Not null Generation time

Relationship: each row represents one verification request. It is independent from a user record and expires after its validity period.

3.5 user_media: User Media and Identity Document Table

Column Type Constraints Description
id INT Primary key, auto-increment File record identifier
user_id INT Not null, foreign key References users.id
media_type VARCHAR(20) Not null intro_video or identity_document
storage_path VARCHAR(500) Not null Object-storage or filesystem path
original_name VARCHAR(255) Nullable Original uploaded filename
mime_type VARCHAR(100) Nullable File MIME type
review_status VARCHAR(20) Default pending pending, approved, or rejected
created_at DATETIME Not null Upload time

Relationship: one user can upload multiple media records. The database stores file metadata and the storage path; the video and identity document binary data are not stored directly in MySQL.

4. Relationship Summary

Parent table Child table Relationship Foreign key Delete behavior
users user_profiles One-to-zero-or-one user_profiles.user_id Cascade delete
users auth_identities One-to-many auth_identities.user_id Cascade delete
users user_media One-to-many user_media.user_id Cascade delete
users verification_codes Logical association target + channel Code expires independently

5. Registration Data Flow

  1. The user submits an email or phone number and password. A row is inserted into users with status pending.
  2. Basic profile information is inserted into user_profiles.
  3. The system sends a verification code and stores its hash in verification_codes.
  4. After successful verification, email_verified or phone_verified is set to true, and the user status becomes active.
  5. When the user uploads an introduction video or identity document, a record is inserted into user_media with review status pending.
  6. When the user signs in with WeChat or Google, the provider account is stored in auth_identities and linked to the corresponding user_id.

6. Implementation Files

7. Meet and Search Extension Tables (2026-08-25)

Table Key columns Relationship and purpose
user_locations user_id, latitude, longitude One-to-one with a user; supports nearby search and distance ordering; city and county from location requests are saved in user_profiles
swipes actor_id, target_id, direction Stores like/pass/super_like; one decision per user pair, deleted on undo
matches user1_id, user2_id, matched_at Created after reciprocal like or super_like; IDs are stored in ascending order to keep each pair unique

Privacy rule: only profile_image and intro_video media appear in Meet/Search responses. An identity_document can only be downloaded by its owner. Content-based image search depends on ML and remains scheduled for after the Function stage.

8. Explore Feed Extension Tables (2026-08-26)

Table Key columns Purpose
posts user_id, content, post_type, content_format, feeling, location_name, location_latitude, location_longitude Stores post text, Markdown mode, feeling, and a snapshot of the selected place
post_media post_id, media_type, storage_path, position Stores up to nine images or one video per post
post_likes post_id, user_id Stores likes; one user can like a post only once
post_comments post_id, user_id, content Stores comments and cascades when a post is deleted

Image/video attachments are already stored through post_media after post creation. Music, live streaming, and ML-based post classification remain future work.

9. Chat Conversation Extension Tables (2026-08-26)

Table Key columns Purpose
conversations match_id At most one conversation belongs to a mutual match
chat_messages conversation_id, sender_id, content Stores text messages accessible only to the two matched users

Chat authorization comes from matches: users cannot create a conversation or send messages without a mutual match. Message recall uses a deleted_at marker; the record remains for history while the body is hidden from clients.

10. Login Session Table (required by Login_Registration.pdf)

user_sessions stores refresh-token sessions without storing the plaintext token:

Column Description
user_id User who owns the session
refresh_token_hash Hashed refresh token
expires_at 30-day default expiration
revoked_at Set during logout or token rotation

Access tokens default to 15 minutes and refresh tokens to 30 days. The app calls /api/v1/auth/me at startup. Refresh uses token rotation, so the previous refresh token becomes invalid immediately.

11. Post Media and AI Feed Questions (2026-08-27)

Table Key columns Purpose
post_media post_id, media_type, storage_path Stores post image/video files; one post supports up to 9 images or 1 video
feed_questions code, question_text, answer_type Stores preference questions with boolean or text answers
user_question_answers user_id, question_id, answer fields Stores one latest answer per user and question

Deleting a post cascades its post_media records and the API removes the physical files. Deleting a user or question cascades its answers. The later ML stage can use these structured answers as user-interest and matching features.

12. Country and Compatibility Ranking (2026-09-01)

user_profiles.country stores the user's country. Meet, user search, and the Explore feed group results by same city, same country, and other countries; results within a group are ranked by compatibility percentage. Compatibility is calculated from existing user_interests and mutually answered user_question_answers, so no persisted score column is added and scores cannot become stale when profile data changes.

user_profiles.county stores the district/county, separately from the nation-level country. The location endpoint updates it together with user_profiles.city and the coordinates. Existing users may have a NULL county.