设计考勤数据库:将员工用作领域是一种好习惯吗?

时间:2016-05-27 15:58:40

标签: mysql database database-design

我正在设计一个非常简单的考勤跟踪数据库,实际上这将是我的第一个数据库。大约有30名员工,每个人都有一个独特的身份。每隔几个月,有人会退出,会有一些新人。每天唯一需要记录的是他们的出勤状态:出勤,缺勤或休假。

我想只使用一张桌子,这些字段是员工' id和行表示天,值是0,1或2.我认为这几乎就是它。但有一件事让我感觉不舒服,就是当有人加入时,我将不得不为他添加一个新的领域。根据我过去的经验,表格的字段总是稳定的,只有记录被更改。这让我想知道我脑海中的设计是不是一个好主意,如果没有,那么这个设计有什么好处呢?

1 个答案:

答案 0 :(得分:2)

我建议启动以下架构。这些表当然只是存根。

create schema xyz837_testdb;    -- create a test db so as not to clutter yours
use xyz837_testdb;  -- use new db just created

-- drop table users;
create table users
(   userId int auto_increment primary key,
    userName varchar(100) not null,
    status char(1) not null, -- dream up some code / FK to a code table?
    endEmploymentDate date null -- date employment ended
);

-- drop table attendance;
create table attendance
(   id int auto_increment primary key,
    userId int not null,
    workDate date not null,
    dayWorkStatus char(1) not null, -- dream up some code / FK to a code table?
    hoursWorked decimal(4,2) not null, -- test this for overflows (errors). Seems fine
    unique index (userId,workDate),
    index (workDate), -- remember, left-most indexes are mostly of value
    FOREIGN KEY (userId) REFERENCES users(userId) -- referential integrity
);

测试它:

insert attendance(userId,workDate,dayWorkStatus,hoursWorked) values
(3,'2016-01-04','w',11.22) -- fails FK contraint. User 3 is not in system. Error 1452

-- Add users 1 to 4 relying on auto_increment for userId
insert users(userName,status,endEmploymentDate) values
('Guy who quit','I','2015-10-31'),
('John Henry','A',null),
('Sally Higgins','A',null),
('Kate Macintosh','A',null);

-- Insert some attendance rows
insert attendance(userid,workdate,dayWorkStatus,hoursWorked) values
(3,'2016-01-04','w',11.22), -- works fine now. Users exist
(2,'2016-01-05','w',8),  
(3,'2016-01-05','w',9/25);  

insert attendance(userid,workdate,dayWorkStatus,hoursWorked) values
(3,'2016-01-04','w',11.22) --  Error 1062: Duplicate entry. good error to have. It means you keep your data clean.

查询测试:

select u.userId,u.userName,ifnull(a.hoursWorked,0) as hoursWorked 
from users u 
left join attendance a 
on u.userId=a.userId   and a.workDate='2016-01-05' 
where u.status='A'; 

+--------+----------------+-------------+
| userId | userName       | hoursWorked |
+--------+----------------+-------------+
|      2 | John Henry     |        8.00 |
|      3 | Sally Higgins  |        9.25 |
|      4 | Kate Macintosh |        0.00 |
+--------+----------------+-------------+

查询测试会跳过非活动工作人员,并使用左连接,在attendance表中选择未报告(0小时工作)的活动工作人员。因此,对于未报告出席的情况,左连接返回null,转换为0。

清理测试:

drop schema xyz837_testdb;  -- drop db just created

使用Foreign Keys注意attendance表中的引用完整性。

此外,attendance表格具有唯一复合键。这样,用户/日期组合不会出现两次。因此重复组合将在插入时失败。而是使用update语句修改一列或两列。

关于用户插入,请参阅LAST_INSERT_ID

上的手册页