Wan2.2-T2V-A5B数据库集成实践MySQL存储用户视频生成历史与偏好最近在折腾一个多用户的视频生成平台核心需求很简单用户来了输入一段文字描述后台调用Wan2.2-T2V-A5B模型生成视频然后把结果返回给用户。听起来流程清晰对吧但真做起来问题就来了。用户A生成了10个视频下次登录怎么快速找到历史记录用户B喜欢科幻风格怎么让系统记住他的偏好下次生成时自动推荐相关参数后台同时有几百个生成任务在排队怎么确保每个任务的状态排队中、生成中、已完成、失败准确无误不会出现数据错乱所有这些问题的答案都指向一个核心组件数据库。我们选择了MySQL因为它成熟、稳定、生态丰富特别适合处理这类结构化的关系型数据。今天我就来聊聊我们是怎么用MySQL来设计这套数据管理系统的把那些看似复杂的“状态”、“偏好”、“历史”都安排得明明白白。1. 核心数据表设计为视频生成业务量身定制设计数据库第一步永远是搞清楚要存什么。对于视频生成平台数据可以归纳为四类核心实体用户、生成任务、生成的视频、用户偏好。围绕这四类实体我们设计了四张主表。1.1 用户表平台的基石用户表 (users) 是所有业务数据的起点。它的设计相对标准但有几个字段是为视频生成场景特别考虑的。CREATE TABLE users ( id bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 用户唯一ID, username varchar(50) NOT NULL COMMENT 用户名用于登录和显示, email varchar(100) DEFAULT NULL COMMENT 邮箱用于通知和找回密码, avatar_url varchar(255) DEFAULT NULL COMMENT 用户头像地址, total_credits int(11) NOT NULL DEFAULT 100 COMMENT 总积分/点数用于控制生成次数, used_credits int(11) NOT NULL DEFAULT 0 COMMENT 已使用的积分, preferred_style varchar(50) DEFAULT NULL COMMENT 偏好的视频风格如“科幻”、“动漫”、“写实”, default_video_length smallint(6) DEFAULT 5 COMMENT 默认视频时长秒用户可设置, created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 注册时间, updated_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 最后更新时间, PRIMARY KEY (id), UNIQUE KEY uk_username (username), UNIQUE KEY uk_email (email), KEY idx_created_at (created_at) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT用户基本信息表;这里有几个设计点值得一说total_credits和used_credits这是典型的“点数”消耗模式。每次生成视频会扣除积分方便进行资源控制和商业化。preferred_style和default_video_length这两个字段直接记录了用户的生成偏好。虽然简单但为后续的个性化推荐提供了基础。比如当用户新建任务时前端可以默认填充他喜欢的风格和时长。utf8mb4字符集确保能存储Emoji等特殊字符因为用户的提示词里很可能包含这些。1.2 任务队列表管理并发的核心视频生成是个耗时任务不可能让用户同步等待。因此我们需要一个任务队列来异步处理。task_queue表就是整个系统的“交通指挥中心”。CREATE TABLE task_queue ( task_id varchar(32) NOT NULL COMMENT 任务唯一IDUUID或雪花算法生成, user_id bigint(20) unsigned NOT NULL COMMENT 发起任务的用户ID, prompt_text text NOT NULL COMMENT 用户输入的文本提示词, negative_prompt text DEFAULT NULL COMMENT 负面提示词不希望视频中出现的内容, style_preset varchar(50) DEFAULT NULL COMMENT 风格预设如“cinematic”, “anime”, video_length smallint(6) NOT NULL DEFAULT 5 COMMENT 期望的视频时长秒, resolution varchar(20) DEFAULT 720p COMMENT 视频分辨率如720p, 1080p, status enum(PENDING,PROCESSING,SUCCESS,FAILED,CANCELLED) NOT NULL DEFAULT PENDING COMMENT 任务状态, progress tinyint(4) DEFAULT 0 COMMENT 生成进度0-100, error_message text DEFAULT NULL COMMENT 如果失败记录错误信息, estimated_finish_time timestamp NULL DEFAULT NULL COMMENT 预计完成时间, created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 任务创建时间, updated_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 状态最后更新时间, PRIMARY KEY (task_id), KEY idx_user_id_status (user_id,status), KEY idx_status_created (status,created_at), KEY idx_user_created (user_id,created_at) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT视频生成任务队列表;这张表的设计精髓在于status字段和一系列索引状态流转PENDING(排队中) -PROCESSING(生成中) -SUCCESS/FAILED/CANCELLED。清晰的状态机是保证业务逻辑正确的关键。复合索引idx_user_id_status: 这是最高频的查询场景——“查询某个用户所有未完成或已完成的任务”。这个索引能极大提升查询速度。idx_status_created: 后台调度程序需要不断捞取PENDING状态的任务按创建时间排序保证先来先服务。idx_user_created: 用于用户个人中心按时间倒序展示所有历史任务。1.3 视频元数据表记录每一次创作任务执行成功后就会产生视频文件。video_metadata表用于存储视频的元信息它与task_queue是一对一的关系。CREATE TABLE video_metadata ( video_id varchar(32) NOT NULL COMMENT 视频唯一ID可与task_id相同或关联, task_id varchar(32) NOT NULL COMMENT 关联的任务ID, user_id bigint(20) unsigned NOT NULL COMMENT 视频所有者, title varchar(200) DEFAULT NULL COMMENT 用户为视频设置的标题, description text DEFAULT NULL COMMENT 视频描述, file_url varchar(500) NOT NULL COMMENT 视频文件存储地址OSS/对象存储URL, thumbnail_url varchar(500) DEFAULT NULL COMMENT 视频封面图地址, duration smallint(6) DEFAULT NULL COMMENT 视频实际时长秒, file_size bigint(20) DEFAULT NULL COMMENT 视频文件大小字节, model_version varchar(20) DEFAULT Wan2.2-T2V-A5B COMMENT 生成使用的模型版本, generation_params json DEFAULT NULL COMMENT 完整的生成参数JSON格式用于追溯和复现, is_public tinyint(1) NOT NULL DEFAULT 0 COMMENT 是否公开0-私有1-公开, like_count int(11) NOT NULL DEFAULT 0 COMMENT 点赞数, view_count int(11) NOT NULL DEFAULT 0 COMMENT 播放/查看次数, created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 生成时间, PRIMARY KEY (video_id), UNIQUE KEY uk_task_id (task_id), KEY idx_user_id_created (user_id,created_at), KEY idx_public_created (is_public,created_at), KEY idx_like_count (like_count), FULLTEXT KEY ft_title_desc (title,description) -- 全文索引用于搜索 ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT视频元数据表;这张表的亮点在于generation_params(JSON类型)我们将所有生成参数提示词、负面提示、强度、步数等以JSON格式完整保存。这有两个巨大好处一是可以精确复现某个视频二是未来做数据分析比如哪种参数组合更受欢迎时数据都在手边。is_public字段区分私有和公开作品为社区功能如作品广场打下基础。全文索引ft_title_desc当用户想在自己的历史记录中搜索某个视频时这个索引能快速定位。1.4 用户偏好模型表让AI更懂你为了让系统更智能我们希望能学习用户的偏好。user_preference_model表用于存储通过用户行为生成、点赞、收藏分析出的偏好模型数据。CREATE TABLE user_preference_model ( user_id bigint(20) unsigned NOT NULL COMMENT 用户ID, preference_type varchar(30) NOT NULL COMMENT 偏好类型如“style”, “topic”, “color”, preference_value varchar(100) NOT NULL COMMENT 偏好值如“sci-fi”, “landscape”, “vibrant”, weight float NOT NULL DEFAULT 1.0 COMMENT 偏好权重越高表示用户越喜欢, last_interacted timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 最后一次与该偏好交互的时间, PRIMARY KEY (user_id, preference_type, preference_value), KEY idx_user_weight (user_id,weight DESC) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT用户偏好模型表简易版;这是一个简化版的偏好模型。它的工作原理是用户每次成功生成一个“科幻”风格的视频系统就为(user_id, ‘style’, ‘sci-fi’)这条记录的weight增加一点。用户点赞或收藏了别人的“风景”主题视频(user_id, ‘topic’, ‘landscape’)的权重也会增加。当用户新建任务时系统可以查询此表按权重排序将他最偏好的风格和主题作为默认推荐。这种设计将复杂的机器学习偏好结果用一张简单的关系表表达出来易于理解和更新。2. 性能优化让查询飞起来的索引策略表结构设计好了但如果数据量上来比如百万级任务记录查询变慢怎么办关键在于合理的索引。2.1 高频查询场景与索引匹配我们的索引都是为实际查询服务的。回顾一下业务中最常见的操作用户查看自己的任务列表SELECT * FROM task_queue WHERE user_id ? ORDER BY created_at DESC LIMIT 20;最优索引idx_user_created (user_id, created_at)。这个索引能直接覆盖WHERE和ORDER BY效率最高。后台调度器获取待处理任务SELECT * FROM task_queue WHERE status ‘PENDING’ ORDER BY created_at ASC LIMIT 10 FOR UPDATE;最优索引idx_status_created (status, created_at)。同样覆盖了查询和排序条件。FOR UPDATE是为了锁定任务防止被多个调度器重复处理。在个人主页搜索历史视频SELECT * FROM video_metadata WHERE user_id ? AND (title LIKE ‘%关键词%’ OR description LIKE ‘%关键词%’);前缀匹配idx_user_id_created能快速定位到该用户的视频。模糊搜索对于LIKE ‘%关键词%’这种前后模糊匹配B-Tree索引无效。这时我们建的全文索引ft_title_desc就派上用场了查询可以改为使用MATCH(title, description) AGAINST(‘关键词’)速度更快。2.2 索引使用建议与避坑指南遵循最左前缀原则INDEX(a, b, c)能加速WHERE a?、WHERE a? AND b?、WHERE a? AND b? AND c?的查询但无法加速WHERE b?或WHERE c?的查询。我们的复合索引设计都遵循了这一原则。避免过度索引索引不是越多越好。每个索引都会增加写操作INSERT/UPDATE/DELETE的开销因为数据变更时需要同步更新索引。我们只为高频查询和排序字段建立索引。定期分析慢查询使用EXPLAIN命令分析慢查询SQL的执行计划是优化索引的黄金手段。3. 数据一致性保障事务与状态管理在多用户并发生成视频的场景下保证数据一致性至关重要。核心问题集中在两点积分扣除和任务状态更新。想象一个场景用户点击生成系统需要做两件事1. 从用户账户扣积分2. 在任务队列创建一条PENDING记录。如果第一步成功第二步因为网络问题失败了用户积分就白白损失了这绝对不行。3.1 使用数据库事务我们必须把这两个操作放在一个数据库事务里保证它们要么都成功要么都失败。import pymysql from contextlib import contextmanager contextmanager def get_db_connection(): # 获取数据库连接 conn pymysql.connect(hostlocalhost, useruser, passwordpass, databaseai_video_db) try: yield conn finally: conn.close() def create_video_generation_task(user_id, prompt, style, credits_needed): with get_db_connection() as conn: cursor conn.cursor() try: # 1. 开启事务 conn.begin() # 2. 扣除用户积分检查积分是否充足 update_credit_sql UPDATE users SET used_credits used_credits %s WHERE id %s AND (total_credits - used_credits) %s rows_affected cursor.execute(update_credit_sql, (credits_needed, user_id, credits_needed)) if rows_affected 0: # 积分不足回滚事务并抛出异常 conn.rollback() raise Exception(用户积分不足) # 3. 创建生成任务记录 task_id generate_unique_id() insert_task_sql INSERT INTO task_queue (task_id, user_id, prompt_text, style_preset, status) VALUES (%s, %s, %s, %s, PENDING) cursor.execute(insert_task_sql, (task_id, user_id, prompt, style)) # 4. 提交事务 conn.commit() print(f任务 {task_id} 创建成功积分已扣除。) return task_id except Exception as e: # 任何一步出错都回滚事务 conn.rollback() print(f创建任务失败已回滚: {e}) raise e finally: cursor.close()这段代码展示了典型的事务用法。conn.begin()和conn.commit()之间的所有数据库操作是一个原子单位。如果中间任何一步出错conn.rollback()会撤销所有更改用户积分不会被错误扣除。3.2 任务状态机的并发控制另一个并发问题是任务状态更新。后台有多个工作进程Worker从task_queue中拉取PENDING任务。必须防止同一个任务被多个Worker同时处理。常见的解决方案是使用SELECT ... FOR UPDATE语句。这条语句会在查询时对符合条件的记录加上“排他锁”。-- Worker进程执行的SQL START TRANSACTION; -- 1. 锁定并获取一个待处理任务 SELECT * FROM task_queue WHERE status PENDING ORDER BY created_at ASC LIMIT 1 FOR UPDATE; -- 假设获取到的task_id是 task_123 -- 2. 立即更新该任务状态为“处理中”防止其他Worker再拿到它 UPDATE task_queue SET status PROCESSING, updated_at NOW() WHERE task_id task_123; COMMIT;在事务中FOR UPDATE锁会一直持有直到事务结束。这样第一个Worker执行SELECT ... FOR UPDATE后其他Worker再执行同样的语句就会被阻塞直到第一个Worker的事务提交更新了状态或回滚。这就实现了安全的并发任务派发。4. 总结回过头看用MySQL来管理视频生成平台的数据核心思路就是把复杂的业务逻辑拆解成几个清晰的数据实体然后用关系型数据库最擅长的方式——表和索引——把它们组织起来。用户表是起点任务队列表是中枢视频元数据表是成果库偏好表则是让系统变得更聪明的“记忆”。通过精心设计的复合索引我们能确保无论是用户查历史还是系统派任务速度都足够快。而事务和锁的运用则像交通规则一样保证了在高并发环境下数据不会“撞车”积分不会算错任务不会被重复执行。这套设计并不是一成不变的。随着业务增长你可能会考虑引入缓存如Redis来存储热点数据或者将task_queue表的功能用更专业的消息队列如RabbitMQ、Kafka来替代。但对于大多数从0到1或者处于快速发展初期的项目来说这样一个清晰、稳健的MySQL设计方案已经能很好地支撑起核心业务让开发者能把精力更多地集中在AI模型的效果优化和用户体验提升上。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。