Last active
January 29, 2026 06:14
-
-
Save isocroft/03eec56bf6db1ca6363b6f1a2b51fc33 to your computer and use it in GitHub Desktop.
A database schema for a Tinder-clone dating app using either MySQL, SQLite or PostgreSQL as primary database
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| -- MySQL v8.0.16 | |
| -- PostgresSQL v16.9.2 | |
| CREATE DATABASE IF NOT EXISTS `test` | |
| DEFAULT CHARACTER SET utf8 -- utf8mb4 | |
| DEFAULT COLLATE utf8_general_ci; -- utf8mb4_unicode_ci | |
| SET default_storage_engine = INNODB; | |
| -- USERS Table: Core authentication information | |
| CREATE TABLE user_details ( | |
| id bigint NOT NULL, | |
| email varchar(100) UNIQUE NOT NULL, | |
| password_hash varchar(255) NOT NULL, | |
| created_at timestamp WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP, | |
| last_login timestamp WITH TIME ZONE, | |
| PRIMARY KEY (id) | |
| ); | |
| -- PROFILES Table: Detailed personal information | |
| CREATE TABLE user_accounts ( | |
| id bigint NOT NULL, | |
| first_name varchar(50) NOT NULL, | |
| last_name varchar(50) NOT NULL, | |
| bio text, | |
| date_of_birth date NOT NULL, | |
| gender enum('male', 'female', 'non-binary') NOT NULL, | |
| location_country char(2), | |
| is_active tinyint(1) NOT NULL DEFAULT 0, | |
| PRIMARY KEY (id), | |
| FOREIGN KEY (id) REFERENCES user_details(id) ON DELETE CASCADE | |
| ); | |
| -- USER_PHOTOS Table: Store links to user photos | |
| CREATE TABLE user_photos ( | |
| id bigint NOT NULL, | |
| user_id bigint NOT NULL , | |
| photo_url varchar(255) NOT NULL, | |
| is_profile_pic tinyint(1) NOT NULL DEFAULT 0, | |
| uploaded_at timestamp WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP, | |
| PRIMARY KEY (id), | |
| FOREIGN KEY (user_id) REFERENCES user_details(id) ON DELETE CASCADE | |
| ); | |
| -- INTERESTS Table: Master list of all possible interests | |
| CREATE TABLE user_interests ( | |
| id bigint NOT NULL, | |
| interest_name varchar(50) UNIQUE NOT NULL, | |
| PRIMARY KEY (id) | |
| ); | |
| -- USER_WITH_INTERESTS Table: Many-to-many relationship between users and interests | |
| CREATE TABLE user_with_interests ( | |
| user_id bigint NOT NULL , | |
| interest_id bigint NOT NULL, | |
| PRIMARY KEY (user_id, interest_id), | |
| FOREIGN KEY (user_id) REFERENCES user_details(id) ON DELETE CASCADE, | |
| FOREIGN KEY (interest_id) REFERENCES user_interests(id) ON DELETE CASCADE | |
| ); | |
| -- SWIPES Table: Track user interactions (likes/dislikes) | |
| CREATE TABLE swipes ( | |
| swipe_id bigint NOT NULL, | |
| swiper_id bigint NOT NULL, | |
| swipee_id bigint NOT NULL, | |
| swipe_type enum('like', 'dislike') NOT NULL, | |
| created_at timestamp WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP, | |
| UNIQUE (swiper_id, swipee_id) -- Ensures a user can only swipe on another user once | |
| PRIMARY KEY (id), | |
| FOREIGN KEY (swiper_id) REFERENCES user_details(id) ON DELETE CASCADE, | |
| FOREIGN KEY (swipee_id) REFERENCES user_details(id) ON DELETE CASCADE | |
| ); | |
| -- MATCHES Table: Store successful matches (both users swiped 'like') | |
| CREATE TABLE matches ( | |
| id bigint NOT NULL, | |
| matcher_user_id bigint NOT NULL, | |
| matchee_user_id bigint NOT NULL, | |
| created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP, | |
| -- Enforces that a match only exists once, regardless of user order | |
| UNIQUE (LEAST(matcher_user_id, matchee_user_id), GREATEST(matcher_user_id, matchee_user_id)), | |
| PRIMARY KEY (id), | |
| FOREIGN KEY (matcher_user_id) REFERENCES use_details(id) ON DELETE CASCADE, | |
| FOREIGN KEY (matchee_user_id) REFERENCES use_details(id) ON DELETE CASCADE | |
| ); | |
| -- MESSAGES Table: In-app messaging | |
| CREATE TABLE messages ( | |
| id bigint NOT NULL, | |
| match_id bigint NOT NULL, | |
| sender_id bigint NOT NULL , | |
| recipient_id UUID NOT NULL REFERENCES users(user_id), | |
| message text NOT NULL, | |
| sent_at timestamp WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP, | |
| is_read tinyint(1) NOT NULL DEFAULT 0, | |
| PRIMARY KEY (id), | |
| FOREIGN KEY (match_id) REFERENCES matches(id) ON DELETE NO ACTION, | |
| FOREIGN KEY (sender_id) REFERENCES user_details(id) ON DELETE NO ACTION, | |
| FOREIGN KEY (recipient_id) REFERENCES user_details(id) ON DELETE NO ACTION, | |
| ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment