我正在为工资单应用程序开发一个数据库,我需要的一个功能是一个表,用于存储每个商店每周工作的员工列表。
每位员工都有一个ID,所以我的表格如下:
| Mon | Tue | Wed | Thu | Fri | Sat | Sun
Store 1 | 3,4,5 | 3,4,5 | 3,4,5 | 4,5,7 | 4,5,7 | 4,5,6,7 | 4,5,6,7
Store 2 | 1,8,9 | 1,8,9 | 1,8,9 | 1,8,9 | 1,8,9 | 1,8,9 | 1,8,9
Store 3 | 10,12 | 10,12 | 10,12 | 10,12 | 10,12 | 10,12 | 10,12
Store 4 | 15 | 15 | 15 | 16 | 16 | 16 | 16
Store 5 | 6,11,13 | 6,11,13 | 6,11,13 | 14,18,19| 14,18,19| 14,18,19| 14,18,19
我的问题是,如何在我的数据库中表示?我提出了以下想法:
创意1 :几乎复制了上面的设计,创建了一个包含以下列的表:[Store_id |周一|星期二... |周六| Sun]然后将每天的员工ID列表存储为字符串,ID以逗号分隔。我知道以逗号分隔的列表不是很好的数据库设计,但有时它们看起来很诱人,就像在这种情况下一样。
Store_id | Mon | Tue | Wed | Thu | Fri | Sat
---------+---------+---------+---------+---------+---------+---------
1 | '3,4,5' | '3,4,5' | '3,4,5' | '4,5,7' | '4,5,7' | '4,5,6,7'
2 | '1,8,9' | '1,8,9' | '1,8,9 '| '1,8,9' | '1,8,9' | '1,8,9'
创意2 :创建一个包含以下列的表:[Store_id |一天|员工ID]。这样,在特定日期在特定商店工作的每个员工都将成为此表中的条目。我看到的问题是这个表会增长得非常快,而且在数据库级别可视化数据会更困难。
Store_id | Day | Employee_id
---------+-----+-------------
1 | mon | 3
1 | mon | 4
1 | mon | 5
1 | tue | 3
1 | tue | 4
这些想法中的任何一个都可行吗?有没有更好的存储数据的方法?
答案 0 :(得分:2)
第二种设计对于关系数据库是正确的。每行一个employee_id,即使每天每个商店产生多行。
如果您的示例准确,则行数不可能大于RDBMS可以处理的行数。每家商店每天不超过4名员工,5家商店,每年最多366天。所以每年不超过7320行,也许更少。
我经常看到MySQL中的数据库在给定的表中有数亿甚至数十亿行。因此,在遇到可伸缩性问题之前,您可以继续运行这些存储多年。
答案 1 :(得分:2)
如果我是你,我会存储员工数据并将数据存储在单独的表中......但仍保留主表的设计。所以做这样的事情
CREATE TABLE stores (
id INT, -- make it the primary key auto increment.. etc
store_name VARCHAR(255)
-- any other data for your store here.
);
CREATE TABLE schedule (
id INT, -- make it the primary key auto increment.. etc
store_id INT, -- FK to the stores table id
day VARCHAR(20),
emp_id INT -- FK to the employees table id
);
CREATE TABLE employees
id INT, -- make it the primary key auto increment.. etc
employee_name VARCHAR(255)
-- whatever other employee data you need to store.
);
我会为商店和员工提供一个表格,因为您可以为每个商店或员工提供特定数据
<强>奖金:强>
如果您希望查询显示商店名称以及员工姓名及其日程安排,那么您所要做的就是加入两个表
SELECT s.store_name, sh.day, e.employee_name
FROM schedule sh
JOIN stores s ON s.id = sh.store_id
JOIN employees e ON e.id = sh.emp_id
这个查询有一定的局限性,因为您无法按天订购,因此您可以随机获取数据..所以实际上您还需要一个包含当天特定数据的日期表,以便您可以在开始时订购数据或本周末。
如果你确实想要制作一个日期表,那将会是同样的事情
CREATE TABLE days(
id INT,
day_name VARCHAR(20),
day_type VARCHAR(55)
-- any more data you want here
)
其中日名称为Mon Tue ...而day_type将为Weekday或Weekend
然后你要为查询做的就是
SELECT s.store_name, sh.day, e.employee_name
FROM schedule sh
JOIN stores s ON s.id = sh.store_id
JOIN employees e ON e.id = sh.emp_id
JOIN days d ON d.id = sh.day_id
ORDER BY d.id
注意日计划表中的两个列将替换为链接到days表的day_id的一列。
希望有帮助!
答案 2 :(得分:2)
我赞成John Ruddell的回答,这基本上是你的选择#2,增加了表来保存关于商店和员工的数据。我不会重复他所说的话,但是我只想补充一些太长的评论意见:
永远不要将逗号分隔值放在数据库记录中。这使得数据更难以使用。
当然,无论是#1还是#2,都可以轻松查询周五在1号店工作的员工:
方法1:
select Friday_employees from schedule where store_id='store 1'
方法2:
select employee_id from schedule where store_id=1 and day='fri'
但是假设您想知道员工#7的工作日期。
使用方法2,很容易:
select day from schedule where employee_id=7
但你怎么用方法1做到这一点?你可以打破它的各个部分并检查每一块。充其量只是一种痛苦,而且我已经看到人们经常搞砸了,比如写作
where Friday_employees like '%7%'
嗯,除非有员工编号17或27怎么办?你也会得到它们。你可以说
where Friday_employees like '%,7,%'
但是如果7是列表中的第一个或最后一个,它就不起作用。
如果您希望用户能够选择一天,然后向他们提供当天工作的员工列表,该怎么办?
使用方法2,轻松:
select employee_id from schedule where day=@day
然后使用参数化查询填写值。
方法1 ......
select employee_id from schedule where case when @day='mon' then Monday_employees when @day='tue' then Tuesday_employees when @day='wed' then Wednesday_employees when @day='thu' then Thursday_employees when @day='fri' then Friday_employees when @day='sat' then Saturday_employees as day_employees
这是一头野兽,如果你做了很多事,迟早你会犯错误,留下一天或意外地输入“当天='星期四'然后星期五_雇员”或其他类似的东西。我见过这种情况经常发生。
即使您编写那些冗长复杂的查询,性能也会很糟糕。如果您有employee_id字段,则可以对其进行索引,因此员工访问速度很快。如果您有一个以逗号分隔的员工列表,那么查询“喜欢'%,7,%'的品种需要按顺序搜索数据库中的每条记录。