插件窝 干货文章 删除题目后,如何保证自动抽题系统中题目数量和数据库 ID 一致?

删除题目后,如何保证自动抽题系统中题目数量和数据库 ID 一致?

questions 删除 方案 题目 352    来源:    2025-04-01

自动抽题系统中题目删除后的ID管理方案

当在自动抽题系统中删除题目后,要保证题目数量和数据库ID的一致性,有以下几种解决方案:

方案一:逻辑删除而非物理删除

推荐方案

ALTER TABLE questions ADD COLUMN is_deleted TINYINT DEFAULT 0;

优点: - 保留原始ID不变 - 可恢复已删除题目 - 不影响现有关联数据 - 查询时只需添加 WHERE is_deleted=0 条件

方案二:使用UUID替代自增ID

ALTER TABLE questions MODIFY COLUMN id CHAR(36) NOT NULL DEFAULT UUID();

优点: - 完全解耦ID与数量关系 - 分布式系统友好 - 删除不影响其他记录

方案三:重建ID序列(适用于小规模数据)

-- 创建临时表备份数据
CREATE TABLE questions_temp AS SELECT * FROM questions WHERE deleted=0 ORDER BY id;

-- 清空原表并重置自增计数器
TRUNCATE TABLE questions;

-- 恢复数据
INSERT INTO questions SELECT * FROM questions_temp;

-- 删除临时表
DROP TABLE questions_temp;

方案四:使用外部计数服务

架构设计: 1. 维护一个独立的计数服务 2. 每次操作更新计数 3. 通过API获取当前有效题目数

最佳实践建议

  1. 优先采用逻辑删除,这是最稳定可靠的方案
  2. 如果必须物理删除,考虑定期执行ID重整脚本(非高峰期)
  3. 前端显示时使用序号而非数据库ID
  4. 对于抽题逻辑,使用WHERE is_deleted=0 LIMIT n而非依赖ID范围

代码示例(逻辑删除实现)

# 删除题目(逻辑删除)
def delete_question(question_id):
    db.execute("UPDATE questions SET is_deleted=1 WHERE id=?", (question_id,))

# 获取有效题目数量
def get_active_question_count():
    return db.query("SELECT COUNT(*) FROM questions WHERE is_deleted=0")[0][0]

# 随机抽题
def get_random_questions(n):
    return db.query("SELECT * FROM questions WHERE is_deleted=0 ORDER BY RAND() LIMIT ?", (n,))

选择哪种方案取决于您的具体业务需求、数据规模和技术架构。