200 lines
7.8 KiB
PL/PgSQL
200 lines
7.8 KiB
PL/PgSQL
-- 职业体系模块数据库迁移脚本(PostgreSQL版本)
|
||
-- 创建时间: 2025-12-20
|
||
-- 说明: 添加职业表和角色职业关联表
|
||
|
||
-- ===== 1. 创建职业表 =====
|
||
CREATE TABLE IF NOT EXISTS careers (
|
||
id VARCHAR(36) PRIMARY KEY,
|
||
project_id VARCHAR(36) NOT NULL,
|
||
|
||
-- 基本信息
|
||
name VARCHAR(100) NOT NULL,
|
||
type VARCHAR(20) NOT NULL, -- 职业类型: main(主职业)/sub(副职业)
|
||
description TEXT, -- 职业描述
|
||
category VARCHAR(50), -- 职业分类(如:战斗系、生产系、辅助系)
|
||
|
||
-- 阶段设定
|
||
stages TEXT NOT NULL, -- 职业阶段列表(JSON): [{"level":1, "name":"", "description":""}, ...]
|
||
max_stage INT NOT NULL DEFAULT 10, -- 最大阶段数
|
||
|
||
-- 职业特性
|
||
requirements TEXT, -- 职业要求/限制
|
||
special_abilities TEXT, -- 特殊能力描述
|
||
worldview_rules TEXT, -- 世界观规则关联
|
||
|
||
-- 职业属性加成(可选,JSON格式)
|
||
attribute_bonuses TEXT, -- 属性加成(JSON): {"strength": "+10%", "intelligence": "+5%"}
|
||
|
||
-- 元数据
|
||
source VARCHAR(20) DEFAULT 'ai', -- 来源: ai/manual
|
||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- 创建时间
|
||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- 更新时间
|
||
|
||
-- 外键约束
|
||
CONSTRAINT fk_career_project FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE
|
||
);
|
||
|
||
-- 创建索引
|
||
CREATE INDEX IF NOT EXISTS idx_careers_project_id ON careers(project_id);
|
||
CREATE INDEX IF NOT EXISTS idx_careers_type ON careers(type);
|
||
|
||
-- 创建更新时间触发器
|
||
CREATE OR REPLACE FUNCTION update_careers_updated_at()
|
||
RETURNS TRIGGER AS $$
|
||
BEGIN
|
||
NEW.updated_at = CURRENT_TIMESTAMP;
|
||
RETURN NEW;
|
||
END;
|
||
$$ LANGUAGE plpgsql;
|
||
|
||
CREATE TRIGGER trigger_careers_updated_at
|
||
BEFORE UPDATE ON careers
|
||
FOR EACH ROW
|
||
EXECUTE FUNCTION update_careers_updated_at();
|
||
|
||
-- 添加表注释
|
||
COMMENT ON TABLE careers IS '职业表';
|
||
COMMENT ON COLUMN careers.name IS '职业名称';
|
||
COMMENT ON COLUMN careers.type IS '职业类型: main(主职业)/sub(副职业)';
|
||
COMMENT ON COLUMN careers.description IS '职业描述';
|
||
COMMENT ON COLUMN careers.category IS '职业分类(如:战斗系、生产系、辅助系)';
|
||
COMMENT ON COLUMN careers.stages IS '职业阶段列表(JSON)';
|
||
COMMENT ON COLUMN careers.max_stage IS '最大阶段数';
|
||
COMMENT ON COLUMN careers.requirements IS '职业要求/限制';
|
||
COMMENT ON COLUMN careers.special_abilities IS '特殊能力描述';
|
||
COMMENT ON COLUMN careers.worldview_rules IS '世界观规则关联';
|
||
COMMENT ON COLUMN careers.attribute_bonuses IS '属性加成(JSON)';
|
||
COMMENT ON COLUMN careers.source IS '来源: ai/manual';
|
||
COMMENT ON COLUMN careers.created_at IS '创建时间';
|
||
COMMENT ON COLUMN careers.updated_at IS '更新时间';
|
||
|
||
-- ===== 2. 创建角色职业关联表 =====
|
||
CREATE TABLE IF NOT EXISTS character_careers (
|
||
id VARCHAR(36) PRIMARY KEY,
|
||
character_id VARCHAR(36) NOT NULL,
|
||
career_id VARCHAR(36) NOT NULL,
|
||
career_type VARCHAR(20) NOT NULL, -- main(主职业)/sub(副职业)
|
||
|
||
-- 阶段进度
|
||
current_stage INT NOT NULL DEFAULT 1, -- 当前阶段(对应职业中的数值)
|
||
stage_progress INT DEFAULT 0, -- 阶段内进度(0-100)
|
||
|
||
-- 时间记录
|
||
started_at VARCHAR(100), -- 开始修炼时间(小说时间线)
|
||
reached_current_stage_at VARCHAR(100), -- 到达当前阶段时间
|
||
|
||
-- 备注
|
||
notes TEXT, -- 备注(如:修炼心得、特殊事件)
|
||
|
||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- 创建时间
|
||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- 更新时间
|
||
|
||
-- 外键约束
|
||
CONSTRAINT fk_charcareer_character FOREIGN KEY (character_id) REFERENCES characters(id) ON DELETE CASCADE,
|
||
CONSTRAINT fk_charcareer_career FOREIGN KEY (career_id) REFERENCES careers(id) ON DELETE CASCADE,
|
||
|
||
-- 唯一约束:一个角色不能重复拥有同一个职业
|
||
CONSTRAINT uk_character_career UNIQUE (character_id, career_id)
|
||
);
|
||
|
||
-- 创建索引
|
||
CREATE INDEX IF NOT EXISTS idx_character_careers_character_id ON character_careers(character_id);
|
||
CREATE INDEX IF NOT EXISTS idx_character_careers_career_type ON character_careers(career_type);
|
||
|
||
-- 创建更新时间触发器
|
||
CREATE OR REPLACE FUNCTION update_character_careers_updated_at()
|
||
RETURNS TRIGGER AS $$
|
||
BEGIN
|
||
NEW.updated_at = CURRENT_TIMESTAMP;
|
||
RETURN NEW;
|
||
END;
|
||
$$ LANGUAGE plpgsql;
|
||
|
||
CREATE TRIGGER trigger_character_careers_updated_at
|
||
BEFORE UPDATE ON character_careers
|
||
FOR EACH ROW
|
||
EXECUTE FUNCTION update_character_careers_updated_at();
|
||
|
||
-- 添加表注释
|
||
COMMENT ON TABLE character_careers IS '角色职业关联表';
|
||
COMMENT ON COLUMN character_careers.career_type IS 'main(主职业)/sub(副职业)';
|
||
COMMENT ON COLUMN character_careers.current_stage IS '当前阶段(对应职业中的数值)';
|
||
COMMENT ON COLUMN character_careers.stage_progress IS '阶段内进度(0-100)';
|
||
COMMENT ON COLUMN character_careers.started_at IS '开始修炼时间(小说时间线)';
|
||
COMMENT ON COLUMN character_careers.reached_current_stage_at IS '到达当前阶段时间';
|
||
COMMENT ON COLUMN character_careers.notes IS '备注(如:修炼心得、特殊事件)';
|
||
|
||
-- ===== 3. 扩展角色表(添加冗余字段,可选) =====
|
||
-- 注意:这部分是可选的,用于提升查询性能
|
||
-- 检查字段是否存在,如果不存在则添加
|
||
|
||
DO $$
|
||
BEGIN
|
||
-- 添加 main_career_id 字段
|
||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns
|
||
WHERE table_name='characters' AND column_name='main_career_id') THEN
|
||
ALTER TABLE characters ADD COLUMN main_career_id VARCHAR(36);
|
||
COMMENT ON COLUMN characters.main_career_id IS '主职业ID';
|
||
END IF;
|
||
|
||
-- 添加 main_career_stage 字段
|
||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns
|
||
WHERE table_name='characters' AND column_name='main_career_stage') THEN
|
||
ALTER TABLE characters ADD COLUMN main_career_stage INT;
|
||
COMMENT ON COLUMN characters.main_career_stage IS '主职业当前阶段';
|
||
END IF;
|
||
|
||
-- 添加 sub_careers 字段
|
||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns
|
||
WHERE table_name='characters' AND column_name='sub_careers') THEN
|
||
ALTER TABLE characters ADD COLUMN sub_careers TEXT;
|
||
COMMENT ON COLUMN characters.sub_careers IS '副职业列表(JSON): [{"career_id": "xxx", "stage": 3}, ...]';
|
||
END IF;
|
||
END $$;
|
||
|
||
-- 添加外键约束(如果需要)
|
||
DO $$
|
||
BEGIN
|
||
IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints
|
||
WHERE constraint_name='fk_main_career' AND table_name='characters') THEN
|
||
ALTER TABLE characters
|
||
ADD CONSTRAINT fk_main_career
|
||
FOREIGN KEY (main_career_id) REFERENCES careers(id) ON DELETE SET NULL;
|
||
END IF;
|
||
END $$;
|
||
|
||
-- ===== 4. 创建视图(可选,便于查询) =====
|
||
CREATE OR REPLACE VIEW v_character_career_details AS
|
||
SELECT
|
||
cc.id AS relation_id,
|
||
cc.character_id,
|
||
c.name AS character_name,
|
||
cc.career_id,
|
||
ca.name AS career_name,
|
||
ca.type AS career_type_name,
|
||
cc.career_type,
|
||
cc.current_stage,
|
||
ca.max_stage,
|
||
cc.stage_progress,
|
||
cc.started_at,
|
||
cc.reached_current_stage_at,
|
||
cc.notes,
|
||
ca.description AS career_description,
|
||
ca.category AS career_category,
|
||
ca.stages AS career_stages_json,
|
||
cc.created_at,
|
||
cc.updated_at
|
||
FROM character_careers cc
|
||
JOIN characters c ON cc.character_id = c.id
|
||
JOIN careers ca ON cc.career_id = ca.id
|
||
ORDER BY cc.career_type DESC, cc.created_at;
|
||
|
||
COMMENT ON VIEW v_character_career_details IS '角色职业详细信息视图';
|
||
|
||
-- ===== 完成提示 =====
|
||
DO $$
|
||
BEGIN
|
||
RAISE NOTICE '职业体系数据库表创建完成!';
|
||
RAISE NOTICE '职业表记录数: %', (SELECT COUNT(*) FROM careers);
|
||
RAISE NOTICE '角色职业关联表记录数: %', (SELECT COUNT(*) FROM character_careers);
|
||
END $$; |