员工考勤系统的核心是对员工出勤、请假、加班等数据进行持久化存储和高效查询,使用MySQL实现该系统的数据库部分,需要先梳理清楚业务涉及的核心实体和关联关系,再设计对应的表结构并编写相关SQL逻辑。

核心表结构设计
员工考勤系统至少需要包含员工基础信息表、考勤记录表、请假类型表、部门表这四个核心表,各表的字段设计如下:
1. 部门表 department
用于存储企业部门的基础信息,字段定义如下:
| 字段名 | 类型 | 说明 |
|---|---|---|
| dept_id | INT PRIMARY KEY AUTO_INCREMENT | 部门ID,自增主键 |
| dept_name | VARCHAR(50) NOT NULL | 部门名称,不可为空 |
| create_time | DATETIME DEFAULT CURRENT_TIMESTAMP | 部门创建时间 |
2. 员工信息表 employee
存储员工的基础信息,关联到部门表,字段定义如下:
| 字段名 | 类型 | 说明 |
|---|---|---|
| emp_id | INT PRIMARY KEY AUTO_INCREMENT | 员工ID,自增主键 |
| emp_name | VARCHAR(30) NOT NULL | 员工姓名 |
| dept_id | INT NOT NULL | 所属部门ID,外键关联department表 |
| position | VARCHAR(30) | 员工职位 |
| entry_time | DATE NOT NULL | 入职时间 |
| status | TINYINT DEFAULT 1 | 员工状态,1为在职,0为离职 |
3. 考勤记录表 attendance
存储员工每日的考勤打卡数据,字段定义如下:
| 字段名 | 类型 | 说明 |
|---|---|---|
| att_id | INT PRIMARY KEY AUTO_INCREMENT | 考勤记录ID,自增主键 |
| emp_id | INT NOT NULL | 员工ID,外键关联employee表 |
| clock_in_time | DATETIME | 上班打卡时间 |
| clock_out_time | DATETIME | 下班打卡时间 |
| att_date | DATE NOT NULL | 考勤日期 |
| att_status | VARCHAR(20) DEFAULT '正常' | 考勤状态,可选正常、迟到、早退、缺勤 |
4. 请假类型表 leave_type
存储请假的类型信息,字段定义如下:
| 字段名 | 类型 | 说明 |
|---|---|---|
| type_id | INT PRIMARY KEY AUTO_INCREMENT | 请假类型ID |
| type_name | VARCHAR(20) NOT NULL | 请假类型名称,如事假、病假、年假 |
| deduct_salary_ratio | DECIMAL(3,2) DEFAULT 1.00 | 扣薪比例,1表示全扣,0.5表示扣一半 |
表创建SQL语句
按照上述表结构,编写MySQL的建表语句如下:
-- 创建部门表
CREATE TABLE IF NOT EXISTS department (
dept_id INT PRIMARY KEY AUTO_INCREMENT,
dept_name VARCHAR(50) NOT NULL,
create_time DATETIME DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 创建员工信息表
CREATE TABLE IF NOT EXISTS employee (
emp_id INT PRIMARY KEY AUTO_INCREMENT,
emp_name VARCHAR(30) NOT NULL,
dept_id INT NOT NULL,
position VARCHAR(30),
entry_time DATE NOT NULL,
status TINYINT DEFAULT 1,
FOREIGN KEY (dept_id) REFERENCES department(dept_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 创建请假类型表
CREATE TABLE IF NOT EXISTS leave_type (
type_id INT PRIMARY KEY AUTO_INCREMENT,
type_name VARCHAR(20) NOT NULL,
deduct_salary_ratio DECIMAL(3,2) DEFAULT 1.00
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 创建考勤记录表
CREATE TABLE IF NOT EXISTS attendance (
att_id INT PRIMARY KEY AUTO_INCREMENT,
emp_id INT NOT NULL,
clock_in_time DATETIME,
clock_out_time DATETIME,
att_date DATE NOT NULL,
att_status VARCHAR(20) DEFAULT '正常',
FOREIGN KEY (emp_id) REFERENCES employee(emp_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
常用业务SQL示例
插入测试数据
先插入基础的部门和员工数据,方便后续测试考勤相关逻辑:
-- 插入部门数据
INSERT INTO department (dept_name) VALUES ('技术部'), ('人事部'), ('财务部');
-- 插入员工数据
INSERT INTO employee (emp_name, dept_id, position, entry_time) VALUES
('张三', 1, '后端开发', '2023-03-01'),
('李四', 1, '前端开发', '2023-04-15'),
('王五', 2, '人事专员', '2022-11-20');
记录员工打卡
员工上班和下班打卡时,分别更新考勤记录表,上班打卡时插入新记录,下班打卡时更新对应记录:
-- 上班打卡,插入考勤记录 INSERT INTO attendance (emp_id, clock_in_time, att_date) VALUES (1, NOW(), CURDATE()); -- 下班打卡,更新对应考勤记录的下班时间 UPDATE attendance SET clock_out_time = NOW() WHERE emp_id = 1 AND att_date = CURDATE();
统计月度考勤情况
统计某员工指定月份的考勤状态分布,比如统计张三2024年5月的考勤情况:
SELECT
att_status,
COUNT(*) AS status_count
FROM attendance
WHERE emp_id = 1
AND att_date BETWEEN '2024-05-01' AND '2024-05-31'
GROUP BY att_status;
关联查询员工考勤和部门信息
需要查询员工考勤数据时,通常会关联员工表和部门表获取更完整的信息:
SELECT
e.emp_name,
d.dept_name,
a.att_date,
a.clock_in_time,
a.clock_out_time,
a.att_status
FROM attendance a
JOIN employee e ON a.emp_id = e.emp_id
JOIN department d ON e.dept_id = d.dept_id
WHERE a.att_date = CURDATE();
注意事项
- 考勤记录表中可以给
emp_id和att_date添加联合唯一索引,避免同一员工同一天重复插入多条考勤记录。 - 考勤状态的计算逻辑可以在应用层实现,比如比对打卡时间和企业规定的上下班时间,判断是正常、迟到还是早退,再写入
att_status字段。 - 如果考勤数据量较大,可以对
att_date字段添加索引,提升按日期查询考勤数据的效率。