TopDev

Xây dựng DB cho website Hội Nhóm như Facebook

minhdev 📖 4 phút đọc

Dưới đây là thiết kế database MySQL tối ưu cho hệ thống Hội Nhóm có lưu lượng lớn, nhiều nhóm – bài viết – bình luận – thành viên, phù hợp để chạy production, dễ scale, dễ cache.

Thiết kế theo tư duy: Facebook Groups / Reddit / Zalo Group



🎯 MỤC TIÊU THIẾT KẾ

  • Chịu tải lớn (nhiều user online, nhiều bài viết)

  • Query nhanh (index hợp lý, tránh JOIN nặng)

  • Dễ mở rộng (sharding, cache Redis)

  • Phù hợp Java / Spring Boot / MyBatis / JPA



🧠 TỔNG QUAN DATABASE

` users groups group_categories (2 cấp) provinces

group_members group_posts group_post_comments group_post_likes

group_statistics (cache số liệu) `



1️⃣ BẢNG USERS (người dùng)

` CREATE TABLE users ( id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, username VARCHAR(50) NOT NULL UNIQUE, email VARCHAR(120) UNIQUE, password_hash VARCHAR(255) NOT NULL, full_name VARCHAR(100), avatar_url VARCHAR(255),

status TINYINT DEFAULT 1 COMMENT '1=active,0=blocked',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,

INDEX idx_user_status (status)

) ENGINE=InnoDB; `

🔹 Tối ưu

  • BIGINT cho scale lớn

  • Không JOIN user quá sâu → chỉ lấy cần thiết



2️⃣ BẢNG PROVINCES (tỉnh / thành)

` CREATE TABLE provinces ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100) NOT NULL, slug VARCHAR(100) UNIQUE,

group_count INT DEFAULT 0 COMMENT 'cache số nhóm'

) ENGINE=InnoDB; `

🔹 group_count để không COUNT realtime



3️⃣ BẢNG GROUP_CATEGORIES (2 cấp)

` CREATE TABLE group_categories ( id INT AUTO_INCREMENT PRIMARY KEY, parent_id INT DEFAULT NULL, name VARCHAR(100) NOT NULL, slug VARCHAR(120) UNIQUE,

group_count INT DEFAULT 0,
sort_order INT DEFAULT 0,

INDEX idx_parent (parent_id)

) ENGINE=InnoDB; `

🔹 parent_id = NULL → cấp cha 🔹 Cache group_count để sidebar load nhanh



4️⃣ BẢNG GROUPS (hội nhóm)

` CREATE TABLE groups ( id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, name VARCHAR(150) NOT NULL, slug VARCHAR(160) UNIQUE, description TEXT, cover_image VARCHAR(255),

category_id INT NOT NULL,
province_id INT NOT NULL,

owner_id BIGINT UNSIGNED NOT NULL,

privacy TINYINT DEFAULT 1 COMMENT '1=public,2=private',
member_count INT DEFAULT 0,
post_count INT DEFAULT 0,

status TINYINT DEFAULT 1 COMMENT '1=active,0=hidden',

created_at DATETIME DEFAULT CURRENT_TIMESTAMP,

INDEX idx_category (category_id),
INDEX idx_province (province_id),
INDEX idx_created (created_at),
INDEX idx_status (status)

) ENGINE=InnoDB; `

🔥 RẤT QUAN TRỌNG

  • member_count, post_countcache

  • Không COUNT trực tiếp bảng member/post



5️⃣ BẢNG GROUP_MEMBERS (thành viên nhóm)

` CREATE TABLE group_members ( group_id BIGINT UNSIGNED NOT NULL, user_id BIGINT UNSIGNED NOT NULL,

role TINYINT DEFAULT 1 COMMENT '1=member,2=admin,3=owner',
joined_at DATETIME DEFAULT CURRENT_TIMESTAMP,

PRIMARY KEY (group_id, user_id),
INDEX idx_user (user_id)

) ENGINE=InnoDB; `

💡 Composite PK → lookup cực nhanh



6️⃣ BẢNG GROUP_POSTS (bài viết)

` CREATE TABLE group_posts ( id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, group_id BIGINT UNSIGNED NOT NULL, author_id BIGINT UNSIGNED NOT NULL,

title VARCHAR(255),
content LONGTEXT,

like_count INT DEFAULT 0,
comment_count INT DEFAULT 0,

status TINYINT DEFAULT 1 COMMENT '1=public,0=hidden',

created_at DATETIME DEFAULT CURRENT_TIMESTAMP,

INDEX idx_group_time (group_id, created_at DESC),
INDEX idx_author (author_id)

) ENGINE=InnoDB; `

🔥 Index cực kỳ quan trọng

  • (group_id, created_at DESC) → load newsfeed


7️⃣ BẢNG GROUP_POST_COMMENTS (bình luận)

` CREATE TABLE group_post_comments ( id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, post_id BIGINT UNSIGNED NOT NULL, user_id BIGINT UNSIGNED NOT NULL,

parent_id BIGINT UNSIGNED DEFAULT NULL,
content TEXT NOT NULL,

status TINYINT DEFAULT 1,

created_at DATETIME DEFAULT CURRENT_TIMESTAMP,

INDEX idx_post (post_id),
INDEX idx_parent (parent_id)

) ENGINE=InnoDB; `

🔹 Hỗ trợ reply comment (2 cấp) 🔹 Không nên quá sâu (tối ưu UI + DB)



8️⃣ BẢNG GROUP_POST_LIKES

` CREATE TABLE group_post_likes ( post_id BIGINT UNSIGNED NOT NULL, user_id BIGINT UNSIGNED NOT NULL,

created_at DATETIME DEFAULT CURRENT_TIMESTAMP,

PRIMARY KEY (post_id, user_id),
INDEX idx_user (user_id)

) ENGINE=InnoDB; `

💡 Không auto increment → tránh spam like



9️⃣ BẢNG GROUP_STATISTICS (CACHE)

` CREATE TABLE group_statistics ( group_id BIGINT UNSIGNED PRIMARY KEY, daily_posts INT DEFAULT 0, weekly_posts INT DEFAULT 0, monthly_posts INT DEFAULT 0,

last_updated DATETIME

) ENGINE=InnoDB; `

🔥 Dành cho trang thống kê / ranking



⚡ TỐI ƯU HIỆU NĂNG (CỰC QUAN TRỌNG)

✅ 1. Không COUNT realtime#

SELECT COUNT(*) FROM group_posts ✅ dùng post_count, member_count



✅ 2. Redis cache#

Cache:

  • Trang chủ

  • Sidebar tỉnh / thể loại

  • Feed nhóm

Key gợi ý:

group:{id}:posts category:{id}:groups province:{id}:groups



✅ 3. Partition (khi > 10 triệu bài)#

ALTER TABLE group_posts PARTITION BY HASH(group_id) PARTITIONS 16;



✅ 4. Chuẩn để scale Microservice#

  • Group Service

  • Post Service

  • User Service



🧩 QUAN HỆ SƠ ĐỒ (TÓM TẮT)

User ──< Group_Members >── Group Group ──< Group_Posts ──< Comments Group ── Category Group ── Province

Bài liên quan trong #Database

✓ Đã sao chép link