繁体   English   中英

如何设计数据库以容纳此数据

[英]How to design my database to accommodate this data

我正在开发一个用于薪资应用程序的数据库,我需要的功能之一是一个表,该表存储一周中每一天在每个商店工作的雇员的列表。

每个员工都有一个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

这些想法听起来可行吗? 还有更好的数据存储方式吗?

第二种设计对于关系数据库是正确的。 即使每天导致每家商店多行,每行一个employee_id。

如果您的示例正确,那么行数可能不会超过RDBMS可以处理的行数。 您每个商店每天最多不超过4名员工,最多不超过5个商店,每年最多366天。 因此,每年不超过7320行,也许更少。

我经常看到MySQL中的数据库在给定表中具有数亿甚至数十亿行。 因此,在遇到可伸缩性问题之前,您可以继续经营这些商店很多年。

如果我是您,我会存储员工数据并将数据存储在单独的表中...但是仍然保留主表的设计。 所以做这样的事情

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
)

日期名称为星期一星期二...,day_type为星期几或周末

然后您要做的就是查询

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

注意,日程安排表中的两个列将替换为链接到日表的day_id的一列。

希望那有帮助!

我赞成约翰·鲁德尔的答案,基本上这是您的选择#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

那是一头野兽,如果您经常这样做,那么迟早您将犯错并浪费一天的时间,或者不小心键入“ when day ='thu'then Friday_employees”或类似的内容。 我已经看到这种情况经常发生。

即使您编写了那些冗长的复杂查询,性能也会很糟糕。 如果您有一个名为employee_id的字段,则可以在该字段上建立索引,因此员工访问将很快。 如果您有一个用逗号分隔的员工列表,则要查询“%'7,%'%之类的变量,需要对数据库中的每个记录进行顺序搜索。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM