Files
ruoyi-vue-pro/sql/mysql/education/007-education-favorite.sql

78 lines
4.2 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.

-- =============================================
-- Education 模块 — 收藏夹 DDL
-- Ticket #10: 学生收藏题目
-- Migration: 007
-- Prerequisites: 000-education-schema.sql (base tables)
-- =============================================
-- =============================================
-- Preconditions
-- =============================================
-- Operator is expected to verify:
-- SELECT COUNT(*) FROM information_schema.tables
-- WHERE table_schema = DATABASE()
-- AND table_name = 'education_favorite';
-- Result MUST be 0 before executing this migration.
-- =============================================
-- 收藏表
-- =============================================
-- Purpose: Student favorites for questions with safe snapshots.
-- Each (tenant, user, target_type, target_id) is a unique entry.
-- Logical deletion: setting deleted=1 marks as unfavorited.
-- Re-adding after deletion reactivates the row via ON DUPLICATE KEY UPDATE.
--
-- target_type values: 'QUESTION' (extensible enum)
--
-- Snapshot fields (stem, type, difficulty, options, content_version):
-- populated at creation time from the visible question's safe fields.
-- These snapshots preserve the question state as it appeared when favorited,
-- and remain stable even if the source question later changes or becomes unavailable.
--
-- available flag:
-- FALSE when the source question becomes hidden/unpublished after being
-- favorited. Existing favorites with available=FALSE remain listable but
-- display an "unavailable" indicator. New favorites cannot be created for
-- unavailable resources.
--
-- Indexes:
-- uk_tenant_user_target — per (tenant, user, target_type, target_id) uniqueness.
-- INSERT ... ON DUPLICATE KEY UPDATE is the primary reactivation path.
-- idx_tenant_user — covers listing queries filtered by current tenant+user.
-- idx_tenant_user_target_type — covers target-type-filtered listing.
CREATE TABLE `education_favorite` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键',
`tenant_id` BIGINT NOT NULL COMMENT '租户编号',
`user_id` BIGINT NOT NULL COMMENT '学生用户编号',
`target_type` VARCHAR(32) NOT NULL COMMENT '目标类型QUESTION',
`target_id` VARCHAR(64) NOT NULL COMMENT '目标 ID题目 ID',
-- safe snapshot fields
`stem` TEXT DEFAULT NULL COMMENT '题干快照',
`type` VARCHAR(32) DEFAULT NULL COMMENT '题型快照',
`difficulty` VARCHAR(32) DEFAULT NULL COMMENT '难度快照',
`options` JSON DEFAULT NULL COMMENT '选项快照 JSON不含 isCorrect',
`content_version` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '题目内容版本',
-- availability
`available` BIT(1) NOT NULL DEFAULT b'1' COMMENT '源资源是否可用',
-- audit
`creator` VARCHAR(64) DEFAULT '' COMMENT '创建者',
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updater` VARCHAR(64) DEFAULT '' COMMENT '更新者',
`update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` BIT(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_tenant_user_target` (`tenant_id`, `user_id`, `target_type`, `target_id`),
KEY `idx_tenant_user` (`tenant_id`, `user_id`),
KEY `idx_tenant_user_target_type` (`tenant_id`, `user_id`, `target_type`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='教育-收藏夹';
-- =============================================
-- Post-migration verification queries
-- =============================================
-- Verify new table exists:
-- SHOW CREATE TABLE education_favorite;
-- Verify unique key is enforced:
-- SHOW INDEX FROM education_favorite WHERE Key_name = 'uk_tenant_user_target';
-- Verify no orphan data (should be 0 after fresh migration):
-- SELECT COUNT(*) FROM education_favorite;