我正在设计一个非常简单的考勤跟踪数据库,实际上这将是我的第一个数据库。大约有30名员工,每个人都有一个独特的身份。每隔几个月,有人会退出,会有一些新人。每天唯一需要记录的是他们的出勤状态:出勤,缺勤或休假。
我想只使用一张桌子,这些字段是员工' id和行表示天,值是0,1或2.我认为这几乎就是它。但有一件事让我感觉不舒服,就是当有人加入时,我将不得不为他添加一个新的领域。根据我过去的经验,表格的字段总是稳定的,只有记录被更改。这让我想知道我脑海中的设计是不是一个好主意,如果没有,那么这个设计有什么好处呢?
答案 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
上的手册页