职位表应设status TINYINT NOT NULL DEFAULT 1和created_at、updated_at时间戳,并建联合索引idx_status_updated;简历存URL而非二进制;面试表用唯一键+SELECT FOR UPDATE防冲突;查最新面试优先用窗口函数或物化视图。

职位表怎么建才支持快速筛选和状态更新
招聘系统最常查的是「哪些职位在招」「某类职位最近更新时间」,所以 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 层面靠唯一约束 + 事务兜底最实在。
SmartB2B 是一款基于PHP、MySQL、Smarty的B2B行业电子商务网站管理系统,系统提供了供求模型、企业模型、产品模型、人才招聘模型、资讯模型等模块,适用于想在行业里取得领先地位的企业快速假设B2B网站,可以运行于Linux与Windows等多重服务器环境,安装方便,使用灵活。 系统使用当前流行的PHP语言开发,以MySQL为数据库,采用B/S架构,MVC模式开发。融入了模型化、模板
实操建议:
- 设复合唯一键:
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 语法解决,得在应用代码里守住边界。









