Files
AcgStyleBlog/backend/schema.sql
2026-03-31 22:29:38 +08:00

137 lines
4.9 KiB
SQL
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- ACG Blog 数据库建表脚本
-- PostgreSQL
-- 运行前请先创建数据库: CREATE DATABASE acg_blog;
-- 启用 UUID 扩展
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
-- ==================== 用户表 ====================
CREATE TABLE IF NOT EXISTS "users" (
"id" UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
"username" VARCHAR(50) UNIQUE NOT NULL,
"email" VARCHAR(255) UNIQUE NOT NULL,
"password_hash" VARCHAR(255) NOT NULL,
"avatar" VARCHAR(500),
"bio" TEXT,
"is_active" BOOLEAN DEFAULT TRUE,
"is_superuser" BOOLEAN DEFAULT FALSE,
"created_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- ==================== 分类表 ====================
CREATE TABLE IF NOT EXISTS "categories" (
"id" UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
"name" VARCHAR(50) UNIQUE NOT NULL,
"slug" VARCHAR(50) UNIQUE NOT NULL,
"description" TEXT,
"created_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- ==================== 标签表 ====================
CREATE TABLE IF NOT EXISTS "tags" (
"id" UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
"name" VARCHAR(50) UNIQUE NOT NULL,
"slug" VARCHAR(50) UNIQUE NOT NULL,
"created_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- ==================== 文章表 ====================
CREATE TABLE IF NOT EXISTS "posts" (
"id" UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
"title" VARCHAR(200) NOT NULL,
"slug" VARCHAR(200) UNIQUE NOT NULL,
"content" TEXT NOT NULL,
"summary" TEXT,
"cover_image" VARCHAR(500),
-- 外键关联
"author_id" UUID NOT NULL REFERENCES "users"("id") ON DELETE CASCADE,
"category_id" UUID REFERENCES "categories"("id") ON DELETE SET NULL,
-- 统计数据
"view_count" INTEGER DEFAULT 0,
"like_count" INTEGER DEFAULT 0,
"comment_count" INTEGER DEFAULT 0,
-- 状态: draft/published/archived
"status" VARCHAR(20) DEFAULT 'draft',
-- SEO
"meta_title" VARCHAR(200),
"meta_description" TEXT,
-- 时间戳
"published_at" TIMESTAMP,
"created_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 索引
CREATE INDEX IF NOT EXISTS "idx_posts_status_published_at" ON "posts"("status", "published_at");
CREATE INDEX IF NOT EXISTS "idx_posts_author_status" ON "posts"("author_id", "status");
-- ==================== 文章标签关联表 ====================
CREATE TABLE IF NOT EXISTS "post_tags" (
"id" UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
"post_id" UUID NOT NULL REFERENCES "posts"("id") ON DELETE CASCADE,
"tag_id" UUID NOT NULL REFERENCES "tags"("id") ON DELETE CASCADE,
UNIQUE("post_id", "tag_id")
);
-- ==================== 评论表 ====================
CREATE TABLE IF NOT EXISTS "comments" (
"id" UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
"content" TEXT NOT NULL,
"is_approved" BOOLEAN DEFAULT TRUE,
-- 外键关联
"author_id" UUID NOT NULL REFERENCES "users"("id") ON DELETE CASCADE,
"post_id" UUID NOT NULL REFERENCES "posts"("id") ON DELETE CASCADE,
"parent_id" UUID REFERENCES "comments"("id") ON DELETE CASCADE,
-- 时间戳
"created_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 索引
CREATE INDEX IF NOT EXISTS "idx_comments_post_id" ON "comments"("post_id");
CREATE INDEX IF NOT EXISTS "idx_comments_author_id" ON "comments"("author_id");
-- ==================== 初始化数据 ====================
-- 插入默认分类
INSERT INTO "categories" ("name", "slug", "description") VALUES
('动漫资讯', 'anime', '最新动漫新闻、番剧更新、业界动态'),
('游戏攻略', 'game', '游戏通关指南、角色培养、剧情解析'),
('二次元美图', 'pictures', '精选壁纸、Cosplay、插画作品'),
('同人创作', 'fanwork', '同人小说、同人绘画、手办模型')
ON CONFLICT ("slug") DO NOTHING;
-- 插入默认标签
INSERT INTO "tags" ("name", "slug") VALUES
('原神', 'genshin'),
('崩坏星穹铁道', 'honkai-star-rail'),
('我的世界', 'minecraft'),
('EVA', 'evangelion'),
('约定的梦幻岛', 'neverland'),
('咒术回战', 'jujutsu-kaisen'),
('Cosplay', 'cosplay'),
('手办', 'figure')
ON CONFLICT ("slug") DO NOTHING;
-- 插入管理员用户 (密码: admin123)
-- 密码哈希基于 bcrypt使用前请替换为实际哈希值
INSERT INTO "users" ("username", "email", "password_hash", "is_superuser") VALUES
('admin', 'admin@acgblog.com', '$2b$12$LQv3c1yqBWVHxkd0LHAkCOYz6TtxMQJqhN8/X4.TZND60LMTUBu.K', TRUE)
ON CONFLICT ("username") DO NOTHING;
-- ==================== 注释 ====================
COMMENT ON TABLE "users" IS '用户表';
COMMENT ON TABLE "categories" IS '文章分类表';
COMMENT ON TABLE "tags" IS '文章标签表';
COMMENT ON TABLE "posts" IS '文章表';
COMMENT ON TABLE "post_tags" IS '文章标签关联表';
COMMENT ON TABLE "comments" IS '评论表';