职位表怎么建才支持快速筛选和状态更新
招聘系统最常查的是「哪些职位在招」「某类职位最近更新时间」,所以
position表必须带状态字段和时间戳。别只用
status VARCHAR(20),用
TINYINT存状态码(比如 1=开放、2=暂停、3=已关闭),查询快、索引小、还能加
CHECK约束防脏数据。
实操建议:
id设为
INT UNSIGNED AUTO_INCREMENT PRIMARY KEY加
status TINYINT NOT NULL DEFAULT 1,配合注释说明各值含义 必加
created_at DATETIME DEFAULT CURRENT_TIMESTAMP和
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP对
status和
updated_at建联合索引:
INDEX idx_status_updated (status, updated_at),查「最近开放的 10 个职位」就不用全表扫
候选人简历存 MySQL 还是文件系统
小团队初期直接存在 MySQL 更省事,但得控制字段类型和大小。别用
TEXT存原始 PDF——MySQL 不会解析内容,搜索靠不住,还拖慢备份。
实操建议:
简历元信息(姓名、电话、投递职位 ID、来源渠道)存在candidate表,
resume_url VARCHAR(512)只存路径(如
/resumes/20240517_abc.pdf) PDF/Word 文件真身放本地目录或对象存储,MySQL 不碰二进制内容 如果硬要存二进制,用
MEDIUMBLOB+
charset binary,且单条别超 16MB(避免触发
max_allowed_packet限制) 加
is_parsed TINYINT DEFAULT 0字段,标记是否已用工具(如
pdftotext)抽过文本,方便后续做简单关键词匹配
面试安排怎么避免时间冲突和重复插入
interview表最容易出错:两个 HR 同时给同一候选人约同一时段,或者没校验面试官当天是否排满。MySQL 层面靠唯一约束 + 事务兜底最实在。
实操建议:
设复合唯一键:UNIQUE KEY uk_candidate_time (candidate_id, interview_time),防止一人同一时间多场面试 面试官日程检查不能只靠应用层查,要在插入前用
SELECT ... FOR UPDATE锁住该面试官当天的记录行(需事务包裹)
interview_time用
DATETIME而非
DATE,精确到分钟,避免「下午」这种模糊值导致冲突 加
status ENUM('scheduled','done','canceled') DEFAULT 'scheduled',避免用数字码,语义清晰且 MySQL 自动校验
为什么 JOIN 多张表查「职位+候选人+面试结果」总变慢
典型场景是看某个职位下所有候选人及最新面试结论,一写
JOIN position + candidate + interview就卡。问题不在 JOIN 本身,而在没拆解「最新面试」这个子查询逻辑。
实操建议:
别在主查询里用(SELECT ... ORDER BY time DESC LIMIT 1)做相关子查询,MySQL 5.7 以前几乎必然全表扫描 改用窗口函数(MySQL 8.0+):
ROW_NUMBER() OVER (PARTITION BY candidate_id ORDER BY interview_time DESC),再外层筛
rn = 1如果还在用 5.7,建物化视图思路:单独一张
latest_interview表,用定时任务或触发器维护,查的时候只 JOIN 这张轻量表 所有 JOIN 字段确保有索引,尤其是
candidate.position_id和
interview.candidate_id—— 缺一个就可能从
ref退化成
ALL实际跑起来你会发现,最难的不是建表,而是「谁来更新
updated_at」「面试取消后要不要删记录而不是改状态」「不同角色看到的职位列表权限怎么切」——这些没法靠 SQL 语法解决,得在应用代码里守住边界。
