Database 如何使用多个“";“多对多”;关系

Database 如何使用多个“";“多对多”;关系,database,database-design,many-to-many,Database,Database Design,Many To Many,我对数据库开发和体系结构相当陌生。我唯一的经历是在大学,现在我的项目要求我运用这些知识,然而我的项目似乎比我所学的要复杂得多 简要概述:我的任务是基本上把以前手工完成的书面工作转变成一个快速的计算机应用程序,我将用Java来完成,但现在还很遥远。我知道我需要建立一个数据库来完成我的任务,因为这些报告经常被编辑。这份报告是劳动报告。基本上,它显示了谁在从事某项特定的工作,这些工作的天数和小时数,以及他们的总小时数、工资率和总金额 我认为我当前的问题在于,我似乎将有几个“多对多”关系,甚至可能是嵌套

我对数据库开发和体系结构相当陌生。我唯一的经历是在大学,现在我的项目要求我运用这些知识,然而我的项目似乎比我所学的要复杂得多

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

我认为我当前的问题在于,我似乎将有几个“多对多”关系,甚至可能是嵌套的,这就是我试图将信息组织到实体关系图和表中时所遇到的问题。(我知道通常有更多的衡量和组织的发展阶段,但我没有这方面的经验,我基本上是一个人的团队)

可以从员工库中选择具有合同的人员

一份劳动合同可以有1人10人(为了在最终打印版本上留出空间,需要更多劳动力的工作将有另一份劳动合同。)

每个人员必须拥有1个头衔(工头、技工等)。这些头衔可以随工作的不同而变化。乔·史密斯可以是a工作的技工,但可以是B工作的工头。
每个人员也必须记录他们一周中每天工作的小时数;可能有加班和双倍加班。(每周一次劳动记录)

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

有人能提出建议吗


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

首先,深呼吸!在我看来,你对这件事处理得很好,也许比你想象的还要好!这根本不是为了尝试和设计你的项目,我相信你会有很多细节要处理,但也许这会让你知道如何面对这些在你脑海中游荡的多对多关系

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

以下是您可以用来开始学习的基本大纲。您的最终解决方案将根据您的具体需求而有所不同

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

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

+----+-------------+
| id | description |
+----+-------------+
|  1 | Contract A  |
|  2 | Contract B  |
| .. | ........... |
+----+-------------+
您将需要一个表来链接合同和员工,并显示员工对给定合同的标题。在我的示例中,您可以看到,对于合同,John Q Public是工头,Mary Jane Smith是技工。对于合同B,他们的头衔是相反的,约翰是机械师,玛丽是工头
contract\u id
employee\u id
是各自表的外键,它们一起构成主键。如果John和Mary可能因同一头衔获得不同的薪酬(例如John作为领班获得25.00/小时,而Mary获得20.00/小时),您可以在此处添加一列,而不是使用
头衔
表中的薪酬

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  |
| ........... | ........... | ........ |
+-------------+-------------+----------+
titles
    id                  varchar(15)(P)
    rate                double

+----------+-------+
| id       | rate  |
+----------+-------+
| Foreman  | 20.00 |
| Mechanic | 15.00 |
| ........ | ..... |
+----------+-------+
您需要一张员工桌(如果愿意,您可以打电话给该人员)。你可能会储存的不仅仅是他们的名字

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     | ... |
| .. | .......... | ........... | ......... | ... |
+----+------------+-------------+-----------+-----+
你需要一张表格来记录工作时间。我只存储开始和结束日期/时间,由应用程序计算经过的时间。您的应用程序还需要确保员工之间没有重叠-员工在任何给定时间都不能处理多个合同。加班和双倍加班时间的计算也取决于您的申请。如果雇员的工资率可以在任何时候改变(即在合同的中间),你就想把工资率存储在这个表中,而不是使用从<代码>契约>雇员> <代码>或<代码>标题>代码> >

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 |
| .. | ........... | ........... | ................... | ................... |
+----+-------------+-------------+---------------------+---------------------+
最后是一个存储标题及其相关薪酬的表格。如果可以为同一职位向员工支付不同的薪酬,则此处不需要“薪酬”列,而是使用存储在
合同\u employees
表中的薪酬

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  |
| ........... | ........... | ........ |
+-------------+-------------+----------+
titles
    id                  varchar(15)(P)
    rate                double

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

谢谢@Benny Hill的回答,我真的很感谢你花时间详细介绍。我会花一些时间来研究它,希望我能开始制作progress@solleks-当涉及到数据库设计时,请记住规范化(几乎总是)是一件好事。祝你好运@本尼希尔:看起来你认为“合同”就是“工作”。当我读到它的时候,它听起来有点像一个合同可以由几个工作组成(例如,“你被承包来执行工作a、B和C”)。在我看来,将有一个
工作
表,其中包含一个
合同id
,然后员工将被分配到一个工作,在这个工作中,他们的职位和薪酬将被定义(即,在同一工作中拥有相同职位的两名员工可能没有相同的薪酬)。然后,
contract\u employees
变成了
job\u employees
。只是一些食物,因为我不知道这是否是真正的意图。