简体   繁体   English

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

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

I am developing a database for a payroll application, and one of the features I'll need is a table that stores the list of employees that work at each store, each day of the week. 我正在开发一个用于薪资应用程序的数据库,我需要的功能之一是一个表,该表存储一周中每一天在每个商店工作的雇员的列表。

Each employee has an ID, so my table looks like this: 每个员工都有一个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

My question is, how do I represent that on my database? 我的问题是,我该如何在数据库中表示呢? I came up with the following ideas: 我提出了以下想法:

Idea 1 : Pretty much replicate the design above, creating a table with the following columns: [Store_id | 想法1 :几乎复制了上面的设计,创建了一个包含以下列的表:[Store_id | Mon | 周一| Tue ... | 周二... | Sat | 星期六| Sun] and then store the list of employee IDs of each day as a string, with IDs separated by commas. Sun],然后将每天的员工ID列表存储为字符串,且ID以逗号分隔。 I know that comma-separated lists are not good database design, but sometimes they do look tempting, as in this case. 我知道用逗号分隔的列表不是很好的数据库设计,但是有时这种情况看起来确实很诱人。

   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'   

Idea 2 : Create a table with the following columns: [Store_id | 想法2 :创建一个包含以下列的表格:[Store_id | Day | Employee_id]. 员工ID]。 That way each employee working at a specific store at a specific day would be an entry in this table. 这样,在特定日期在特定商店工作的每位员工将成为此表中的条目。 The problem I see is that this table would grow quite fast, and it would be harder to visualize the data at the database level. 我看到的问题是,该表将快速增长,并且很难在数据库级别可视化数据。

Store_id | Day | Employee_id
---------+-----+-------------
   1     | mon |     3
   1     | mon |     4
   1     | mon |     5
   1     | tue |     3
   1     | tue |     4

Any of these ideas sound viable? 这些想法听起来可行吗? Any better way of storing the data? 还有更好的数据存储方式吗?

The second design is correct for a relational database. 第二种设计对于关系数据库是正确的。 One employee_id per row, even if it results in multiple rows per store per day. 即使每天导致每家商店多行,每行一个employee_id。

The number of rows is not likely to get larger than the RDBMS can handle, if your example is accurate. 如果您的示例正确,那么行数可能不会超过RDBMS可以处理的行数。 You have no more than 4 employees per store per day, and 5 stores, and up to 366 days per year. 您每个商店每天最多不超过4名员工,最多不超过5个商店,每年最多366天。 So no more than 7320 rows per year, and perhaps less. 因此,每年不超过7320行,也许更少。

I regularly see databases in MySQL that have hundreds of millions or even billions of rows in a given table. 我经常看到MySQL中的数据库在给定表中具有数亿甚至数十亿行。 So you can continue to run those stores for many years before running into scalability problems. 因此,在遇到可伸缩性问题之前,您可以继续经营这些商店很多年。

if I were you I would store the employee data and stores data in separate tables... but still keep the design of your main table. 如果我是您,我会存储员工数据并将数据存储在单独的表中...但是仍然保留主表的设计。 so do something like this 所以做这样的事情

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.
);

I would have a table for stores and for employees as that way you can have specific data for each store or employee 我会为商店和员工提供一张表格,这样您就可以为每个商店或员工提供特定的数据

BONUS: 奖金:

if you wanted a query to show the store name with the employees name and their schedule and everything then all you have to do is join the two tables 如果要查询以显示商店名称,员工姓名和他们的时间表以及所有内容,那么您要做的就是将两个表连接起来

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

this query has limitations though because you cannot order by days so you could get data by random days.. so in reality you also need a days table with specific data for the day that way you can order the data by the beginning or end of the week. 该查询有局限性,因为您无法按天排序,因此可以按随机天数获取数据。因此,实际上,您还需要一个包含特定数据的天表,以便您可以按日期的开始或结尾对数据进行排序周。

if you did want to make a days table it would just be the same thing again 如果您确实想做一个天数表,那就又是一回事了

CREATE TABLE days(
    id INT,
    day_name VARCHAR(20),
    day_type VARCHAR(55)
    -- any more data you want here
)

where day name would be Mon Tue... and day_type would be Weekday or Weekend 日期名称为星期一星期二...,day_type为星期几或周末

and then all you would have to do for your query is 然后您要做的就是查询

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

notice the two colums in the schedule table for day would be replaced with one column for the day_id linked to the days table. 注意,日程安排表中的两个列将替换为链接到日表的day_id的一列。

hope thats helpful! 希望那有帮助!

I upvoted John Ruddell's answer, which is basically your option #2 with the addition of tables to hold data about the store and the employee. 我赞成约翰·鲁德尔的答案,基本上这是您的选择#2,其中增加了用于存储有关商店和员工的数据的表。 I won't repeat what he said, but let me just add a couple of thoughts that are too long for a comment: 我不会重复他的讲话,但让我补充一些想法,这些想法太长了,无法发表评论:

Never ever ever put comma-separated values in a database record. 永远不要将逗号分隔的值放在数据库记录中。 This makes the data way harder to work with. 这使得数据处理起来更加困难。

Sure, either #1 or #2 makes it easy to query to find which employees are working at store 1 on Friday: 当然,使用#1或#2可以轻松查询以查找哪些员工在星期五在1号商店工作:

Method 1: 方法1:

select Friday_employees from schedule where store_id='store 1'

Method 2: 方法2:

select employee_id from schedule where store_id=1 and day='fri'

But suppose you want to know what days employee #7 is working. 但是,假设您想知道7号员工的工作时间。

With method 2, it's easy: 使用方法2,很容易:

select day from schedule where employee_id=7

But how would you do that with method 1? 但是如何使用方法1来做到这一点? You'd have break the field up into it's individual pieces and check each piece. 您将把该字段分解成各个部分,并检查每个部分。 At best that's a pain, and I've seen people screw it up regularly, like writing 充其量是痛苦的,而且我已经看到人们经常将其弄糟,例如写作

where Friday_employees like '%7%'

Umm, except what if there's an employee number 17 or 27? 嗯,除非有17号或27号员工怎么办? You'll get them too. 您也将获得它们。 You could say 你可以说

where Friday_employees like '%,7,%'

But then if the 7 is the first or the last on the list, it doesn't work. 但是,如果7是列表中的第一个或最后一个,它将不起作用。

What if you want the user to be able to select a day and then give them the list of employees working on that day? 如果您希望用户能够选择一天,然后为他们提供当天工作的雇员列表,该怎么办?

With method 2, easy: 使用方法2,容易:

select employee_id from schedule where day=@day

Then you use a parameterized query to fill in the value. 然后,您可以使用参数化查询来填写值。

With method 1 ... 使用方法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

That's a beast, and if you do it a lot, sooner or later you're going to make a mistake and leave a day out or accidentally type "when day='thu' then Friday_employees" or some such. 那是一头野兽,如果您经常这样做,那么迟早您将犯错并浪费一天的时间,或者不小心键入“ when day ='thu'then Friday_employees”或类似的内容。 I've seen that happen often enough. 我已经看到这种情况经常发生。

Even if you write those long complex queries, performance will suck. 即使您编写了那些冗长的复杂查询,性能也会很糟糕。 If you have a field for employee_id, you can index on it, so access by employee will be fast. 如果您有一个名为employee_id的字段,则可以在该字段上建立索引,因此员工访问将很快。 If you have a comma-separated list of employees, then a query of the "like '%,7,%' variety requires a sequential search of every record in the database. 如果您有一个用逗号分隔的员工列表,则要查询“%'7,%'%之类的变量,需要对数据库中的每个记录进行顺序搜索。

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

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