353 lines
13 KiB
SQL
353 lines
13 KiB
SQL
-- V6__consolidated_migrations.sql
|
||
-- 整合所有分散的迁移脚本(2026-05-15)
|
||
-- 包含: materials, asset_material_relations, 经济系统表, 字段修改等
|
||
|
||
-- =====================================================
|
||
-- Part 1: materials 素材主表
|
||
-- =====================================================
|
||
CREATE TABLE IF NOT EXISTS public.materials (
|
||
id BIGSERIAL PRIMARY KEY,
|
||
oss_key VARCHAR(255) NOT NULL,
|
||
original_name VARCHAR(255) NOT NULL,
|
||
file_size BIGINT NOT NULL,
|
||
mime_type VARCHAR(100) NOT NULL,
|
||
width INT,
|
||
height INT,
|
||
hash VARCHAR(64) NOT NULL,
|
||
created_by BIGINT NOT NULL,
|
||
star_id BIGINT NOT NULL DEFAULT 0,
|
||
created_at BIGINT NOT NULL,
|
||
updated_at BIGINT NOT NULL,
|
||
deleted_at BIGINT
|
||
);
|
||
|
||
CREATE UNIQUE INDEX IF NOT EXISTS uk_materials_oss_key ON public.materials(oss_key);
|
||
CREATE INDEX IF NOT EXISTS idx_materials_hash ON public.materials(hash);
|
||
CREATE INDEX IF NOT EXISTS idx_materials_created_by ON public.materials(created_by);
|
||
CREATE INDEX IF NOT EXISTS idx_materials_star_id ON public.materials(star_id);
|
||
|
||
COMMENT ON TABLE public.materials IS '素材主表';
|
||
|
||
-- =====================================================
|
||
-- Part 2: asset_material_relations 资产-素材关联表
|
||
-- =====================================================
|
||
CREATE TABLE IF NOT EXISTS public.asset_material_relations (
|
||
id BIGSERIAL PRIMARY KEY,
|
||
asset_id BIGINT NOT NULL,
|
||
material_id BIGINT NOT NULL,
|
||
material_type VARCHAR(50) NOT NULL,
|
||
layer_order INT NOT NULL DEFAULT 0,
|
||
pos_x DOUBLE PRECISION,
|
||
pos_y DOUBLE PRECISION,
|
||
opacity DOUBLE PRECISION DEFAULT 1.0,
|
||
rotation DOUBLE PRECISION DEFAULT 0,
|
||
scale_x DOUBLE PRECISION DEFAULT 1.0,
|
||
scale_y DOUBLE PRECISION DEFAULT 1.0,
|
||
version INT NOT NULL DEFAULT 1,
|
||
created_at BIGINT NOT NULL,
|
||
updated_at BIGINT NOT NULL,
|
||
deleted_at BIGINT
|
||
);
|
||
|
||
CREATE INDEX IF NOT EXISTS idx_amr_asset_id ON public.asset_material_relations(asset_id) WHERE deleted_at IS NULL;
|
||
CREATE INDEX IF NOT EXISTS idx_amr_material_id ON public.asset_material_relations(material_id) WHERE deleted_at IS NULL;
|
||
CREATE INDEX IF NOT EXISTS idx_amr_asset_type_layer ON public.asset_material_relations(asset_id, material_type, layer_order) WHERE deleted_at IS NULL;
|
||
CREATE UNIQUE INDEX IF NOT EXISTS uk_amr_asset_type_active ON public.asset_material_relations(asset_id, material_type) WHERE deleted_at IS NULL;
|
||
CREATE UNIQUE INDEX IF NOT EXISTS uk_amr_asset_layer_active ON public.asset_material_relations(asset_id, layer_order) WHERE deleted_at IS NULL;
|
||
|
||
COMMENT ON TABLE public.asset_material_relations IS '资产-素材关联表';
|
||
|
||
-- 外键约束(如果 assets 表已存在)
|
||
DO $$
|
||
BEGIN
|
||
IF EXISTS (SELECT 1 FROM pg_tables WHERE tablename = 'assets') THEN
|
||
ALTER TABLE public.asset_material_relations
|
||
ADD CONSTRAINT fk_amr_asset
|
||
FOREIGN KEY (asset_id) REFERENCES public.assets(id) ON DELETE CASCADE;
|
||
END IF;
|
||
EXCEPTION WHEN others THEN
|
||
RAISE NOTICE 'Foreign key constraint for asset_material_relations skipped: %', SQLERRM;
|
||
END $$;
|
||
|
||
DO $$
|
||
BEGIN
|
||
IF EXISTS (SELECT 1 FROM pg_tables WHERE tablename = 'materials') THEN
|
||
ALTER TABLE public.asset_material_relations
|
||
ADD CONSTRAINT fk_amr_material
|
||
FOREIGN KEY (material_id) REFERENCES public.materials(id) ON DELETE RESTRICT;
|
||
END IF;
|
||
EXCEPTION WHEN others THEN
|
||
RAISE NOTICE 'Foreign key constraint for asset_material_relations skipped: %', SQLERRM;
|
||
END $$;
|
||
|
||
-- =====================================================
|
||
-- Part 3: user_mint_count 铸爱次数表
|
||
-- =====================================================
|
||
CREATE TABLE IF NOT EXISTS public.user_mint_count (
|
||
id BIGSERIAL PRIMARY KEY,
|
||
user_id BIGINT NOT NULL,
|
||
star_id BIGINT NOT NULL,
|
||
mint_count INT NOT NULL DEFAULT 0,
|
||
revenue_boost_bps INT NOT NULL DEFAULT 0,
|
||
updated_at BIGINT NOT NULL,
|
||
CONSTRAINT uk_user_mint_count_user_star UNIQUE (user_id, star_id)
|
||
);
|
||
|
||
CREATE INDEX IF NOT EXISTS idx_user_mint_count_user ON public.user_mint_count USING btree (user_id);
|
||
CREATE INDEX IF NOT EXISTS idx_user_mint_count_star ON public.user_mint_count USING btree (star_id);
|
||
|
||
COMMENT ON TABLE public.user_mint_count IS '用户在某偶像下的累计铸爱次数与收益加成(基点)';
|
||
|
||
-- =====================================================
|
||
-- Part 4: mint_cost_config 铸爱阶梯配置表
|
||
-- =====================================================
|
||
CREATE TABLE IF NOT EXISTS public.mint_cost_config (
|
||
id BIGSERIAL PRIMARY KEY,
|
||
mint_count INT NOT NULL,
|
||
cost_crystal BIGINT NOT NULL,
|
||
probability BIGINT NOT NULL DEFAULT 0,
|
||
reward_type VARCHAR(50) DEFAULT NULL,
|
||
reward_value BIGINT NOT NULL DEFAULT 0,
|
||
description VARCHAR(255),
|
||
updated_at BIGINT NOT NULL,
|
||
CONSTRAINT uk_mint_cost_config_mint_count UNIQUE (mint_count)
|
||
);
|
||
|
||
COMMENT ON TABLE public.mint_cost_config IS '铸爱次数阶梯消耗与保底配置';
|
||
|
||
-- 插入铸爱阶梯数据
|
||
INSERT INTO public.mint_cost_config (mint_count, cost_crystal, probability, reward_type, reward_value, description, updated_at)
|
||
VALUES
|
||
(1, 2, 0, NULL, 0, '第1次', 1773322573872),
|
||
(2, 4, 0, NULL, 0, '第2次', 1773322573872),
|
||
(3, 8, 0, NULL, 0, '第3次', 1773322573872),
|
||
(4, 16, 0, NULL, 0, '第4次', 1773322573872),
|
||
(5, 32, 0, NULL, 0, '第5次', 1773322573872),
|
||
(6, 64, 0, NULL, 0, '第6次', 1773322573872),
|
||
(7, 128, 0, NULL, 0, '第7次', 1773322573872),
|
||
(8, 256, 0, NULL, 0, '第8次', 1773322573872),
|
||
(9, 512, 20, '收益提升', 5, '小保底', 1773322573872),
|
||
(10, 1024, 100, '收益提升', 5, '大保底', 1773322573872)
|
||
ON CONFLICT (mint_count) DO UPDATE SET
|
||
cost_crystal = EXCLUDED.cost_crystal,
|
||
probability = EXCLUDED.probability,
|
||
reward_type = EXCLUDED.reward_type,
|
||
reward_value = EXCLUDED.reward_value,
|
||
description = EXCLUDED.description,
|
||
updated_at = EXCLUDED.updated_at;
|
||
|
||
-- =====================================================
|
||
-- Part 5: 字段修改迁移
|
||
-- =====================================================
|
||
|
||
-- 5.1 exhibitions 表添加 deleted_at 字段
|
||
DO $$
|
||
BEGIN
|
||
IF NOT EXISTS (
|
||
SELECT 1 FROM information_schema.columns
|
||
WHERE table_name = 'exhibitions' AND column_name = 'deleted_at'
|
||
) THEN
|
||
ALTER TABLE public.exhibitions ADD COLUMN deleted_at BIGINT;
|
||
RAISE NOTICE 'Column deleted_at added to exhibitions table';
|
||
ELSE
|
||
RAISE NOTICE 'Column deleted_at already exists in exhibitions table';
|
||
END IF;
|
||
END $$;
|
||
|
||
-- 5.2 assets 表添加 material_type 字段
|
||
DO $$
|
||
BEGIN
|
||
IF NOT EXISTS (
|
||
SELECT 1 FROM information_schema.columns
|
||
WHERE table_name = 'assets' AND column_name = 'material_type'
|
||
) THEN
|
||
ALTER TABLE public.assets ADD COLUMN material_type VARCHAR(50);
|
||
RAISE NOTICE 'Column material_type added to assets table';
|
||
ELSE
|
||
RAISE NOTICE 'Column material_type already exists in assets table';
|
||
END IF;
|
||
END $$;
|
||
|
||
-- 5.3 activities 表添加 icon 字段
|
||
DO $$
|
||
BEGIN
|
||
IF NOT EXISTS (
|
||
SELECT 1 FROM information_schema.columns
|
||
WHERE table_name = 'activities' AND column_name = 'icon'
|
||
) THEN
|
||
ALTER TABLE public.activities ADD COLUMN icon VARCHAR(500) DEFAULT '';
|
||
RAISE NOTICE 'Column icon added to activities table';
|
||
ELSE
|
||
RAISE NOTICE 'Column icon already exists in activities table';
|
||
END IF;
|
||
END $$;
|
||
|
||
-- 5.4 activities 表添加 overall_end_time 字段
|
||
DO $$
|
||
BEGIN
|
||
IF NOT EXISTS (
|
||
SELECT 1 FROM information_schema.columns
|
||
WHERE table_name = 'activities' AND column_name = 'overall_end_time'
|
||
) THEN
|
||
ALTER TABLE public.activities ADD COLUMN overall_end_time BIGINT DEFAULT 0;
|
||
RAISE NOTICE 'Column overall_end_time added to activities table';
|
||
ELSE
|
||
RAISE NOTICE 'Column overall_end_time already exists in activities table';
|
||
END IF;
|
||
END $$;
|
||
|
||
-- 5.5 fan_profiles 表添加 avatar_url 字段
|
||
DO $$
|
||
BEGIN
|
||
IF NOT EXISTS (
|
||
SELECT 1 FROM information_schema.columns
|
||
WHERE table_name = 'fan_profiles' AND column_name = 'avatar_url'
|
||
) THEN
|
||
ALTER TABLE public.fan_profiles ADD COLUMN avatar_url VARCHAR(500);
|
||
RAISE NOTICE 'Column avatar_url added to fan_profiles table';
|
||
ELSE
|
||
RAISE NOTICE 'Column avatar_url already exists in fan_profiles table';
|
||
END IF;
|
||
END $$;
|
||
|
||
-- 5.6 assets 表添加 is_original 字段
|
||
DO $$
|
||
BEGIN
|
||
IF NOT EXISTS (
|
||
SELECT 1 FROM information_schema.columns
|
||
WHERE table_name = 'assets' AND column_name = 'is_original'
|
||
) THEN
|
||
ALTER TABLE public.assets ADD COLUMN is_original BOOLEAN DEFAULT false;
|
||
RAISE NOTICE 'Column is_original added to assets table';
|
||
ELSE
|
||
RAISE NOTICE 'Column is_original already exists in assets table';
|
||
END IF;
|
||
END $$;
|
||
|
||
-- 5.7 activities 表添加 theme 字段
|
||
DO $$
|
||
BEGIN
|
||
IF NOT EXISTS (
|
||
SELECT 1 FROM information_schema.columns
|
||
WHERE table_name = 'activities' AND column_name = 'theme'
|
||
) THEN
|
||
ALTER TABLE public.activities ADD COLUMN theme VARCHAR(100);
|
||
RAISE NOTICE 'Column theme added to activities table';
|
||
ELSE
|
||
RAISE NOTICE 'Column theme already exists in activities table';
|
||
END IF;
|
||
END $$;
|
||
|
||
-- =====================================================
|
||
-- Part 6: 索引和约束修改
|
||
-- =====================================================
|
||
|
||
-- 6.1 asset_likes 表唯一约束修改(添加 star_id)
|
||
DO $$
|
||
BEGIN
|
||
IF EXISTS (
|
||
SELECT 1 FROM pg_constraint WHERE conname = 'uk_asset_likes_user_asset'
|
||
) THEN
|
||
ALTER TABLE public.asset_likes DROP CONSTRAINT uk_asset_likes_user_asset;
|
||
RAISE NOTICE 'Old constraint uk_asset_likes_user_asset dropped';
|
||
END IF;
|
||
EXCEPTION WHEN others THEN
|
||
RAISE NOTICE 'Constraint uk_asset_likes_user_asset not found or already dropped: %', SQLERRM;
|
||
END $$;
|
||
|
||
DO $$
|
||
BEGIN
|
||
IF NOT EXISTS (
|
||
SELECT 1 FROM pg_constraint WHERE conname = 'uk_asset_likes_user_asset_star'
|
||
) THEN
|
||
ALTER TABLE public.asset_likes ADD CONSTRAINT uk_asset_likes_user_asset_star UNIQUE (user_id, asset_id, star_id);
|
||
RAISE NOTICE 'New constraint uk_asset_likes_user_asset_star added';
|
||
END IF;
|
||
EXCEPTION WHEN others THEN
|
||
RAISE NOTICE 'Constraint uk_asset_likes_user_asset_star already exists: %', SQLERRM;
|
||
END $$;
|
||
|
||
-- 6.2 exhibitions 表唯一约束移除(asset_id)
|
||
DO $$
|
||
BEGIN
|
||
IF EXISTS (
|
||
SELECT 1 FROM pg_constraint WHERE conname = 'uk_asset'
|
||
) THEN
|
||
ALTER TABLE public.exhibitions DROP CONSTRAINT uk_asset;
|
||
RAISE NOTICE 'Constraint uk_asset dropped from exhibitions table';
|
||
END IF;
|
||
EXCEPTION WHEN others THEN
|
||
RAISE NOTICE 'Constraint uk_asset not found or already dropped: %', SQLERRM;
|
||
END $$;
|
||
|
||
-- 6.3 exhibitions 表添加 idx_asset 普通索引
|
||
DO $$
|
||
BEGIN
|
||
IF NOT EXISTS (
|
||
SELECT 1 FROM pg_indexes WHERE indexname = 'idx_asset' AND schemaname = 'public'
|
||
) THEN
|
||
CREATE INDEX idx_asset ON public.exhibitions(asset_id);
|
||
RAISE NOTICE 'Index idx_asset created on exhibitions table';
|
||
END IF;
|
||
EXCEPTION WHEN others THEN
|
||
RAISE NOTICE 'Index idx_asset already exists: %', SQLERRM;
|
||
END $$;
|
||
|
||
-- =====================================================
|
||
-- Migration completed
|
||
-- =====================================================
|
||
DO $$
|
||
BEGIN
|
||
RAISE NOTICE 'V6__consolidated_migrations completed successfully';
|
||
END $$;
|
||
|
||
-- 素材主表
|
||
CREATE TABLE materials (
|
||
id BIGSERIAL PRIMARY KEY,
|
||
oss_key VARCHAR(255) NOT NULL,
|
||
original_name VARCHAR(255) NOT NULL,
|
||
file_size BIGINT NOT NULL,
|
||
mime_type VARCHAR(100) NOT NULL,
|
||
width INT,
|
||
height INT,
|
||
hash VARCHAR(64) NOT NULL,
|
||
created_by BIGINT NOT NULL,
|
||
star_id BIGINT NOT NULL DEFAULT 0,
|
||
created_at BIGINT NOT NULL,
|
||
updated_at BIGINT NOT NULL,
|
||
deleted_at BIGINT
|
||
);
|
||
|
||
CREATE UNIQUE INDEX uk_materials_oss_key ON materials(oss_key);
|
||
CREATE INDEX idx_materials_hash ON materials(hash);
|
||
CREATE INDEX idx_materials_created_by ON materials(created_by);
|
||
CREATE INDEX idx_materials_star_id ON materials(star_id);
|
||
|
||
-- 资产-素材关联表
|
||
CREATE TABLE asset_material_relations (
|
||
id BIGSERIAL PRIMARY KEY,
|
||
asset_id BIGINT NOT NULL REFERENCES assets(id) ON DELETE CASCADE,
|
||
material_id BIGINT NOT NULL REFERENCES materials(id) ON DELETE RESTRICT,
|
||
material_type VARCHAR(50) NOT NULL,
|
||
layer_order INT NOT NULL DEFAULT 0,
|
||
pos_x DOUBLE PRECISION,
|
||
pos_y DOUBLE PRECISION,
|
||
opacity DOUBLE PRECISION DEFAULT 1.0,
|
||
rotation DOUBLE PRECISION DEFAULT 0,
|
||
scale_x DOUBLE PRECISION DEFAULT 1.0,
|
||
scale_y DOUBLE PRECISION DEFAULT 1.0,
|
||
version INT NOT NULL DEFAULT 1,
|
||
created_at BIGINT NOT NULL,
|
||
updated_at BIGINT NOT NULL,
|
||
deleted_at BIGINT
|
||
);
|
||
|
||
-- 索引
|
||
CREATE INDEX idx_amr_asset_id ON asset_material_relations(asset_id) WHERE deleted_at IS NULL;
|
||
CREATE INDEX idx_amr_material_id ON asset_material_relations(material_id) WHERE deleted_at IS NULL;
|
||
CREATE INDEX idx_amr_asset_type_layer ON asset_material_relations(asset_id, material_type, layer_order) WHERE deleted_at IS NULL;
|
||
|
||
-- 部分唯一索引(软删除感知)
|
||
CREATE UNIQUE INDEX uk_amr_asset_type_active ON asset_material_relations(asset_id, material_type) WHERE deleted_at IS NULL;
|
||
CREATE UNIQUE INDEX uk_amr_asset_layer_active ON asset_material_relations(asset_id, layer_order) WHERE deleted_at IS NULL;
|