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

250 lines
11 KiB

USE dating_app;
CREATE TABLE IF NOT EXISTS users (
id INT AUTO_INCREMENT PRIMARY KEY,
email_or_phone VARCHAR(320) UNIQUE,
password_hash VARCHAR(256),
status VARCHAR(20) NOT NULL DEFAULT 'active',
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE IF NOT EXISTS user_profiles (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL UNIQUE,
full_name VARCHAR(120),
gender VARCHAR(30),
birth_date VARCHAR(10),
city VARCHAR(120),
county VARCHAR(120),
country VARCHAR(120),
relationship_goal VARCHAR(30),
bio TEXT,
occupation VARCHAR(120),
education VARCHAR(120),
height_cm INT,
beliefs VARCHAR(120),
smoking VARCHAR(50),
drinking VARCHAR(50),
pets VARCHAR(120),
exercise VARCHAR(50),
INDEX ix_user_profiles_city_country (city, country),
CONSTRAINT fk_user_profiles_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE IF NOT EXISTS user_interests (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
name VARCHAR(120) NOT NULL,
created_at DATETIME NOT NULL,
CONSTRAINT uq_user_interest_name UNIQUE (user_id, name),
CONSTRAINT fk_user_interests_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
INDEX ix_user_interests_user (user_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE IF NOT EXISTS auth_identities (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
provider VARCHAR(30) NOT NULL,
provider_user_id VARCHAR(255) NOT NULL,
created_at DATETIME NOT NULL,
CONSTRAINT uq_auth_provider_user UNIQUE (provider, provider_user_id),
CONSTRAINT fk_auth_identities_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE IF NOT EXISTS user_media (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
media_type VARCHAR(20) NOT NULL,
storage_path VARCHAR(500) NOT NULL,
original_name VARCHAR(255),
mime_type VARCHAR(100),
review_status VARCHAR(20) NOT NULL DEFAULT 'pending',
created_at DATETIME NOT NULL,
INDEX ix_user_media_user (user_id),
CONSTRAINT fk_user_media_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE IF NOT EXISTS user_locations (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL UNIQUE,
latitude DOUBLE NOT NULL,
longitude DOUBLE NOT NULL,
updated_at DATETIME NOT NULL,
CONSTRAINT fk_user_locations_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE IF NOT EXISTS user_sessions (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
refresh_token_hash VARCHAR(256) NOT NULL UNIQUE,
expires_at DATETIME NOT NULL,
created_at DATETIME NOT NULL,
revoked_at DATETIME NULL,
CONSTRAINT fk_user_sessions_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
INDEX ix_user_sessions_user (user_id),
INDEX ix_user_sessions_expires (expires_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE IF NOT EXISTS swipes (
id INT AUTO_INCREMENT PRIMARY KEY,
actor_id INT NOT NULL,
target_id INT NOT NULL,
direction VARCHAR(10) NOT NULL,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
CONSTRAINT uq_swipe_actor_target UNIQUE (actor_id, target_id),
CONSTRAINT ck_swipe_not_self CHECK (actor_id <> target_id),
CONSTRAINT ck_swipe_direction CHECK (direction IN ('like', 'pass', 'super_like')),
CONSTRAINT fk_swipes_actor FOREIGN KEY (actor_id) REFERENCES users(id) ON DELETE CASCADE,
CONSTRAINT fk_swipes_target FOREIGN KEY (target_id) REFERENCES users(id) ON DELETE CASCADE,
INDEX ix_swipes_actor (actor_id),
INDEX ix_swipes_target (target_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE IF NOT EXISTS matches (
id INT AUTO_INCREMENT PRIMARY KEY,
user1_id INT NOT NULL,
user2_id INT NOT NULL,
matched_at DATETIME NOT NULL,
CONSTRAINT uq_match_user_pair UNIQUE (user1_id, user2_id),
CONSTRAINT ck_match_canonical_order CHECK (user1_id < user2_id),
CONSTRAINT fk_matches_user1 FOREIGN KEY (user1_id) REFERENCES users(id) ON DELETE CASCADE,
CONSTRAINT fk_matches_user2 FOREIGN KEY (user2_id) REFERENCES users(id) ON DELETE CASCADE,
INDEX ix_matches_user1 (user1_id),
INDEX ix_matches_user2 (user2_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE IF NOT EXISTS posts (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
content TEXT NOT NULL,
post_type VARCHAR(20) NOT NULL DEFAULT 'text',
content_format VARCHAR(10) NOT NULL DEFAULT 'plain',
feeling VARCHAR(50) NULL,
location_name VARCHAR(255) NULL,
location_latitude DOUBLE NULL,
location_longitude DOUBLE NULL,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
CONSTRAINT ck_posts_type CHECK (post_type IN ('text', 'image', 'video')),
CONSTRAINT fk_posts_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
INDEX ix_posts_user (user_id),
INDEX ix_posts_created (created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE IF NOT EXISTS post_media (
id INT AUTO_INCREMENT PRIMARY KEY,
post_id INT NOT NULL,
media_type VARCHAR(20) NOT NULL,
storage_path VARCHAR(500) NOT NULL,
original_name VARCHAR(255),
mime_type VARCHAR(100) NOT NULL,
size_bytes INT NOT NULL,
position INT NOT NULL DEFAULT 0,
created_at DATETIME NOT NULL,
CONSTRAINT ck_post_media_type CHECK (media_type IN ('image', 'video')),
CONSTRAINT fk_post_media_post FOREIGN KEY (post_id) REFERENCES posts(id) ON DELETE CASCADE,
INDEX ix_post_media_post (post_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE IF NOT EXISTS post_likes (
id INT AUTO_INCREMENT PRIMARY KEY,
post_id INT NOT NULL,
user_id INT NOT NULL,
created_at DATETIME NOT NULL,
CONSTRAINT uq_post_like UNIQUE (post_id, user_id),
CONSTRAINT fk_post_likes_post FOREIGN KEY (post_id) REFERENCES posts(id) ON DELETE CASCADE,
CONSTRAINT fk_post_likes_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
INDEX ix_post_likes_post (post_id),
INDEX ix_post_likes_user (user_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE IF NOT EXISTS post_comments (
id INT AUTO_INCREMENT PRIMARY KEY,
post_id INT NOT NULL,
user_id INT NOT NULL,
parent_comment_id INT NULL,
content TEXT NOT NULL,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
CONSTRAINT fk_post_comments_post FOREIGN KEY (post_id) REFERENCES posts(id) ON DELETE CASCADE,
CONSTRAINT fk_post_comments_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
CONSTRAINT fk_post_comments_parent FOREIGN KEY (parent_comment_id) REFERENCES post_comments(id) ON DELETE CASCADE,
INDEX ix_post_comments_post (post_id),
INDEX ix_post_comments_user (user_id),
INDEX ix_post_comments_parent (parent_comment_id),
INDEX ix_post_comments_created (created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE IF NOT EXISTS comment_likes (
id INT AUTO_INCREMENT PRIMARY KEY,
comment_id INT NOT NULL,
user_id INT NOT NULL,
created_at DATETIME NOT NULL,
CONSTRAINT uq_comment_like UNIQUE (comment_id, user_id),
CONSTRAINT fk_comment_likes_comment FOREIGN KEY (comment_id) REFERENCES post_comments(id) ON DELETE CASCADE,
CONSTRAINT fk_comment_likes_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
INDEX ix_comment_likes_comment (comment_id),
INDEX ix_comment_likes_user (user_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE IF NOT EXISTS conversations (
id INT AUTO_INCREMENT PRIMARY KEY,
match_id INT NOT NULL UNIQUE,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
CONSTRAINT fk_conversations_match FOREIGN KEY (match_id) REFERENCES matches(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE IF NOT EXISTS chat_messages (
id INT AUTO_INCREMENT PRIMARY KEY,
conversation_id INT NOT NULL,
sender_id INT NOT NULL,
content TEXT NOT NULL,
message_type VARCHAR(20) NOT NULL DEFAULT 'text',
created_at DATETIME NOT NULL,
deleted_at DATETIME NULL,
CONSTRAINT ck_chat_messages_type CHECK (message_type IN ('text')),
CONSTRAINT fk_chat_messages_conversation FOREIGN KEY (conversation_id) REFERENCES conversations(id) ON DELETE CASCADE,
CONSTRAINT fk_chat_messages_sender FOREIGN KEY (sender_id) REFERENCES users(id) ON DELETE CASCADE,
INDEX ix_chat_messages_conversation (conversation_id),
INDEX ix_chat_messages_sender (sender_id),
INDEX ix_chat_messages_created (created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE IF NOT EXISTS feed_questions (
id INT AUTO_INCREMENT PRIMARY KEY,
code VARCHAR(100) NOT NULL UNIQUE,
question_text VARCHAR(500) NOT NULL,
question_text_zh VARCHAR(500),
answer_type VARCHAR(20) NOT NULL DEFAULT 'boolean',
is_active BOOLEAN NOT NULL DEFAULT TRUE,
sort_order INT NOT NULL DEFAULT 0,
created_at DATETIME NOT NULL,
CONSTRAINT ck_feed_questions_type CHECK (answer_type IN ('boolean', 'text')),
INDEX ix_feed_questions_active (is_active)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE IF NOT EXISTS user_question_answers (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
question_id INT NOT NULL,
boolean_answer BOOLEAN NULL,
text_answer TEXT NULL,
answered_at DATETIME NOT NULL,
CONSTRAINT uq_user_question_answer UNIQUE (user_id, question_id),
CONSTRAINT fk_user_question_answers_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
CONSTRAINT fk_user_question_answers_question FOREIGN KEY (question_id) REFERENCES feed_questions(id) ON DELETE CASCADE,
INDEX ix_user_question_answers_user (user_id),
INDEX ix_user_question_answers_question (question_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT IGNORE INTO feed_questions
(code, question_text, question_text_zh, answer_type, is_active, sort_order, created_at)
VALUES
('weekend_movies', 'Do you like watching movies on weekends?', '你喜欢周末看电影吗?', 'boolean', TRUE, 10, NOW()),
('outdoor_activities', 'Do you enjoy outdoor activities?', '你喜欢户外活动吗?', 'boolean', TRUE, 20, NOW()),
('quiet_weekends', 'Do you prefer quiet weekends?', '你更喜欢安静的周末吗?', 'boolean', TRUE, 30, NOW()),
('long_term_relationship', 'Are you looking for a long-term relationship?', '你希望发展长期关系吗?', 'boolean', TRUE, 40, NOW()),
('ideal_first_date', 'What is your ideal first date?', '你理想中的第一次约会是什么?', 'text', TRUE, 50, NOW());