feat: S0 主键改雪花(DDL 去 identity + 实体 ASSIGN_ID + 雪花配置)

为什么:自增主键把 ID 分配锁在单库序列上,分库分表时无法横向扩展。趁线上业务数据
近零(只有系统种子表有量)先改,代价最低。

- sql/schema.sql、sql/schema-phase1.sql、sql/partition-maintenance.sql:61 处
  GENERATED BY DEFAULT AS IDENTITY 去掉,主键改 BIGINT 无默认值
- 52 个实体 @TableId IdType.AUTO -> IdType.ASSIGN_ID;两个入口 id-type: assign_id,
  并加 global-config.sequence.worker-id/datacenter-id(单机固定值,多实例需按实例分配)
- 新增 sql/migrate-s0-snowflake.sql:存量库幂等迁移,走 DROP IDENTITY 保留数据,不重建表
- 实测:三份建表脚本在新库连跑两遍幂等;线上 57 张表 identity 归零;
  watch_history/playback_ticket/order_event 的主键与唯一索引仍含分区键
This commit is contained in:
Vicky committed 2026-10-16 09:00:38 +08:00
1 parent 6833e01e1f
commit 37c9a141d3
58 files changed
+174 -115

No files matched your search

@@ -26,10 +26,15 @@ mybatis-plus:
global-config: global-config:
banner: false banner: false
db-config: db-config:
id-type: auto # 主键由应用侧雪花算法生成(S0),数据库不再自增
id-type: assign_id
logic-delete-field: deleted logic-delete-field: deleted
logic-delete-value: 1 logic-delete-value: 1
logic-not-delete-value: 0 logic-not-delete-value: 0
sequence:
# 单机开发用固定值;上多实例前必须改成按实例分配(环境变量注入),否则会撞 ID
worker-id: 1
datacenter-id: 1
fruitshorts: fruitshorts:
media: media:
@@ -21,10 +21,15 @@ mybatis-plus:
global-config: global-config:
banner: false banner: false
db-config: db-config:
id-type: auto # 主键由应用侧雪花算法生成(S0),数据库不再自增
id-type: assign_id
logic-delete-field: deleted logic-delete-field: deleted
logic-delete-value: 1 logic-delete-value: 1
logic-not-delete-value: 0 logic-not-delete-value: 0
sequence:
# 单机开发用固定值;上多实例前必须改成按实例分配(环境变量注入),否则会撞 ID
worker-id: 1
datacenter-id: 1
fruitshorts: fruitshorts:
interaction: interaction:
@@ -12,7 +12,7 @@ import java.time.LocalDateTime;
@TableName("coin_ledger") @TableName("coin_ledger")
public class CoinLedger { public class CoinLedger {
@TableId(type = IdType.AUTO) @TableId(type = IdType.ASSIGN_ID)
private Long id; private Long id;
private Long userId; private Long userId;
/** 正数入账、负数出账 */ /** 正数入账、负数出账 */
@@ -15,7 +15,7 @@ import java.time.LocalDateTime;
@TableName("entitlement") @TableName("entitlement")
public class Entitlement { public class Entitlement {
@TableId(type = IdType.AUTO) @TableId(type = IdType.ASSIGN_ID)
private Long id; private Long id;
private Long userId; private Long userId;
private Long dramaId; private Long dramaId;
@@ -12,7 +12,7 @@ import java.time.LocalDateTime;
@TableName("order_event") @TableName("order_event")
public class OrderEvent { public class OrderEvent {
@TableId(type = IdType.AUTO) @TableId(type = IdType.ASSIGN_ID)
private Long id; private Long id;
private String orderNo; private String orderNo;
private String event; private String event;
@@ -16,7 +16,7 @@ import java.time.LocalDateTime;
@TableName("orders") @TableName("orders")
public class Orders { public class Orders {
@TableId(type = IdType.AUTO) @TableId(type = IdType.ASSIGN_ID)
private Long id; private Long id;
private String orderNo; private String orderNo;
private Long userId; private Long userId;
@@ -16,7 +16,7 @@ import java.time.LocalDateTime;
@TableName("product") @TableName("product")
public class Product { public class Product {
@TableId(type = IdType.AUTO) @TableId(type = IdType.ASSIGN_ID)
private Long id; private Long id;
private String code; private String code;
private String name; private String name;
@@ -14,7 +14,7 @@ import java.time.LocalDateTime;
@TableName("reconcile_task") @TableName("reconcile_task")
public class ReconcileTask { public class ReconcileTask {
@TableId(type = IdType.AUTO) @TableId(type = IdType.ASSIGN_ID)
private Long id; private Long id;
private LocalDate bizDate; private LocalDate bizDate;
private String platform; private String platform;
@@ -15,7 +15,7 @@ import java.time.LocalDateTime;
@TableName("store_receipt") @TableName("store_receipt")
public class StoreReceipt { public class StoreReceipt {
@TableId(type = IdType.AUTO) @TableId(type = IdType.ASSIGN_ID)
private Long id; private Long id;
private String platform; private String platform;
private String transactionId; private String transactionId;
@@ -15,7 +15,7 @@ import java.time.LocalDateTime;
@TableName("wallet") @TableName("wallet")
public class Wallet { public class Wallet {
@TableId(type = IdType.AUTO) @TableId(type = IdType.ASSIGN_ID)
private Long id; private Long id;
private Long userId; private Long userId;
private Long coinBalance; private Long coinBalance;
@@ -14,7 +14,7 @@ import java.time.LocalDateTime;
@TableName("content_banner") @TableName("content_banner")
public class ContentBanner { public class ContentBanner {
@TableId(type = IdType.AUTO) @TableId(type = IdType.ASSIGN_ID)
private Long id; private Long id;
private String imageUrl; private String imageUrl;
/** 展示位置,列名为 slot(position 在 PostgreSQL 里是关键字) */ /** 展示位置,列名为 slot(position 在 PostgreSQL 里是关键字) */
@@ -14,7 +14,7 @@ import java.time.LocalDateTime;
@TableName("drama") @TableName("drama")
public class Drama { public class Drama {
@TableId(type = IdType.AUTO) @TableId(type = IdType.ASSIGN_ID)
private Long id; private Long id;
private String code; private String code;
private String title; private String title;
@@ -9,7 +9,7 @@ import lombok.Data;
@TableName("drama_category") @TableName("drama_category")
public class DramaCategory { public class DramaCategory {
@TableId(type = IdType.AUTO) @TableId(type = IdType.ASSIGN_ID)
private Long id; private Long id;
private String name; private String name;
private Integer sort; private Integer sort;
@@ -14,7 +14,7 @@ import java.time.LocalDateTime;
@TableName("drama_episode") @TableName("drama_episode")
public class DramaEpisode { public class DramaEpisode {
@TableId(type = IdType.AUTO) @TableId(type = IdType.ASSIGN_ID)
private Long id; private Long id;
private Long dramaId; private Long dramaId;
private Integer epNo; private Integer epNo;
@@ -11,7 +11,7 @@ import java.time.LocalDateTime;
@TableName("drama_review_record") @TableName("drama_review_record")
public class DramaReviewRecord { public class DramaReviewRecord {
@TableId(type = IdType.AUTO) @TableId(type = IdType.ASSIGN_ID)
private Long id; private Long id;
private String bizType; private String bizType;
private Long bizId; private Long bizId;
@@ -15,7 +15,7 @@ import java.time.LocalDateTime;
@TableName("content_submission") @TableName("content_submission")
public class ContentSubmission { public class ContentSubmission {
@TableId(type = IdType.AUTO) @TableId(type = IdType.ASSIGN_ID)
private Long id; private Long id;
private Long creatorId; private Long creatorId;
private Long dramaId; private Long dramaId;
@@ -16,7 +16,7 @@ import java.time.LocalDateTime;
@TableName("creator") @TableName("creator")
public class Creator { public class Creator {
@TableId(type = IdType.AUTO) @TableId(type = IdType.ASSIGN_ID)
private Long id; private Long id;
/** 关联 C 端账号 app_user.id */ /** 关联 C 端账号 app_user.id */
private Long userId; private Long userId;
@@ -15,7 +15,7 @@ import java.time.LocalDateTime;
@TableName("creator_document") @TableName("creator_document")
public class CreatorDocument { public class CreatorDocument {
@TableId(type = IdType.AUTO) @TableId(type = IdType.ASSIGN_ID)
private Long id; private Long id;
private Long creatorId; private Long creatorId;
/** ID_CARD / BUSINESS_LICENSE / CONTRACT */ /** ID_CARD / BUSINESS_LICENSE / CONTRACT */
@@ -15,7 +15,7 @@ import java.time.LocalDateTime;
@TableName("content_audit_record") @TableName("content_audit_record")
public class ContentAuditRecord { public class ContentAuditRecord {
@TableId(type = IdType.AUTO) @TableId(type = IdType.ASSIGN_ID)
private Long id; private Long id;
/** COMMENT/DRAMA/AVATAR/CREATOR */ /** COMMENT/DRAMA/AVATAR/CREATOR */
private String bizType; private String bizType;
@@ -15,7 +15,7 @@ import java.time.LocalDateTime;
@TableName("content_comment") @TableName("content_comment")
public class ContentComment { public class ContentComment {
@TableId(type = IdType.AUTO) @TableId(type = IdType.ASSIGN_ID)
private Long id; private Long id;
private Long dramaId; private Long dramaId;
private Long episodeId; private Long episodeId;
@@ -13,7 +13,7 @@ import java.time.LocalDateTime;
@TableName("content_like") @TableName("content_like")
public class ContentLike { public class ContentLike {
@TableId(type = IdType.AUTO) @TableId(type = IdType.ASSIGN_ID)
private Long id; private Long id;
private Long userId; private Long userId;
/** DRAMA/EPISODE/COMMENT */ /** DRAMA/EPISODE/COMMENT */
@@ -15,7 +15,7 @@ import java.time.LocalDateTime;
@TableName("content_report") @TableName("content_report")
public class ContentReport { public class ContentReport {
@TableId(type = IdType.AUTO) @TableId(type = IdType.ASSIGN_ID)
private Long id; private Long id;
private Long reporterId; private Long reporterId;
/** COMMENT/USER/DRAMA */ /** COMMENT/USER/DRAMA */
@@ -12,7 +12,7 @@ import java.time.LocalDateTime;
@TableName("content_share") @TableName("content_share")
public class ContentShare { public class ContentShare {
@TableId(type = IdType.AUTO) @TableId(type = IdType.ASSIGN_ID)
private Long id; private Long id;
private Long userId; private Long userId;
private Long dramaId; private Long dramaId;
@@ -15,7 +15,7 @@ import java.time.LocalDateTime;
@TableName("sensitive_word") @TableName("sensitive_word")
public class SensitiveWord { public class SensitiveWord {
@TableId(type = IdType.AUTO) @TableId(type = IdType.ASSIGN_ID)
private Long id; private Long id;
private String word; private String word;
/** POLITICS/PORN/ABUSE/AD/RELIGION */ /** POLITICS/PORN/ABUSE/AD/RELIGION */
@@ -13,7 +13,7 @@ import java.time.LocalDateTime;
@TableName("user_blocklist") @TableName("user_blocklist")
public class UserBlocklist { public class UserBlocklist {
@TableId(type = IdType.AUTO) @TableId(type = IdType.ASSIGN_ID)
private Long id; private Long id;
private Long userId; private Long userId;
private Long blockedUserId; private Long blockedUserId;
@@ -14,7 +14,7 @@ import java.time.LocalDateTime;
@TableName("media_asset") @TableName("media_asset")
public class MediaAsset { public class MediaAsset {
@TableId(type = IdType.AUTO) @TableId(type = IdType.ASSIGN_ID)
private Long id; private Long id;
private String bizType; private String bizType;
private String fileName; private String fileName;
@@ -15,7 +15,7 @@ import java.time.LocalDateTime;
@TableName("media_rendition") @TableName("media_rendition")
public class MediaRendition { public class MediaRendition {
@TableId(type = IdType.AUTO) @TableId(type = IdType.ASSIGN_ID)
private Long id; private Long id;
private Long mediaAssetId; private Long mediaAssetId;
private Long dramaId; private Long dramaId;
@@ -13,7 +13,7 @@ import java.time.LocalDateTime;
@TableName("media_upload_task") @TableName("media_upload_task")
public class MediaUploadTask { public class MediaUploadTask {
@TableId(type = IdType.AUTO) @TableId(type = IdType.ASSIGN_ID)
private Long id; private Long id;
private String uploadId; private String uploadId;
private String bizType; private String bizType;
@@ -15,7 +15,7 @@ import java.time.LocalDateTime;
@TableName("transcode_task") @TableName("transcode_task")
public class TranscodeTask { public class TranscodeTask {
@TableId(type = IdType.AUTO) @TableId(type = IdType.ASSIGN_ID)
private Long id; private Long id;
private Long mediaAssetId; private Long mediaAssetId;
private Long dramaId; private Long dramaId;
@@ -15,7 +15,7 @@ import java.time.LocalDateTime;
@TableName("download_license") @TableName("download_license")
public class DownloadLicense { public class DownloadLicense {
@TableId(type = IdType.AUTO) @TableId(type = IdType.ASSIGN_ID)
private Long id; private Long id;
private Long userId; private Long userId;
private Long dramaId; private Long dramaId;
@@ -18,7 +18,7 @@ import java.time.LocalDateTime;
@TableName("download_task") @TableName("download_task")
public class DownloadTask { public class DownloadTask {
@TableId(type = IdType.AUTO) @TableId(type = IdType.ASSIGN_ID)
private Long id; private Long id;
private Long userId; private Long userId;
private String deviceId; private String deviceId;
@@ -15,7 +15,7 @@ import java.time.LocalDateTime;
@TableName("playback_ticket") @TableName("playback_ticket")
public class PlaybackTicket { public class PlaybackTicket {
@TableId(type = IdType.AUTO) @TableId(type = IdType.ASSIGN_ID)
private Long id; private Long id;
private String ticketNo; private String ticketNo;
private Long userId; private Long userId;
@@ -15,7 +15,7 @@ import java.time.LocalDateTime;
@TableName("user_favorite") @TableName("user_favorite")
public class UserFavorite { public class UserFavorite {
@TableId(type = IdType.AUTO) @TableId(type = IdType.ASSIGN_ID)
private Long id; private Long id;
private Long userId; private Long userId;
private Long dramaId; private Long dramaId;
@@ -16,7 +16,7 @@ import java.time.LocalDateTime;
@TableName("watch_history") @TableName("watch_history")
public class WatchHistory { public class WatchHistory {
@TableId(type = IdType.AUTO) @TableId(type = IdType.ASSIGN_ID)
private Long id; private Long id;
private Long userId; private Long userId;
private Long dramaId; private Long dramaId;
@@ -15,7 +15,7 @@ import java.time.LocalDateTime;
@TableName("watch_progress") @TableName("watch_progress")
public class WatchProgress { public class WatchProgress {
@TableId(type = IdType.AUTO) @TableId(type = IdType.ASSIGN_ID)
private Long id; private Long id;
private Long userId; private Long userId;
private Long dramaId; private Long dramaId;
@@ -14,7 +14,7 @@ import java.time.LocalDateTime;
@TableName("sys_admin_user") @TableName("sys_admin_user")
public class AdminUser { public class AdminUser {
@TableId(type = IdType.AUTO) @TableId(type = IdType.ASSIGN_ID)
private Long id; private Long id;
private String username; private String username;
private String password; private String password;
@@ -13,7 +13,7 @@ import lombok.NoArgsConstructor;
@TableName("sys_admin_user_role") @TableName("sys_admin_user_role")
public class AdminUserRole { public class AdminUserRole {
@TableId(type = IdType.AUTO) @TableId(type = IdType.ASSIGN_ID)
private Long id; private Long id;
private Long userId; private Long userId;
private Long roleId; private Long roleId;
@@ -17,7 +17,7 @@ import java.time.LocalDateTime;
@TableName("audit_log") @TableName("audit_log")
public class AuditLog { public class AuditLog {
@TableId(type = IdType.AUTO) @TableId(type = IdType.ASSIGN_ID)
private Long id; private Long id;
/** ORDER / ENTITLEMENT / USER / CREATOR / PRICE */ /** ORDER / ENTITLEMENT / USER / CREATOR / PRICE */
private String bizType; private String bizType;
@@ -13,7 +13,7 @@ import java.time.LocalDateTime;
@TableName("sys_menu") @TableName("sys_menu")
public class Menu { public class Menu {
@TableId(type = IdType.AUTO) @TableId(type = IdType.ASSIGN_ID)
private Long id; private Long id;
private Long parentId; private Long parentId;
private String title; private String title;
@@ -11,7 +11,7 @@ import java.time.LocalDateTime;
@TableName("sys_operation_log") @TableName("sys_operation_log")
public class OperationLog { public class OperationLog {
@TableId(type = IdType.AUTO) @TableId(type = IdType.ASSIGN_ID)
private Long id; private Long id;
private Long adminUserId; private Long adminUserId;
private String username; private String username;
@@ -9,7 +9,7 @@ import lombok.Data;
@TableName("sys_permission") @TableName("sys_permission")
public class Permission { public class Permission {
@TableId(type = IdType.AUTO) @TableId(type = IdType.ASSIGN_ID)
private Long id; private Long id;
private String code; private String code;
private String name; private String name;
@@ -14,7 +14,7 @@ import java.time.LocalDateTime;
@TableName("sys_role") @TableName("sys_role")
public class Role { public class Role {
@TableId(type = IdType.AUTO) @TableId(type = IdType.ASSIGN_ID)
private Long id; private Long id;
private String name; private String name;
private String code; private String code;
@@ -14,7 +14,7 @@ import java.time.LocalDateTime;
@TableName("sys_role_category") @TableName("sys_role_category")
public class RoleCategory { public class RoleCategory {
@TableId(type = IdType.AUTO) @TableId(type = IdType.ASSIGN_ID)
private Long id; private Long id;
private String name; private String name;
private String description; private String description;
@@ -13,7 +13,7 @@ import lombok.NoArgsConstructor;
@TableName("sys_role_menu") @TableName("sys_role_menu")
public class RoleMenu { public class RoleMenu {
@TableId(type = IdType.AUTO) @TableId(type = IdType.ASSIGN_ID)
private Long id; private Long id;
private Long roleId; private Long roleId;
private Long menuId; private Long menuId;
@@ -13,7 +13,7 @@ import lombok.NoArgsConstructor;
@TableName("sys_role_permission") @TableName("sys_role_permission")
public class RolePermission { public class RolePermission {
@TableId(type = IdType.AUTO) @TableId(type = IdType.ASSIGN_ID)
private Long id; private Long id;
private Long roleId; private Long roleId;
private Long permissionId; private Long permissionId;
@@ -9,7 +9,7 @@ import lombok.Data;
@TableName("sys_config") @TableName("sys_config")
public class SysConfig { public class SysConfig {
@TableId(type = IdType.AUTO) @TableId(type = IdType.ASSIGN_ID)
private Long id; private Long id;
private String configKey; private String configKey;
private String configValue; private String configValue;
@@ -15,7 +15,7 @@ import java.time.LocalDateTime;
@TableName("app_account_deletion") @TableName("app_account_deletion")
public class AppAccountDeletion { public class AppAccountDeletion {
@TableId(type = IdType.AUTO) @TableId(type = IdType.ASSIGN_ID)
private Long id; private Long id;
private Long userId; private Long userId;
/** pending/cancelled/completed */ /** pending/cancelled/completed */
@@ -16,7 +16,7 @@ import java.time.LocalDateTime;
@TableName("app_user") @TableName("app_user")
public class AppUser { public class AppUser {
@TableId(type = IdType.AUTO) @TableId(type = IdType.ASSIGN_ID)
private Long id; private Long id;
/** 对外用户标识,接口只暴露 uid,不暴露自增 ID */ /** 对外用户标识,接口只暴露 uid,不暴露自增 ID */
private String uid; private String uid;
@@ -15,7 +15,7 @@ import java.time.LocalDateTime;
@TableName("app_user_ban_record") @TableName("app_user_ban_record")
public class AppUserBanRecord { public class AppUserBanRecord {
@TableId(type = IdType.AUTO) @TableId(type = IdType.ASSIGN_ID)
private Long id; private Long id;
private Long userId; private Long userId;
/** BAN/LIMIT/MUTE */ /** BAN/LIMIT/MUTE */
@@ -15,7 +15,7 @@ import java.time.LocalDateTime;
@TableName("app_user_consent") @TableName("app_user_consent")
public class AppUserConsent { public class AppUserConsent {
@TableId(type = IdType.AUTO) @TableId(type = IdType.ASSIGN_ID)
private Long id; private Long id;
private Long userId; private Long userId;
private String scene; private String scene;
@@ -15,7 +15,7 @@ import java.time.LocalDateTime;
@TableName("app_user_credential") @TableName("app_user_credential")
public class AppUserCredential { public class AppUserCredential {
@TableId(type = IdType.AUTO) @TableId(type = IdType.ASSIGN_ID)
private Long id; private Long id;
private Long userId; private Long userId;
/** PHONE/EMAIL/APPLE/GOOGLE */ /** PHONE/EMAIL/APPLE/GOOGLE */
@@ -15,7 +15,7 @@ import java.time.LocalDateTime;
@TableName("app_user_device") @TableName("app_user_device")
public class AppUserDevice { public class AppUserDevice {
@TableId(type = IdType.AUTO) @TableId(type = IdType.ASSIGN_ID)
private Long id; private Long id;
private Long userId; private Long userId;
private String deviceId; private String deviceId;
@@ -15,7 +15,7 @@ import java.time.LocalDateTime;
@TableName("app_user_otp") @TableName("app_user_otp")
public class AppUserOtp { public class AppUserOtp {
@TableId(type = IdType.AUTO) @TableId(type = IdType.ASSIGN_ID)
private Long id; private Long id;
private String scene; private String scene;
private String targetType; private String targetType;
@@ -15,7 +15,7 @@ import java.time.LocalDateTime;
@TableName("app_user_session") @TableName("app_user_session")
public class AppUserSession { public class AppUserSession {
@TableId(type = IdType.AUTO) @TableId(type = IdType.ASSIGN_ID)
private Long id; private Long id;
private Long userId; private Long userId;
private String refreshTokenHash; private String refreshTokenHash;
+49
View File
@@ -0,0 +1,49 @@
-- Author: fruit.com.cn
--
-- S0 主键改雪花 · 存量库迁移(PostgreSQL 18)
--
-- 背景:第一阶段建表用的是 GENERATED BY DEFAULT AS IDENTITY(数据库自增序列),
-- 这会让 ID 分配集中在单库的序列上,一旦分库分表就无法横向扩展。
-- S0 把主键改成应用侧雪花 ID(MyBatis-Plus IdType.ASSIGN_ID),
-- DDL 侧只需要把 identity 去掉——序列不再需要。
--
-- 本脚本只做一件事:把所有 identity 列改成普通 BIGINT(**保留已有数据,不重建表**)。
-- 刻意不用 DROP TABLE / TRUNCATE,避免误伤存量数据。
-- 幂等:已经迁移过的库再跑一遍不做任何改动,NOTICE 里的数字会是 0。
--
-- 执行:psql -h 127.0.0.1 -U fruitshorts -d fruitshorts -f sql/migrate-s0-snowflake.sql
-- 复查:脚本末尾的注释 SQL(改写后应返回 0 行)
DO $$
DECLARE
r record;
v_done int := 0;
BEGIN
-- relispartition = false 表示"只处理顶层表":
-- 分区父表在 pg_class 里 relkind = 'p',月分区子表 relispartition = true;
-- identity 定义在父表上,子表跟着继承,所以逐个改子表是多余的。
FOR r IN
SELECT c.oid::regclass AS tbl, a.attname AS col
FROM pg_class c
JOIN pg_namespace n ON n.oid = c.relnamespace
JOIN pg_attribute a ON a.attrelid = c.oid
WHERE n.nspname = 'public'
AND c.relkind IN ('r', 'p')
AND c.relispartition = false
AND a.attidentity <> ''
AND a.attnum > 0
ORDER BY c.relname
LOOP
EXECUTE format('ALTER TABLE %s ALTER COLUMN %I DROP IDENTITY IF EXISTS', r.tbl, r.col);
v_done := v_done + 1;
END LOOP;
RAISE NOTICE 'S0 迁移完成:处理 % 个 identity 列(重复执行时为 0)', v_done;
END $$;
-- 复查用(结果应为 0 行):
-- SELECT c.relname, a.attname
-- FROM pg_class c
-- JOIN pg_namespace n ON n.oid = c.relnamespace
-- JOIN pg_attribute a ON a.attrelid = c.oid
-- WHERE n.nspname = 'public' AND a.attidentity <> ''
-- ORDER BY 1, 2;
+2 -2
View File
@@ -99,7 +99,7 @@ BEGIN
END IF; END IF;
CREATE TABLE IF NOT EXISTS playback_ticket ( CREATE TABLE IF NOT EXISTS playback_ticket (
id BIGINT GENERATED BY DEFAULT AS IDENTITY, id BIGINT,
ticket_no VARCHAR(40) NOT NULL, ticket_no VARCHAR(40) NOT NULL,
user_id BIGINT NOT NULL DEFAULT 0, user_id BIGINT NOT NULL DEFAULT 0,
drama_id BIGINT NOT NULL, drama_id BIGINT NOT NULL,
@@ -134,7 +134,7 @@ BEGIN
END IF; END IF;
CREATE TABLE IF NOT EXISTS order_event ( CREATE TABLE IF NOT EXISTS order_event (
id BIGINT GENERATED BY DEFAULT AS IDENTITY, id BIGINT,
order_no VARCHAR(40) NOT NULL, order_no VARCHAR(40) NOT NULL,
event VARCHAR(32) NOT NULL, event VARCHAR(32) NOT NULL,
from_status VARCHAR(16) NOT NULL DEFAULT '', from_status VARCHAR(16) NOT NULL DEFAULT '',
+41 -41
View File
@@ -9,7 +9,7 @@
-- 具体的月分区由 sql/partition-maintenance.sql 创建(并把已存在的普通表转成分区表)。 -- 具体的月分区由 sql/partition-maintenance.sql 创建(并把已存在的普通表转成分区表)。
-- --
-- 命名与类型约定(与 sql/schema.sql 保持一致): -- 命名与类型约定(与 sql/schema.sql 保持一致):
-- BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY -- BIGINT PRIMARY KEY(不设默认值;主键由应用侧雪花算法生成:MyBatis-Plus IdType.ASSIGN_ID)
-- 布尔语义用 SMALLINT(1/0),时间用 TIMESTAMP(3),默认 CURRENT_TIMESTAMP -- 布尔语义用 SMALLINT(1/0),时间用 TIMESTAMP(3),默认 CURRENT_TIMESTAMP
-- 逻辑删除 deleted SMALLINT NOT NULL DEFAULT 0 -- 逻辑删除 deleted SMALLINT NOT NULL DEFAULT 0
-- updated_at 由 set_updated_at() 触发器维护 -- updated_at 由 set_updated_at() 触发器维护
@@ -53,7 +53,7 @@ ALTER TABLE media_asset ADD COLUMN IF NOT EXISTS storage_type VARCHAR(16) NO
-- ============================================================ -- ============================================================
CREATE TABLE IF NOT EXISTS app_user ( CREATE TABLE IF NOT EXISTS app_user (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, id BIGINT PRIMARY KEY,
uid VARCHAR(32) NOT NULL, -- 对外展示的用户标识,避免暴露自增 ID uid VARCHAR(32) NOT NULL, -- 对外展示的用户标识,避免暴露自增 ID
nickname VARCHAR(64) NOT NULL DEFAULT '', nickname VARCHAR(64) NOT NULL DEFAULT '',
avatar_url VARCHAR(512) NOT NULL DEFAULT '', avatar_url VARCHAR(512) NOT NULL DEFAULT '',
@@ -89,7 +89,7 @@ CREATE INDEX IF NOT EXISTS idx_app_user_created ON app_user (created_at DESC);
COMMENT ON TABLE app_user IS 'C 端用户'; COMMENT ON TABLE app_user IS 'C 端用户';
CREATE TABLE IF NOT EXISTS app_user_credential ( CREATE TABLE IF NOT EXISTS app_user_credential (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, id BIGINT PRIMARY KEY,
user_id BIGINT NOT NULL, user_id BIGINT NOT NULL,
type VARCHAR(16) NOT NULL, -- PHONE/EMAIL/APPLE/GOOGLE type VARCHAR(16) NOT NULL, -- PHONE/EMAIL/APPLE/GOOGLE
identifier VARCHAR(191) NOT NULL, -- E.164 手机号 / 邮箱 / 第三方唯一标识 identifier VARCHAR(191) NOT NULL, -- E.164 手机号 / 邮箱 / 第三方唯一标识
@@ -108,7 +108,7 @@ CREATE INDEX IF NOT EXISTS idx_app_credential_user ON app_user_credential (user_
COMMENT ON TABLE app_user_credential IS 'C 端登录凭证(手机号/邮箱/第三方)'; COMMENT ON TABLE app_user_credential IS 'C 端登录凭证(手机号/邮箱/第三方)';
CREATE TABLE IF NOT EXISTS app_user_session ( CREATE TABLE IF NOT EXISTS app_user_session (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, id BIGINT PRIMARY KEY,
user_id BIGINT NOT NULL, user_id BIGINT NOT NULL,
refresh_token_hash VARCHAR(64) NOT NULL, -- SHA-256,不存明文 refresh_token_hash VARCHAR(64) NOT NULL, -- SHA-256,不存明文
device_id VARCHAR(128) NOT NULL DEFAULT '', device_id VARCHAR(128) NOT NULL DEFAULT '',
@@ -130,7 +130,7 @@ CREATE INDEX IF NOT EXISTS idx_app_session_user ON app_user_session (user_id, re
COMMENT ON TABLE app_user_session IS 'C 端会话(可多设备)'; COMMENT ON TABLE app_user_session IS 'C 端会话(可多设备)';
CREATE TABLE IF NOT EXISTS app_user_otp ( CREATE TABLE IF NOT EXISTS app_user_otp (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, id BIGINT PRIMARY KEY,
scene VARCHAR(16) NOT NULL, -- REGISTER/LOGIN/RESET_PWD/BIND scene VARCHAR(16) NOT NULL, -- REGISTER/LOGIN/RESET_PWD/BIND
target_type VARCHAR(16) NOT NULL, -- PHONE/EMAIL target_type VARCHAR(16) NOT NULL, -- PHONE/EMAIL
target VARCHAR(191) NOT NULL, target VARCHAR(191) NOT NULL,
@@ -150,7 +150,7 @@ CREATE INDEX IF NOT EXISTS idx_app_otp_ip ON app_user_otp (send_ip, created_at D
COMMENT ON TABLE app_user_otp IS '验证码发送与校验记录(同时用于反刷频控)'; COMMENT ON TABLE app_user_otp IS '验证码发送与校验记录(同时用于反刷频控)';
CREATE TABLE IF NOT EXISTS app_user_consent ( CREATE TABLE IF NOT EXISTS app_user_consent (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, id BIGINT PRIMARY KEY,
user_id BIGINT NOT NULL, user_id BIGINT NOT NULL,
scene VARCHAR(32) NOT NULL, -- PRIVACY/TERMS/MARKETING/PERSONALIZED_AD scene VARCHAR(32) NOT NULL, -- PRIVACY/TERMS/MARKETING/PERSONALIZED_AD
version VARCHAR(32) NOT NULL DEFAULT '', version VARCHAR(32) NOT NULL DEFAULT '',
@@ -165,7 +165,7 @@ CREATE INDEX IF NOT EXISTS idx_app_consent_user ON app_user_consent (user_id, sc
COMMENT ON TABLE app_user_consent IS '同意管理记录,商店审核与隐私合规要求可追溯'; COMMENT ON TABLE app_user_consent IS '同意管理记录,商店审核与隐私合规要求可追溯';
CREATE TABLE IF NOT EXISTS app_user_device ( CREATE TABLE IF NOT EXISTS app_user_device (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, id BIGINT PRIMARY KEY,
user_id BIGINT NOT NULL, user_id BIGINT NOT NULL,
device_id VARCHAR(128) NOT NULL, device_id VARCHAR(128) NOT NULL,
platform VARCHAR(16) NOT NULL DEFAULT '', platform VARCHAR(16) NOT NULL DEFAULT '',
@@ -181,7 +181,7 @@ CREATE UNIQUE INDEX IF NOT EXISTS uk_app_device ON app_user_device (user_id, dev
COMMENT ON TABLE app_user_device IS '用户设备,用于下载授权与并发播放数限制'; COMMENT ON TABLE app_user_device IS '用户设备,用于下载授权与并发播放数限制';
CREATE TABLE IF NOT EXISTS app_user_ban_record ( CREATE TABLE IF NOT EXISTS app_user_ban_record (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, id BIGINT PRIMARY KEY,
user_id BIGINT NOT NULL, user_id BIGINT NOT NULL,
type VARCHAR(16) NOT NULL, -- BAN/LIMIT/MUTE type VARCHAR(16) NOT NULL, -- BAN/LIMIT/MUTE
reason_code VARCHAR(32) NOT NULL DEFAULT '', reason_code VARCHAR(32) NOT NULL DEFAULT '',
@@ -205,7 +205,7 @@ CREATE INDEX IF NOT EXISTS idx_app_ban_user ON app_user_ban_record (user_id, sta
COMMENT ON TABLE app_user_ban_record IS '封禁/限制与申诉记录'; COMMENT ON TABLE app_user_ban_record IS '封禁/限制与申诉记录';
CREATE TABLE IF NOT EXISTS app_account_deletion ( CREATE TABLE IF NOT EXISTS app_account_deletion (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, id BIGINT PRIMARY KEY,
user_id BIGINT NOT NULL, user_id BIGINT NOT NULL,
status VARCHAR(16) NOT NULL DEFAULT 'pending', -- pending/cancelled/completed status VARCHAR(16) NOT NULL DEFAULT 'pending', -- pending/cancelled/completed
reason VARCHAR(255) NOT NULL DEFAULT '', reason VARCHAR(255) NOT NULL DEFAULT '',
@@ -226,7 +226,7 @@ COMMENT ON TABLE app_account_deletion IS '账号注销申请与冷静期';
-- ============================================================ -- ============================================================
CREATE TABLE IF NOT EXISTS watch_progress ( CREATE TABLE IF NOT EXISTS watch_progress (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, id BIGINT PRIMARY KEY,
user_id BIGINT NOT NULL, user_id BIGINT NOT NULL,
drama_id BIGINT NOT NULL, drama_id BIGINT NOT NULL,
episode_id BIGINT NOT NULL, episode_id BIGINT NOT NULL,
@@ -246,7 +246,7 @@ COMMENT ON TABLE watch_progress IS '每用户每剧一条续看进度(跨端
-- 观看流水:量大,按 watched_at 做声明式月分区,便于按期归档与清理 -- 观看流水:量大,按 watched_at 做声明式月分区,便于按期归档与清理
CREATE TABLE IF NOT EXISTS watch_history ( CREATE TABLE IF NOT EXISTS watch_history (
id BIGINT GENERATED BY DEFAULT AS IDENTITY, id BIGINT,
user_id BIGINT NOT NULL, user_id BIGINT NOT NULL,
drama_id BIGINT NOT NULL, drama_id BIGINT NOT NULL,
episode_id BIGINT NOT NULL, episode_id BIGINT NOT NULL,
@@ -263,7 +263,7 @@ CREATE INDEX IF NOT EXISTS idx_watch_history_drama ON watch_history (drama_id, w
COMMENT ON TABLE watch_history IS '观看流水(月分区,保留 12–24 个月)'; COMMENT ON TABLE watch_history IS '观看流水(月分区,保留 12–24 个月)';
CREATE TABLE IF NOT EXISTS user_favorite ( CREATE TABLE IF NOT EXISTS user_favorite (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, id BIGINT PRIMARY KEY,
user_id BIGINT NOT NULL, user_id BIGINT NOT NULL,
drama_id BIGINT NOT NULL, drama_id BIGINT NOT NULL,
sort INT NOT NULL DEFAULT 0, sort INT NOT NULL DEFAULT 0,
@@ -280,7 +280,7 @@ COMMENT ON TABLE user_favorite IS '剧集收藏';
-- 唯一索引是 (ticket_no, created_at);ticket_no 是 UUID,实际唯一性不受影响。 -- 唯一索引是 (ticket_no, created_at);ticket_no 是 UUID,实际唯一性不受影响。
-- 月分区本身由 sql/partition-maintenance.sql 建(含未来 3 个月)。 -- 月分区本身由 sql/partition-maintenance.sql 建(含未来 3 个月)。
CREATE TABLE IF NOT EXISTS playback_ticket ( CREATE TABLE IF NOT EXISTS playback_ticket (
id BIGINT GENERATED BY DEFAULT AS IDENTITY, id BIGINT,
ticket_no VARCHAR(40) NOT NULL, ticket_no VARCHAR(40) NOT NULL,
user_id BIGINT NOT NULL DEFAULT 0, -- 0 表示未登录的免费集 user_id BIGINT NOT NULL DEFAULT 0, -- 0 表示未登录的免费集
drama_id BIGINT NOT NULL, drama_id BIGINT NOT NULL,
@@ -303,7 +303,7 @@ CREATE INDEX IF NOT EXISTS idx_playback_ticket_user
COMMENT ON TABLE playback_ticket IS '播放票据签发审计;真正的鉴权在签名 URL 上(月分区)'; COMMENT ON TABLE playback_ticket IS '播放票据签发审计;真正的鉴权在签名 URL 上(月分区)';
CREATE TABLE IF NOT EXISTS download_license ( CREATE TABLE IF NOT EXISTS download_license (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, id BIGINT PRIMARY KEY,
user_id BIGINT NOT NULL, user_id BIGINT NOT NULL,
drama_id BIGINT NOT NULL, drama_id BIGINT NOT NULL,
episode_id BIGINT NOT NULL, episode_id BIGINT NOT NULL,
@@ -326,7 +326,7 @@ COMMENT ON TABLE download_license IS '离线下载授权与设备绑定(换机
-- ============================================================ -- ============================================================
CREATE TABLE IF NOT EXISTS content_comment ( CREATE TABLE IF NOT EXISTS content_comment (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, id BIGINT PRIMARY KEY,
drama_id BIGINT NOT NULL, drama_id BIGINT NOT NULL,
episode_id BIGINT NOT NULL DEFAULT 0, episode_id BIGINT NOT NULL DEFAULT 0,
user_id BIGINT NOT NULL, user_id BIGINT NOT NULL,
@@ -352,7 +352,7 @@ CREATE INDEX IF NOT EXISTS idx_comment_user ON content_comment (user_id, created
COMMENT ON TABLE content_comment IS '评论与回复(先审后发)'; COMMENT ON TABLE content_comment IS '评论与回复(先审后发)';
CREATE TABLE IF NOT EXISTS content_like ( CREATE TABLE IF NOT EXISTS content_like (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, id BIGINT PRIMARY KEY,
user_id BIGINT NOT NULL, user_id BIGINT NOT NULL,
target_type VARCHAR(16) NOT NULL, -- DRAMA/EPISODE/COMMENT target_type VARCHAR(16) NOT NULL, -- DRAMA/EPISODE/COMMENT
target_id BIGINT NOT NULL, target_id BIGINT NOT NULL,
@@ -364,7 +364,7 @@ CREATE INDEX IF NOT EXISTS idx_content_like_target ON content_like (target_type,
COMMENT ON TABLE content_like IS '点赞关系;计数值异步聚合'; COMMENT ON TABLE content_like IS '点赞关系;计数值异步聚合';
CREATE TABLE IF NOT EXISTS content_report ( CREATE TABLE IF NOT EXISTS content_report (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, id BIGINT PRIMARY KEY,
reporter_id BIGINT NOT NULL, reporter_id BIGINT NOT NULL,
target_type VARCHAR(16) NOT NULL, -- COMMENT/USER/DRAMA target_type VARCHAR(16) NOT NULL, -- COMMENT/USER/DRAMA
target_id BIGINT NOT NULL, target_id BIGINT NOT NULL,
@@ -383,7 +383,7 @@ CREATE INDEX IF NOT EXISTS idx_report_status ON content_report (status, created_
COMMENT ON TABLE content_report IS '举报工单'; COMMENT ON TABLE content_report IS '举报工单';
CREATE TABLE IF NOT EXISTS user_blocklist ( CREATE TABLE IF NOT EXISTS user_blocklist (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, id BIGINT PRIMARY KEY,
user_id BIGINT NOT NULL, user_id BIGINT NOT NULL,
blocked_user_id BIGINT NOT NULL, blocked_user_id BIGINT NOT NULL,
source VARCHAR(16) NOT NULL DEFAULT 'MANUAL', -- MANUAL/COMMENT source VARCHAR(16) NOT NULL DEFAULT 'MANUAL', -- MANUAL/COMMENT
@@ -394,7 +394,7 @@ CREATE UNIQUE INDEX IF NOT EXISTS uk_user_blocklist ON user_blocklist (user_id,
COMMENT ON TABLE user_blocklist IS '拉黑关系'; COMMENT ON TABLE user_blocklist IS '拉黑关系';
CREATE TABLE IF NOT EXISTS sensitive_word ( CREATE TABLE IF NOT EXISTS sensitive_word (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, id BIGINT PRIMARY KEY,
word VARCHAR(64) NOT NULL, word VARCHAR(64) NOT NULL,
category VARCHAR(32) NOT NULL DEFAULT '', -- POLITICS/PORN/ABUSE/AD/RELIGION category VARCHAR(32) NOT NULL DEFAULT '', -- POLITICS/PORN/ABUSE/AD/RELIGION
level VARCHAR(16) NOT NULL DEFAULT 'REVIEW', -- BLOCK/REVIEW/REPLACE level VARCHAR(16) NOT NULL DEFAULT 'REVIEW', -- BLOCK/REVIEW/REPLACE
@@ -409,7 +409,7 @@ CREATE UNIQUE INDEX IF NOT EXISTS uk_sensitive_word ON sensitive_word (language,
COMMENT ON TABLE sensitive_word IS '敏感词库'; COMMENT ON TABLE sensitive_word IS '敏感词库';
CREATE TABLE IF NOT EXISTS content_audit_record ( CREATE TABLE IF NOT EXISTS content_audit_record (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, id BIGINT PRIMARY KEY,
biz_type VARCHAR(16) NOT NULL, -- COMMENT/DRAMA/AVATAR/CREATOR biz_type VARCHAR(16) NOT NULL, -- COMMENT/DRAMA/AVATAR/CREATOR
biz_id BIGINT NOT NULL, biz_id BIGINT NOT NULL,
round INT NOT NULL DEFAULT 1, round INT NOT NULL DEFAULT 1,
@@ -427,7 +427,7 @@ CREATE INDEX IF NOT EXISTS idx_audit_biz ON content_audit_record (biz_type, biz_
COMMENT ON TABLE content_audit_record IS '审核留证(机审 + 人审都记)'; COMMENT ON TABLE content_audit_record IS '审核留证(机审 + 人审都记)';
CREATE TABLE IF NOT EXISTS content_share ( CREATE TABLE IF NOT EXISTS content_share (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, id BIGINT PRIMARY KEY,
user_id BIGINT NOT NULL DEFAULT 0, user_id BIGINT NOT NULL DEFAULT 0,
drama_id BIGINT NOT NULL, drama_id BIGINT NOT NULL,
episode_id BIGINT NOT NULL DEFAULT 0, episode_id BIGINT NOT NULL DEFAULT 0,
@@ -442,7 +442,7 @@ COMMENT ON TABLE content_share IS '分享事件,用于渠道效果与裂变分
-- ============================================================ -- ============================================================
CREATE TABLE IF NOT EXISTS wallet ( CREATE TABLE IF NOT EXISTS wallet (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, id BIGINT PRIMARY KEY,
user_id BIGINT NOT NULL, user_id BIGINT NOT NULL,
coin_balance BIGINT NOT NULL DEFAULT 0, coin_balance BIGINT NOT NULL DEFAULT 0,
total_recharged_coin BIGINT NOT NULL DEFAULT 0, total_recharged_coin BIGINT NOT NULL DEFAULT 0,
@@ -457,7 +457,7 @@ CREATE UNIQUE INDEX IF NOT EXISTS uk_wallet_user ON wallet (user_id);
COMMENT ON TABLE wallet IS '金币钱包;所有变动必须同时写 coin_ledger'; COMMENT ON TABLE wallet IS '金币钱包;所有变动必须同时写 coin_ledger';
CREATE TABLE IF NOT EXISTS product ( CREATE TABLE IF NOT EXISTS product (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, id BIGINT PRIMARY KEY,
code VARCHAR(64) NOT NULL, code VARCHAR(64) NOT NULL,
name VARCHAR(128) NOT NULL, name VARCHAR(128) NOT NULL,
type VARCHAR(16) NOT NULL DEFAULT 'COIN_PACK', -- COIN_PACK/VIP/EPISODE_PACK(VIP 为第二阶段预留) type VARCHAR(16) NOT NULL DEFAULT 'COIN_PACK', -- COIN_PACK/VIP/EPISODE_PACK(VIP 为第二阶段预留)
@@ -483,7 +483,7 @@ CREATE INDEX IF NOT EXISTS idx_product_platform ON product (platform, status);
COMMENT ON TABLE product IS '商品配置(金币包;会员与活动价为后续阶段预留)'; COMMENT ON TABLE product IS '商品配置(金币包;会员与活动价为后续阶段预留)';
CREATE TABLE IF NOT EXISTS orders ( CREATE TABLE IF NOT EXISTS orders (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, id BIGINT PRIMARY KEY,
order_no VARCHAR(40) NOT NULL, order_no VARCHAR(40) NOT NULL,
user_id BIGINT NOT NULL, user_id BIGINT NOT NULL,
product_id BIGINT NOT NULL DEFAULT 0, product_id BIGINT NOT NULL DEFAULT 0,
@@ -522,7 +522,7 @@ COMMENT ON TABLE orders IS '订单;orders 为保留字规避(order 是 SQL
-- 订单状态流转流水,同样按月分区(同 playback_ticket,主键带分区键) -- 订单状态流转流水,同样按月分区(同 playback_ticket,主键带分区键)
CREATE TABLE IF NOT EXISTS order_event ( CREATE TABLE IF NOT EXISTS order_event (
id BIGINT GENERATED BY DEFAULT AS IDENTITY, id BIGINT,
order_no VARCHAR(40) NOT NULL, order_no VARCHAR(40) NOT NULL,
event VARCHAR(32) NOT NULL, -- CREATE/VERIFY_OK/VERIFY_FAIL/DELIVER/REFUND/NOTIFY event VARCHAR(32) NOT NULL, -- CREATE/VERIFY_OK/VERIFY_FAIL/DELIVER/REFUND/NOTIFY
from_status VARCHAR(16) NOT NULL DEFAULT '', from_status VARCHAR(16) NOT NULL DEFAULT '',
@@ -537,7 +537,7 @@ CREATE INDEX IF NOT EXISTS idx_order_event_no ON order_event (order_no, created_
COMMENT ON TABLE order_event IS '订单状态流转流水,支付争议时的证据链(月分区)'; COMMENT ON TABLE order_event IS '订单状态流转流水,支付争议时的证据链(月分区)';
CREATE TABLE IF NOT EXISTS store_receipt ( CREATE TABLE IF NOT EXISTS store_receipt (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, id BIGINT PRIMARY KEY,
platform VARCHAR(16) NOT NULL, platform VARCHAR(16) NOT NULL,
transaction_id VARCHAR(128) NOT NULL, transaction_id VARCHAR(128) NOT NULL,
original_transaction_id VARCHAR(128) NOT NULL DEFAULT '', original_transaction_id VARCHAR(128) NOT NULL DEFAULT '',
@@ -557,7 +557,7 @@ CREATE UNIQUE INDEX IF NOT EXISTS uk_store_receipt ON store_receipt (platform, t
COMMENT ON TABLE store_receipt IS '商店票据去重与校验留证(重放防护)'; COMMENT ON TABLE store_receipt IS '商店票据去重与校验留证(重放防护)';
CREATE TABLE IF NOT EXISTS coin_ledger ( CREATE TABLE IF NOT EXISTS coin_ledger (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, id BIGINT PRIMARY KEY,
user_id BIGINT NOT NULL, user_id BIGINT NOT NULL,
change_amount BIGINT NOT NULL, -- 正数入账,负数出账 change_amount BIGINT NOT NULL, -- 正数入账,负数出账
balance_after BIGINT NOT NULL, balance_after BIGINT NOT NULL,
@@ -573,7 +573,7 @@ CREATE INDEX IF NOT EXISTS idx_coin_ledger_user ON coin_ledger (user_id, created
COMMENT ON TABLE coin_ledger IS '金币流水,钱包余额的唯一事实来源'; COMMENT ON TABLE coin_ledger IS '金币流水,钱包余额的唯一事实来源';
CREATE TABLE IF NOT EXISTS entitlement ( CREATE TABLE IF NOT EXISTS entitlement (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, id BIGINT PRIMARY KEY,
user_id BIGINT NOT NULL, user_id BIGINT NOT NULL,
drama_id BIGINT NOT NULL DEFAULT 0, drama_id BIGINT NOT NULL DEFAULT 0,
episode_id BIGINT NOT NULL DEFAULT 0, -- 0 表示整剧权益 episode_id BIGINT NOT NULL DEFAULT 0, -- 0 表示整剧权益
@@ -593,7 +593,7 @@ CREATE INDEX IF NOT EXISTS idx_entitlement_user ON entitlement (user_id, status)
COMMENT ON TABLE entitlement IS '权益;播放判定优先读这里'; COMMENT ON TABLE entitlement IS '权益;播放判定优先读这里';
CREATE TABLE IF NOT EXISTS refund_record ( CREATE TABLE IF NOT EXISTS refund_record (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, id BIGINT PRIMARY KEY,
order_no VARCHAR(40) NOT NULL, order_no VARCHAR(40) NOT NULL,
platform VARCHAR(16) NOT NULL DEFAULT '', platform VARCHAR(16) NOT NULL DEFAULT '',
refund_id VARCHAR(128) NOT NULL DEFAULT '', refund_id VARCHAR(128) NOT NULL DEFAULT '',
@@ -613,7 +613,7 @@ CREATE INDEX IF NOT EXISTS idx_refund_status ON refund_record (status, created_a
COMMENT ON TABLE refund_record IS '退款与撤销事件,触发权益回收'; COMMENT ON TABLE refund_record IS '退款与撤销事件,触发权益回收';
CREATE TABLE IF NOT EXISTS reconcile_task ( CREATE TABLE IF NOT EXISTS reconcile_task (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, id BIGINT PRIMARY KEY,
biz_date DATE NOT NULL, biz_date DATE NOT NULL,
platform VARCHAR(16) NOT NULL DEFAULT 'ALL', platform VARCHAR(16) NOT NULL DEFAULT 'ALL',
total_count INT NOT NULL DEFAULT 0, total_count INT NOT NULL DEFAULT 0,
@@ -635,7 +635,7 @@ COMMENT ON TABLE reconcile_task IS '每日对账任务(与商店账单比对
-- ============================================================ -- ============================================================
CREATE TABLE IF NOT EXISTS creator ( CREATE TABLE IF NOT EXISTS creator (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, id BIGINT PRIMARY KEY,
user_id BIGINT NOT NULL, -- 关联 C 端账号 user_id BIGINT NOT NULL, -- 关联 C 端账号
code VARCHAR(32) NOT NULL, code VARCHAR(32) NOT NULL,
name VARCHAR(128) NOT NULL, name VARCHAR(128) NOT NULL,
@@ -663,7 +663,7 @@ CREATE INDEX IF NOT EXISTS idx_creator_status ON creator (status, created_at DES
COMMENT ON TABLE creator IS '创作者主体与资质'; COMMENT ON TABLE creator IS '创作者主体与资质';
CREATE TABLE IF NOT EXISTS creator_document ( CREATE TABLE IF NOT EXISTS creator_document (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, id BIGINT PRIMARY KEY,
creator_id BIGINT NOT NULL, creator_id BIGINT NOT NULL,
type VARCHAR(32) NOT NULL, -- ID_CARD/BUSINESS_LICENSE/CONTRACT type VARCHAR(32) NOT NULL, -- ID_CARD/BUSINESS_LICENSE/CONTRACT
file_url VARCHAR(512) NOT NULL, file_url VARCHAR(512) NOT NULL,
@@ -678,7 +678,7 @@ CREATE INDEX IF NOT EXISTS idx_creator_doc ON creator_document (creator_id, type
COMMENT ON TABLE creator_document IS '创作者资质文件'; COMMENT ON TABLE creator_document IS '创作者资质文件';
CREATE TABLE IF NOT EXISTS content_submission ( CREATE TABLE IF NOT EXISTS content_submission (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, id BIGINT PRIMARY KEY,
creator_id BIGINT NOT NULL, creator_id BIGINT NOT NULL,
drama_id BIGINT NOT NULL, drama_id BIGINT NOT NULL,
type VARCHAR(16) NOT NULL DEFAULT 'CREATE', -- CREATE/UPDATE/PUBLISH/OFFLINE type VARCHAR(16) NOT NULL DEFAULT 'CREATE', -- CREATE/UPDATE/PUBLISH/OFFLINE
@@ -698,7 +698,7 @@ CREATE INDEX IF NOT EXISTS idx_submission_status ON content_submission (status,
COMMENT ON TABLE content_submission IS '创作者内容提交与审核流转'; COMMENT ON TABLE content_submission IS '创作者内容提交与审核流转';
CREATE TABLE IF NOT EXISTS creator_stat_daily ( CREATE TABLE IF NOT EXISTS creator_stat_daily (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, id BIGINT PRIMARY KEY,
creator_id BIGINT NOT NULL, creator_id BIGINT NOT NULL,
drama_id BIGINT NOT NULL DEFAULT 0, drama_id BIGINT NOT NULL DEFAULT 0,
stat_date DATE NOT NULL, stat_date DATE NOT NULL,
@@ -715,7 +715,7 @@ CREATE UNIQUE INDEX IF NOT EXISTS uk_creator_stat ON creator_stat_daily (creator
COMMENT ON TABLE creator_stat_daily IS '创作者数据看板日汇总'; COMMENT ON TABLE creator_stat_daily IS '创作者数据看板日汇总';
CREATE TABLE IF NOT EXISTS creator_settlement ( CREATE TABLE IF NOT EXISTS creator_settlement (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, id BIGINT PRIMARY KEY,
creator_id BIGINT NOT NULL, creator_id BIGINT NOT NULL,
period VARCHAR(16) NOT NULL, -- 2026-10 period VARCHAR(16) NOT NULL, -- 2026-10
revenue BIGINT NOT NULL DEFAULT 0, revenue BIGINT NOT NULL DEFAULT 0,
@@ -737,7 +737,7 @@ COMMENT ON TABLE creator_settlement IS '预留:创作者结算(第二阶段
-- ============================================================ -- ============================================================
CREATE TABLE IF NOT EXISTS transcode_task ( CREATE TABLE IF NOT EXISTS transcode_task (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, id BIGINT PRIMARY KEY,
media_asset_id BIGINT NOT NULL DEFAULT 0, media_asset_id BIGINT NOT NULL DEFAULT 0,
drama_id BIGINT NOT NULL DEFAULT 0, drama_id BIGINT NOT NULL DEFAULT 0,
episode_id BIGINT NOT NULL DEFAULT 0, episode_id BIGINT NOT NULL DEFAULT 0,
@@ -758,7 +758,7 @@ CREATE INDEX IF NOT EXISTS idx_transcode_episode ON transcode_task (episode_id);
COMMENT ON TABLE transcode_task IS '转码任务队列(本地 worker / 云转码)'; COMMENT ON TABLE transcode_task IS '转码任务队列(本地 worker / 云转码)';
CREATE TABLE IF NOT EXISTS media_rendition ( CREATE TABLE IF NOT EXISTS media_rendition (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, id BIGINT PRIMARY KEY,
media_asset_id BIGINT NOT NULL DEFAULT 0, media_asset_id BIGINT NOT NULL DEFAULT 0,
drama_id BIGINT NOT NULL DEFAULT 0, drama_id BIGINT NOT NULL DEFAULT 0,
episode_id BIGINT NOT NULL DEFAULT 0, episode_id BIGINT NOT NULL DEFAULT 0,
@@ -787,7 +787,7 @@ COMMENT ON TABLE media_rendition IS '多码率产物;播放票据按此生成
-- ============================================================ -- ============================================================
CREATE TABLE IF NOT EXISTS ops_notice ( CREATE TABLE IF NOT EXISTS ops_notice (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, id BIGINT PRIMARY KEY,
title VARCHAR(128) NOT NULL, title VARCHAR(128) NOT NULL,
content VARCHAR(2000) NOT NULL DEFAULT '', content VARCHAR(2000) NOT NULL DEFAULT '',
target VARCHAR(16) NOT NULL DEFAULT 'ALL', -- ALL/USER/CREATOR target VARCHAR(16) NOT NULL DEFAULT 'ALL', -- ALL/USER/CREATOR
@@ -804,7 +804,7 @@ CREATE INDEX IF NOT EXISTS idx_notice_target ON ops_notice (target, status, publ
COMMENT ON TABLE ops_notice IS '系统公告(创作者审核结果、活动、支付通知)'; COMMENT ON TABLE ops_notice IS '系统公告(创作者审核结果、活动、支付通知)';
CREATE TABLE IF NOT EXISTS ops_daily_stat ( CREATE TABLE IF NOT EXISTS ops_daily_stat (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, id BIGINT PRIMARY KEY,
stat_date DATE NOT NULL, stat_date DATE NOT NULL,
new_user_count BIGINT NOT NULL DEFAULT 0, new_user_count BIGINT NOT NULL DEFAULT 0,
active_user_count BIGINT NOT NULL DEFAULT 0, active_user_count BIGINT NOT NULL DEFAULT 0,
@@ -824,7 +824,7 @@ CREATE UNIQUE INDEX IF NOT EXISTS uk_ops_daily_stat ON ops_daily_stat (stat_date
COMMENT ON TABLE ops_daily_stat IS '经营大盘日汇总(含成本口径)'; COMMENT ON TABLE ops_daily_stat IS '经营大盘日汇总(含成本口径)';
CREATE TABLE IF NOT EXISTS audit_log ( CREATE TABLE IF NOT EXISTS audit_log (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, id BIGINT PRIMARY KEY,
biz_type VARCHAR(32) NOT NULL, -- ORDER/ENTITLEMENT/USER/CREATOR/PRICE biz_type VARCHAR(32) NOT NULL, -- ORDER/ENTITLEMENT/USER/CREATOR/PRICE
biz_id VARCHAR(64) NOT NULL DEFAULT '', biz_id VARCHAR(64) NOT NULL DEFAULT '',
action VARCHAR(32) NOT NULL, action VARCHAR(32) NOT NULL,
@@ -878,7 +878,7 @@ ALTER TABLE app_user ADD COLUMN IF NOT EXISTS download_max_quality VARCHAR(16) N
-- 下载任务与断点续传进度。分片由客户端直接向 CDN 拉取,服务端只记账: -- 下载任务与断点续传进度。分片由客户端直接向 CDN 拉取,服务端只记账:
-- 用它实现"下载中/已暂停/已完成"的跨端展示、断点续传的进度恢复,以及配额统计。 -- 用它实现"下载中/已暂停/已完成"的跨端展示、断点续传的进度恢复,以及配额统计。
CREATE TABLE IF NOT EXISTS download_task ( CREATE TABLE IF NOT EXISTS download_task (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, id BIGINT PRIMARY KEY,
user_id BIGINT NOT NULL, user_id BIGINT NOT NULL,
device_id VARCHAR(128) NOT NULL DEFAULT '', device_id VARCHAR(128) NOT NULL DEFAULT '',
drama_id BIGINT NOT NULL, drama_id BIGINT NOT NULL,
+18 -18
View File
@@ -1,7 +1,7 @@
-- FruitShorts 短剧服务 · 建表脚本(PostgreSQL 18) -- FruitShorts 短剧服务 · 建表脚本(PostgreSQL 18)
-- --
-- 与 MySQL 版本的对应关系: -- 与 MySQL 版本的对应关系:
-- AUTO_INCREMENT -> GENERATED BY DEFAULT AS IDENTITY -- AUTO_INCREMENT -> 无(主键由应用侧雪花算法生成:MyBatis-Plus IdType.ASSIGN_ID)
-- TINYINT -> SMALLINT -- TINYINT -> SMALLINT
-- DATETIME(3) -> TIMESTAMP(3) -- DATETIME(3) -> TIMESTAMP(3)
-- ON UPDATE CURRENT_TIMESTAMP -> set_updated_at() 触发器 -- ON UPDATE CURRENT_TIMESTAMP -> set_updated_at() 触发器
@@ -11,7 +11,7 @@
-- ========== 系统域 ========== -- ========== 系统域 ==========
CREATE TABLE IF NOT EXISTS sys_admin_user ( CREATE TABLE IF NOT EXISTS sys_admin_user (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, id BIGINT PRIMARY KEY,
username VARCHAR(64) NOT NULL, -- 登录名 username VARCHAR(64) NOT NULL, -- 登录名
password VARCHAR(100) NOT NULL, -- BCrypt 哈希 password VARCHAR(100) NOT NULL, -- BCrypt 哈希
real_name VARCHAR(64) NOT NULL DEFAULT '', real_name VARCHAR(64) NOT NULL DEFAULT '',
@@ -31,7 +31,7 @@ CREATE UNIQUE INDEX IF NOT EXISTS uk_sys_admin_user_username ON sys_admin_user (
COMMENT ON TABLE sys_admin_user IS '管理员'; COMMENT ON TABLE sys_admin_user IS '管理员';
CREATE TABLE IF NOT EXISTS sys_role_category ( CREATE TABLE IF NOT EXISTS sys_role_category (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, id BIGINT PRIMARY KEY,
name VARCHAR(64) NOT NULL, name VARCHAR(64) NOT NULL,
description VARCHAR(255) NOT NULL DEFAULT '', description VARCHAR(255) NOT NULL DEFAULT '',
sort INT NOT NULL DEFAULT 0, sort INT NOT NULL DEFAULT 0,
@@ -43,7 +43,7 @@ CREATE UNIQUE INDEX IF NOT EXISTS uk_sys_role_category_name ON sys_role_category
COMMENT ON TABLE sys_role_category IS '角色分类'; COMMENT ON TABLE sys_role_category IS '角色分类';
CREATE TABLE IF NOT EXISTS sys_role ( CREATE TABLE IF NOT EXISTS sys_role (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, id BIGINT PRIMARY KEY,
name VARCHAR(64) NOT NULL, name VARCHAR(64) NOT NULL,
code VARCHAR(64) NOT NULL, -- 如 super_admin code VARCHAR(64) NOT NULL, -- 如 super_admin
category_id BIGINT NOT NULL DEFAULT 0, category_id BIGINT NOT NULL DEFAULT 0,
@@ -59,7 +59,7 @@ CREATE UNIQUE INDEX IF NOT EXISTS uk_sys_role_code ON sys_role (code);
COMMENT ON TABLE sys_role IS '角色'; COMMENT ON TABLE sys_role IS '角色';
CREATE TABLE IF NOT EXISTS sys_admin_user_role ( CREATE TABLE IF NOT EXISTS sys_admin_user_role (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, id BIGINT PRIMARY KEY,
user_id BIGINT NOT NULL, user_id BIGINT NOT NULL,
role_id BIGINT NOT NULL role_id BIGINT NOT NULL
); );
@@ -68,7 +68,7 @@ CREATE INDEX IF NOT EXISTS idx_sys_admin_user_role_role ON sys_admin_user_role (
COMMENT ON TABLE sys_admin_user_role IS '管理员-角色'; COMMENT ON TABLE sys_admin_user_role IS '管理员-角色';
CREATE TABLE IF NOT EXISTS sys_permission ( CREATE TABLE IF NOT EXISTS sys_permission (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, id BIGINT PRIMARY KEY,
code VARCHAR(128) NOT NULL, -- 如 drama:create code VARCHAR(128) NOT NULL, -- 如 drama:create
name VARCHAR(64) NOT NULL, name VARCHAR(64) NOT NULL,
group_name VARCHAR(64) NOT NULL DEFAULT '', group_name VARCHAR(64) NOT NULL DEFAULT '',
@@ -79,7 +79,7 @@ CREATE UNIQUE INDEX IF NOT EXISTS uk_sys_permission_code ON sys_permission (code
COMMENT ON TABLE sys_permission IS '权限点'; COMMENT ON TABLE sys_permission IS '权限点';
CREATE TABLE IF NOT EXISTS sys_menu ( CREATE TABLE IF NOT EXISTS sys_menu (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, id BIGINT PRIMARY KEY,
parent_id BIGINT NOT NULL DEFAULT 0, parent_id BIGINT NOT NULL DEFAULT 0,
title VARCHAR(64) NOT NULL, title VARCHAR(64) NOT NULL,
route_path VARCHAR(128) NOT NULL DEFAULT '', route_path VARCHAR(128) NOT NULL DEFAULT '',
@@ -101,7 +101,7 @@ CREATE INDEX IF NOT EXISTS idx_sys_menu_parent ON sys_menu (parent_id);
COMMENT ON TABLE sys_menu IS '菜单'; COMMENT ON TABLE sys_menu IS '菜单';
CREATE TABLE IF NOT EXISTS sys_role_permission ( CREATE TABLE IF NOT EXISTS sys_role_permission (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, id BIGINT PRIMARY KEY,
role_id BIGINT NOT NULL, role_id BIGINT NOT NULL,
permission_id BIGINT NOT NULL permission_id BIGINT NOT NULL
); );
@@ -109,7 +109,7 @@ CREATE UNIQUE INDEX IF NOT EXISTS uk_sys_role_permission ON sys_role_permission
COMMENT ON TABLE sys_role_permission IS '角色-权限'; COMMENT ON TABLE sys_role_permission IS '角色-权限';
CREATE TABLE IF NOT EXISTS sys_role_menu ( CREATE TABLE IF NOT EXISTS sys_role_menu (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, id BIGINT PRIMARY KEY,
role_id BIGINT NOT NULL, role_id BIGINT NOT NULL,
menu_id BIGINT NOT NULL menu_id BIGINT NOT NULL
); );
@@ -117,7 +117,7 @@ CREATE UNIQUE INDEX IF NOT EXISTS uk_sys_role_menu ON sys_role_menu (role_id, me
COMMENT ON TABLE sys_role_menu IS '角色-菜单'; COMMENT ON TABLE sys_role_menu IS '角色-菜单';
CREATE TABLE IF NOT EXISTS sys_config ( CREATE TABLE IF NOT EXISTS sys_config (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, id BIGINT PRIMARY KEY,
config_key VARCHAR(128) NOT NULL, config_key VARCHAR(128) NOT NULL,
config_value VARCHAR(1024) NOT NULL DEFAULT '', config_value VARCHAR(1024) NOT NULL DEFAULT '',
remark VARCHAR(255) NOT NULL DEFAULT '' remark VARCHAR(255) NOT NULL DEFAULT ''
@@ -126,7 +126,7 @@ CREATE UNIQUE INDEX IF NOT EXISTS uk_sys_config_key ON sys_config (config_key);
COMMENT ON TABLE sys_config IS '系统配置'; COMMENT ON TABLE sys_config IS '系统配置';
CREATE TABLE IF NOT EXISTS sys_operation_log ( CREATE TABLE IF NOT EXISTS sys_operation_log (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, id BIGINT PRIMARY KEY,
admin_user_id BIGINT NOT NULL DEFAULT 0, admin_user_id BIGINT NOT NULL DEFAULT 0,
username VARCHAR(64) NOT NULL DEFAULT '', username VARCHAR(64) NOT NULL DEFAULT '',
module VARCHAR(64) NOT NULL DEFAULT '', module VARCHAR(64) NOT NULL DEFAULT '',
@@ -148,7 +148,7 @@ COMMENT ON TABLE sys_operation_log IS '操作日志';
-- ========== 内容域 ========== -- ========== 内容域 ==========
CREATE TABLE IF NOT EXISTS drama_category ( CREATE TABLE IF NOT EXISTS drama_category (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, id BIGINT PRIMARY KEY,
name VARCHAR(64) NOT NULL, name VARCHAR(64) NOT NULL,
sort INT NOT NULL DEFAULT 0, sort INT NOT NULL DEFAULT 0,
status SMALLINT NOT NULL DEFAULT 1 status SMALLINT NOT NULL DEFAULT 1
@@ -157,7 +157,7 @@ CREATE UNIQUE INDEX IF NOT EXISTS uk_drama_category_name ON drama_category (name
COMMENT ON TABLE drama_category IS '短剧类型'; COMMENT ON TABLE drama_category IS '短剧类型';
CREATE TABLE IF NOT EXISTS drama ( CREATE TABLE IF NOT EXISTS drama (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, id BIGINT PRIMARY KEY,
code VARCHAR(64) NOT NULL DEFAULT '', code VARCHAR(64) NOT NULL DEFAULT '',
title VARCHAR(128) NOT NULL, title VARCHAR(128) NOT NULL,
subtitle VARCHAR(128) NOT NULL DEFAULT '', subtitle VARCHAR(128) NOT NULL DEFAULT '',
@@ -194,7 +194,7 @@ CREATE INDEX IF NOT EXISTS idx_drama_status_category ON drama (status, category_
COMMENT ON TABLE drama IS '短剧'; COMMENT ON TABLE drama IS '短剧';
CREATE TABLE IF NOT EXISTS drama_episode ( CREATE TABLE IF NOT EXISTS drama_episode (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, id BIGINT PRIMARY KEY,
drama_id BIGINT NOT NULL, drama_id BIGINT NOT NULL,
ep_no INT NOT NULL, ep_no INT NOT NULL,
title VARCHAR(128) NOT NULL DEFAULT '', title VARCHAR(128) NOT NULL DEFAULT '',
@@ -217,7 +217,7 @@ CREATE INDEX IF NOT EXISTS idx_drama_episode_status ON drama_episode (drama_id,
COMMENT ON TABLE drama_episode IS '剧集'; COMMENT ON TABLE drama_episode IS '剧集';
CREATE TABLE IF NOT EXISTS drama_review_record ( CREATE TABLE IF NOT EXISTS drama_review_record (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, id BIGINT PRIMARY KEY,
biz_type VARCHAR(16) NOT NULL, -- DRAMA/EPISODE biz_type VARCHAR(16) NOT NULL, -- DRAMA/EPISODE
biz_id BIGINT NOT NULL, biz_id BIGINT NOT NULL,
action VARCHAR(16) NOT NULL, -- SUBMIT/APPROVE/REJECT/PUBLISH/OFFLINE action VARCHAR(16) NOT NULL, -- SUBMIT/APPROVE/REJECT/PUBLISH/OFFLINE
@@ -230,7 +230,7 @@ CREATE INDEX IF NOT EXISTS idx_drama_review_biz ON drama_review_record (biz_type
COMMENT ON TABLE drama_review_record IS '审核记录'; COMMENT ON TABLE drama_review_record IS '审核记录';
CREATE TABLE IF NOT EXISTS content_banner ( CREATE TABLE IF NOT EXISTS content_banner (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, id BIGINT PRIMARY KEY,
image_url VARCHAR(512) NOT NULL DEFAULT '', image_url VARCHAR(512) NOT NULL DEFAULT '',
slot VARCHAR(32) NOT NULL DEFAULT 'HOME_TOP', -- 展示位置:HOME_TOP/DISCOVER slot VARCHAR(32) NOT NULL DEFAULT 'HOME_TOP', -- 展示位置:HOME_TOP/DISCOVER
link_type VARCHAR(16) NOT NULL DEFAULT 'NONE', -- NONE/DRAMA/URL link_type VARCHAR(16) NOT NULL DEFAULT 'NONE', -- NONE/DRAMA/URL
@@ -249,7 +249,7 @@ COMMENT ON TABLE content_banner IS '轮播图';
-- 本地存储版本:文件落在 fruitshorts.media.root-dir 下,通过 /files/** 访问 -- 本地存储版本:文件落在 fruitshorts.media.root-dir 下,通过 /files/** 访问
CREATE TABLE IF NOT EXISTS media_asset ( CREATE TABLE IF NOT EXISTS media_asset (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, id BIGINT PRIMARY KEY,
biz_type VARCHAR(32) NOT NULL DEFAULT 'EPISODE', biz_type VARCHAR(32) NOT NULL DEFAULT 'EPISODE',
file_name VARCHAR(255) NOT NULL DEFAULT '', file_name VARCHAR(255) NOT NULL DEFAULT '',
object_key VARCHAR(512) NOT NULL DEFAULT '', object_key VARCHAR(512) NOT NULL DEFAULT '',
@@ -274,7 +274,7 @@ CREATE INDEX IF NOT EXISTS idx_media_asset_biz_type ON media_asset (biz_type);
COMMENT ON TABLE media_asset IS '媒资'; COMMENT ON TABLE media_asset IS '媒资';
CREATE TABLE IF NOT EXISTS media_upload_task ( CREATE TABLE IF NOT EXISTS media_upload_task (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, id BIGINT PRIMARY KEY,
upload_id VARCHAR(64) NOT NULL, upload_id VARCHAR(64) NOT NULL,
biz_type VARCHAR(32) NOT NULL DEFAULT 'EPISODE', biz_type VARCHAR(32) NOT NULL DEFAULT 'EPISODE',
file_name VARCHAR(255) NOT NULL DEFAULT '', file_name VARCHAR(255) NOT NULL DEFAULT '',