Files
flower-rain/docs/hr/hr.md
2025-11-23 15:21:45 +08:00

144 lines
6.7 KiB
Markdown
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.
# 【实战分析】从界面反推数据库设计:以金华人才网站为例
## 前言
最近在学习系统架构与数据库设计,为了检验学习成果,我选取了 **金华人才网 (jhrcsc.com)** 及其关联的 **大学生欢迎中心** 网站作为案例。通过浏览其核心业务界面(找工作、找人才、企业招聘、资讯公告等),我尝试反推了其后端数据库的表结构设计,并总结了关键的业务实现逻辑与潜在的优化方案。
以下是我的分析总结记录。
---
## 一、 核心数据库架构设计
一个成熟的招聘系统通常由 **用户权限**、**企业/职位**、**简历中心**、**内容管理(CMS)** 四大模块构成。
### 1. 用户与权限模块 (User & Auth)
这是系统的入口最大的难点在于如何处理“个人求职者”与“企业HR”的身份区分。
* **表名:`sys_user` (用户主表)**
* `uid` (PK): 用户唯一标识。
* `username` / `mobile`: 登录账号/手机号。
* `password`: 加密后的密码 (推荐 Bcrypt)。
* `user_type`: 用户类型 (1=个人, 2=企业)。
* `last_login_time`: 最后登录时间(用于判断活跃度)。
* **设计思考**:为了扩展性,建议配合 RBAC 模型,增加 `sys_role``sys_user_role` 表,允许一个账号切换不同身份。
### 2. 企业与职位模块 (Enterprise & Jobs)
对应网站的“找企业”和“找工作”界面。
* **表名:`company_profile` (企业信息表)**
* `id` (PK): 企业ID。
* `uid`: 关联的用户ID。
* `company_name`: 企业全称。
* `logo_url`: Logo图片存储路径 (建议存相对路径或CDN地址)。
* `industry_id`: 行业字典ID (如:交通/物流)。
* `nature_id`: 性质字典ID (如:国企、民营)。
* `scale_id`: 规模字典ID (如20-99人)。
* `is_famous`: 是否名企 (用于首页推荐排序)。
* **表名:`company_jobs` (职位发布表)**
* `id` (PK): 职位ID。
* `company_id`: 关联企业ID。
* `job_name`: 职位名称 (如:市场营销)。
* `salary_min` / `salary_max`: 薪资范围 (存储数值,单位元)。
* `is_negotiable`: 是否面议 (Boolean)。
* `edu_req` / `exp_req`: 学历与经验要求的字典ID。
* `city_id` / `district_id`: 工作地区ID。
* `refresh_time`: 刷新时间 (决定列表页排序权重)。
* `status`: 状态 (1=招聘中, 0=已下架)。
### 3. 简历中心模块 (Resume)
对应网站的“找人才”界面,核心在于隐私保护与多维度展示。
* **表名:`resume_base` (简历基本信息)**
* `id` (PK): 简历ID。
* `uid`: 关联求职者ID。
* `realname`: 真实姓名。
* `gender`: 性别。
* `birth_year`: 出生年份 (界面显示年龄通常由年份动态计算)。
* `privacy_level`: 隐私设置 (完全公开/仅投递可见/保密)。
* **表名:`resume_edu` / `resume_work` (经历附表)**
* 设计为 **一对多** 关系。
* `resume_id`: 外键。
* `school_name` / `company_name`: 学校或公司名。
* `start_time` / `end_time`: 起止时间。
* `description`: 经历描述。
### 4. 运营与内容模块 (Operation & CMS)
对应“看资讯”、“招聘会”界面。
* **表名:`cms_article` (资讯文章)**
* `title`: 标题。
* `cat_id`: 分类ID (政策、公告、指导)。
* `content`: 富文本内容 (HTML)。
* `publish_time`: 发布时间。
* **表名:`job_fair` (招聘会)**
* `title`: 招聘会主题。
* `start_time` / `end_time`: 举办时间范围。
* `poster_url`: 海报图片。
* `address`: 举办地点。
* **表名:`sys_dict` (通用数据字典)**
* **作用**:这是系统中最重要的辅助表,用于存储“行业”、“学历”、“薪资范围”等下拉选项,减少数据冗余。
* 字段:`dict_code` (如 edu_level), `dict_value` (1), `dict_label` (本科)。
---
## 二、 关键业务逻辑实现
在分析界面交互时,我总结了以下几个有趣的逻辑实现方式:
### 1. 简历隐私脱敏 (Masking)
在“找人才”列表页,求职者姓名显示为“季**”。
* **实现逻辑**:前端不应接收完整姓名。后端 API 在输出 JSON 前进行处理:
```php
// 伪代码示例
if (!$user->is_paid_enterprise) {
$resume['name'] = mb_substr($resume['realname'], 0, 1) . "**";
$resume['mobile'] = "******";
}
```
### 2. 招聘会状态判断
界面显示“进行中”或“已结束”。
* **实现逻辑**:通常不在数据库存状态字段,而是运行时计算:
* `Now < start_time` -> **未开始**
* `Now > end_time` -> **已结束**
* `Otherwise` -> **进行中**
### 3. 薪资的存储与展示
界面显示“6.7-12k/月”或“面议”。
* **实现逻辑**
* **存储**:数据库存精确数值 `salary_min=6700`, `salary_max=12000`。
* **展示**:若 `is_negotiable=1` 则直接显示“面议”否则除以1000拼接字符串。这种方式既支持范围搜索WHERE salary > 5000又支持前端灵活展示。
### 4. 登录分流
如何实现个人和企业在同一个入口登录?
* **方案**:后端接口统一,通过前端 Tab 页传参(`type=person` 或 `type=company`)。登录成功后,根据数据库 `user_type` 字段,后端返回不同的重定向 URL`/person/dashboard` 或 `/company/dashboard`)。
---
## 三、 思考:现有架构的潜在优化点
作为学习者,如果让我来重构这个系统,我会考虑以下技术升级:
1. **搜索性能优化 (Elasticsearch)**
* 目前的 SQL `LIKE '%关键词%'` 查询在数据量大时效率极低。
* **改进**:引入 Elasticsearch将职位和简历数据同步索引实现毫秒级全文检索、拼写纠错和高亮显示。
2. **图片存储 (OSS + CDN)**
* 网站包含大量 Logo 和海报。
* **改进**:不应将图片二进制存入数据库或仅存本地服务器路径。应上传至阿里云 OSS / 七牛云,数据库只存 URL配合 CDN 加速加载。
3. **安全性加强**
* 招聘网站数据价值高,极易被爬虫抓取。
* **改进**:接口增加 **Rate Limiting (频率限制)**;简历联系方式查看需增加 **积分扣除** 逻辑;关键接口增加 **Signature 签名校验**。
## 总结
通过对 `jhrcsc.com` 的逆向分析,我深刻体会到:**界面是数据的投影**。看似简单的网页,背后需要严密的数据库范式设计和复杂的业务逻辑支撑。这次分析不仅帮我复习了 SQL 表设计,也让我对业务系统的全链路交互有了更清晰的认识。