Note
我完全重写了我原来的帖子,以便更好地解释我想要了解的问题 . 我试图尽可能地概括这个问题 .
另外,我要感谢回应的原始人 . 希望这篇文章能让事情变得更加清晰 .
Context
简而言之,我正在努力理解设计小规模数据库以处理(我认为是)多个多对多关系的最佳方法 .
想象一下公司组织结构的以下场景:
Textile Division Marketing Division
| |
---------------------- ----------------------
| | | |
HR Dept Finance Dept HR Dept Finance Dept
| | | |
---------- ---------- ---------- ---------
| | | | | | | |
Payroll Hiring Audit Tax Payroll Hiring Audit Accounts
| | | | | | | |
Emps Emps Emps Emps Emps Emps Emps Emps
注意: Emps
表示在该区域工作的雇员名单
当我第一次开始这个问题时,我做了四个单独的表:
-
Divisions
- >纺织,营销(PK = DivisionID) -
Departments
- >人力资源,财务(PK = DeptID) -
Functions
- >薪资,招聘,审计,税务,账户(PK = FunctionID) -
Employees
- >所有员工列表(PK = EmployeeID)
我认为问题在于存在多个多对多关系,即许多部门有许多部门,许多部门有很多部门 .
Question
给出上面的数据库结构,假设我想要执行以下操作:
- 获取在营销部门的薪资功能中工作的所有员工
为此,我需要能够区分两个薪资部门,但我不确定如何做到这一点?
我知道我可以在Departments和Functions之间 Build 一个'Link / Junction'表,这样我就可以检索哪些部门的功能 . 但是,我仍然需要区分他们所属的部门 .
Research Effort
正如您所看到的,在数据库设计方面,我是一名初学者 . 我花了最近两天来解决这个问题,遍历嵌套集模型,邻接模型,读取这个问题已知不是NP完全等等 . 我确信有一个简单的解决方案?
7 回答
基于更新后的帖子,并基于所使用的名称做出一些(相当明显的)假设,我想出了以下内容 . 有四个实体:
分部
部门
功能
实体
这些实体之间存在许多关系 . 其中很少是等级的,大多数都是简单的联想:
选项A1:有一个主要的功能列表 . 每个部门都可以执行(或执行)一个或多个功能,并且可以由多个部门执行功能 .
选项A2:各部门“拥有”职能 . 两个或更多部门无法执行任何功能 . (情况似乎如此,因为人力资源部门有薪资和招聘,财务部门有审计,税务和账户 . )
各部门(代表)各部门履行职能 . (人力资源部负责纺织和营销部门的薪资和招聘;财务部负责纺织部门的审计和税务 - 但不包括账户 - 审计和账户 - 但不包括营销部门的税务 . )也许有点更准确地说,部门为与之关联的所选部门执行选定的功能,并且该关联由其功能的性能定义 .
除了履行职能部门之外,部门和部门之间似乎没有任何关系 . 它们之间没有层次关系,因为一个人不“拥有”或包含另一个 .
这导致了这些大致草拟的表格:
(您可以选择包含一个代理键来唯一标识每一行,但DivisionId FunctionId可以工作 . )
这里没有足够的材料来充分描述"employees"如何适应模型 . 鉴于员工从事的是职能部门的工作:员工可以完成多项职能的工作,还是只做一项职能?员工是否负责该职能的工作,无论其所处的职责是什么,或者他们是否被指派为一个或多个部门工作?这里有两个明显的选择,但更复杂的变体是可能的:
选项B1:员工在部门内完成一项或多项职能的工作,并为需要该部门职能的所有部门执行该工作 .
选项B2:指定员工为特定部门执行特定功能 .
鉴于这些,表可能看起来像:
......因此,所有能够执行功能的员工都会为需要它的所有部门执行该功能 . 要么,
(或者,而不是DivisionId和FunctionId,包括来自DivisionFunctions的可选代理键 . )...因此,员工被单独分配给部门为部门执行的功能 .
但这仍然留下了很多“如果/何时”的问题:员工“属于”部门吗?员工可以属于(为多个部门工作)吗?也许员工属于分部?您是否跟踪员工可以执行哪些功能,即使他们目前没有这样做?同样,你跟踪员工在哪个部门工作,即使他们目前“在职能部门之间”?如果员工可以执行功能A和B,并且某个部门需要这两个功能,那么员工是否可以被分配为仅为该部门执行A而不是B?
这里有更多的需求研究要做,但我想这是一个好的开始 .
好吧,你不会把它全部放在一张 table 里 . 您需要阅读规范化数据和连接 . (永远不要在逗号分隔列表中存储任何内容 . )
没有数据库值得它的盐会有最轻微的问题处理一百万条记录,这是一个很小的数据库 .
您需要用于功能,课程,位置,人员,组织以及可能的一些连接表的表,以适应多对多的关系 . 但这一切都不是很难,甚至超出了非常基本的设计 . 我建议您在执行任何操作之前,先阅读所选数据库的书籍并阅读基础知识 .
你需要一个简单的 star 关系 . 位置(事实表)只有相关主表的ID(部门,部门等) . 这允许使用主表的任何组合
主表可以根据需要在每个主表中构建简单的层次结构 . 并且可以根据需要相互关联 . 但是详细信息不会影响对Position的查询
对于可选关系,您可以将ID设置为位置可空
您可以将StartDate和EndDate列添加到Position以跟踪随时间的变化
一个简单的例子是:
SQL Table Diagram http://img52.imageshack.us/img52/3484/sqldiag1.jpg
因为你是"abecedarian" :),在尝试在家中使用数据库设计之前要做的一件事是关于规范化,并完全理解所有正常形式,直到5NF
如果你想模仿那个
部门是分部的
2.职能在部门执行
3.员工履行职能
并且并非所有功能都在所有部门中执行,也不是所有部门都在所有部门中,那么您必须将该事实存储在某个地方 .
在进行逻辑设计时,请为表格提供描述性名称,以便某些部门处于分支状态
那么你在某些部门有一些功能
然后,员工可以从一些部门和部门获得一些职能
在此之后(或之前),您还有3个实体函数,部门和部门,它们将列出上述表格也会引用的所有可能的部门,部门和职能(这可能没有完全标准化) .
此外,实体(表)的名称可以变得更适合您(只有您可以知道数据模型的完整语义) . 特别是如果您注意到需要为其分配其他属性(字段) .
部门,部门和职能部门的名称是他们的名字,在上面的分析中还没有人工设备 . 在逻辑建模进行物理建模之后,您可以在下一步中介绍它们,或者您可以保留自然键 . 如果使用可以将复合键的使用量减少到最大2的人工键,但它会混淆您在表中存储的事实的关系和含义 . (示例functionID可以是函数名称的ID,也可以是在某个部门/部门组合中执行的函数的ID - 不清楚它是什么,这些不可互换;有点像实例和实例之间的区别类) .
尝试给每个实体一个自己的表格,例如
一些样本选择
通常在我 Build 数据库时,我想出了我需要的实体以及它们如何相互关联(即多对一,一对......) . 你似乎已经做了什么 . 接下来我会弄清楚每个实体需要什么 . 例如,位置可能具有:locationid,address,...然后,分部假设每个分区有一个位置,您可以让分区实体具有divisionid,locationid,每个分区需要的信息 . 所以基本上,如果它是一个多关系,就像一个位置到多个部门,你可以把位置的id放在除法表中 . 但是,如果它是一个多关系,那么最好有一个中间表来连接这两个,这样你就不需要只有id更改的重复记录 .
也许(可能)您应该将纺织部门的人力资源部门视为与市场部门人力资源部门不同的部门 .