如何否定或最小化具有多个“多对多”关系的重复数据库记录(行)

时间:2014-01-16 16:52:15

标签: database database-design many-to-many

我是数据库开发和架构的新手。我唯一的经历是在大学里,现在我的项目要求我使用这些知识,但是我的项目看起来要复杂得多,复杂程度要比我研究的复杂得多。

简要概述:我的任务是将以前手工完成的纸质工作基本上变成一个快速的计算机应用程序,我将用Java做,但现在还很遥远。我知道我需要一个数据库设置来完成我的任务,因为这些报告经常被编辑。该报告是劳工报告。基本上,它显示了谁在从事某项特定工作,当天的工作日数和工作时数,以及他们的总工时,工资率和总金额。

我相信我当前的问题在于,我似乎会有几个“多对多”的关系,甚至可能是嵌套的,这就是我试图组织信息时我的头脑旋转到实体关系图和表。 (我知道通常会有更多测量和组织的发展阶段,但我没有这种经验,而且我基本上是一个单人团队)

从员工池中选择合同人员。

劳动合同可以 1 10名员工(为了最终印刷版本的空间,需要更多劳动力的工作将会有另一份劳动合同。)

每个人员必须 1 标题(领班,机械师等)这些标题可以在不同工作之间变更。乔史密斯可以是工作A的机械师,但是工作B的工头 每个人员 必须还记录他们每周工作的小时数;并且可能加班加倍。 (每周一份劳工记录)。

我试图避免重复数据,或者至少将其保持在最低限度,但我正在努力弄清楚在这种情况下如何做到这一点。至少在我看来,棘手的事情是弄清楚如何处理这样一个事实:不同的员工可以同时处理多个工作,不同的头衔和不同的工资率,并记录不同类型的工作时间(直接时间,OT,双OT)在一周的每一天。

有人可以提出建议吗?

我希望我提供足够的信息并道歉,如果我没有或不够详细。请记住,请记住,我是这类工作的新手。

2 个答案:

答案 0 :(得分:2)

首先,深吸一口气!在我看来,你对此有一个非常好的处理,可能比你想象的还要多!这根本不是尝试和设计你的项目,我相信你会有很多细节需要处理,但也许这会让你知道如何面对周围游泳这么多的多对多关系在你的脑海里。

EMPLOYEES
---------
emp_id
emp_name
emp_address


JOBS
----
job_id
job_description


EMPLOYEE_JOBS
-------------
ej_id    -- primary key
emp_id   -- fk to employees table
job_id   -- fk to jobs table
ej_title -- employee title for this job
ej_rate  -- employee pay rate for this job


EMPLOYEE_JOB_HOURS
------------------
ejh_id  -- primary key
ej_id   -- fk to employee_jobs table
ejh_date
ejh_normal_hours  -- hours worked by the employee on this job on this date, etc.
ejh_overtime_hours
ejh_double_overtime_hours

答案 1 :(得分:1)

以下是您可以用来开始的基本概要。您的最终解决方案将根据您的确切需求而有所不同。

您需要一张表来存储合同信息。我的例子只是一个描述,但我相信你会有更多的东西。

contracts
    id              unsigned int(P)
    description     varchar(50)

+----+-------------+
| id | description |
+----+-------------+
|  1 | Contract A  |
|  2 | Contract B  |
| .. | ........... |
+----+-------------+

您需要一个链接合同和员工的表格,并显示员工对给定合同的标题。在我的例子中,你可以看到,对于契约A,John Q Public是一名工头,而Mary Jane Smith是一名机械师。对于合同B,他们的头衔是相反的,约翰是机械师而玛丽是工头。 contract_idemployee_id是各自表的外键,它们一起构成主键。如果John和Mary有可能为同一个头衔支付不同的费率(例如,约翰得到25.00 /小时作为Foreman而Mary得到20.00 /小时)你会在这里添加一列,而不是使用titles中的费率表

contracts_employees
    contract_id     unsigned int(F contracts.id)--\_(P)
    employee_id     unsigned int(F employees.id)--/
    title_id        varchar(15)(F titles.id)

+-------------+-------------+----------+
| contract_id | employee_id | title_id |
+-------------+-------------+----------+
|           1 |           1 | Foreman  |
|           1 |           2 | Mechanic |
|           2 |           1 | Mechanic |
|           2 |           2 | Foreman  |
| ........... | ........... | ........ |
+-------------+-------------+----------+

您需要一张员工桌(如果您愿意,可以打电话给这些人员)。你可能会存储的不仅仅是他们的名字......

employees
    id              unsigned int(P)
    first_name      varchar(30)
    middle_name     varchar(30)
    last_name       varchar(30)
    ...

+----+------------+-------------+-----------+-----+
| id | first_name | middle_name | last_name | ... |
+----+------------+-------------+-----------+-----+
|  1 | John       | Quincy      | Public    | ... |
|  2 | Mary       | Jane        | Smith     | ... |
| .. | .......... | ........... | ......... | ... |
+----+------------+-------------+-----------+-----+

您需要一张表来跟踪工作时间。我只存储一个开始和结束日期/时间,将其留给应用程序来计算经过的时间。您的申请还需要确保员工不会重叠 - 员工在任何特定时间都不应该处理多份合同。加班和双加班时间的计算也取决于您的申请。如果员工的工资率随时发生变化(即在合同中间),您可能希望将工资率存储在此表中,而不是使用contracts_employeestitles中的费率。

hours
    id              unsigned int(P)
    contract_id     unsigned int(F contracts.id)
    employee_id     unsigned int(F employees.id)
    beg             datetime
    end             datetime

+----+-------------+-------------+---------------------+---------------------+
| id | contract_id | employee_id | beg                 | end                 |
+----+-------------+-------------+---------------------+---------------------+
|  1 |           1 |           1 | 2014-01-01 08:00:00 | 2014-01-01 17:00:00 |
|  2 |           1 |           2 | 2014-01-01 09:00:00 | 2014-01-01 17:30:00 |
|  3 |           1 |           1 | 2014-01-02 09:00:00 | 2014-01-02 10:00:00 |
|  4 |           1 |           2 | 2014-01-02 08:00:00 | 2014-01-02 09:00:00 |
|  5 |           2 |           1 | 2014-01-02 10:00:00 | 2014-01-02 17:30:00 |
|  6 |           2 |           2 | 2014-01-02 09:00:00 | 2014-01-02 15:00:00 |
| .. | ........... | ........... | ................... | ................... |
+----+-------------+-------------+---------------------+---------------------+

最后是一张存储标题及其相关工资率的表格。如果员工可以为同一个职位支付不同的费率,则您不需要此处的费率列,而是使用contracts_employees表中存储的费率。

titles
    id                  varchar(15)(P)
    rate                double

+----------+-------+
| id       | rate  |
+----------+-------+
| Foreman  | 20.00 |
| Mechanic | 15.00 |
| ........ | ..... |
+----------+-------+