4

建模以下内容的最佳方法是什么...

假设我有两个对象:AgencyPublisher,并且两者都与Employee. 这是一个真正的 1 对 n 关系,因为每个Employee只能为一个Agency或一个工作Publisher。让我们进一步假设我不能引入具有Employer1 对 n 关系的超类型(例如 )。

我首选的解决方案是有一个外键,Employee它可以链接到Agency或的主键Publisher(我的所有主键都是 64 位 ID,在数据库中是唯一的)。但是,现在我将无法映射双向关联,而无需指明Employee这是否是一种AgencyPublisher关系。

我的另一个选择是使用两个表AgencyEmployeePublisherEmployee,然后可以将它们链接为传统的 1 对 n 双向关联。

在这种情况下,您认为最佳做法是什么?

更新:感谢您在如此短的时间内做出如此出色的回应!您如何看待以下解决方案: and 的外键,Employee例如and ? AgencyPublisheragency_idpublisher_id

4

6 回答 6

1

最佳实践可能是引入一个 Employer 类。

另一方面,将 Employee 分为 AgencyEmployee 和 PublisherEmployee 将是一件坏事™。

如果介绍雇主是不可能的,我会在 Employee 中指明雇主类型(Agency 或 Publisher)。

回复更新的问题:

这是一种选择,但雇主类型更好,因为:

  1. 您将来可能希望添加其他雇主类型
  2. 在Employees 表的每一行中都会有一个空字段。
于 2009-03-11T16:52:19.857 回答
0

听起来这可以建模为三元关系。看看您是否喜欢这篇 MSDN 文章中采用的方法。

于 2009-03-11T16:43:39.033 回答
0

我个人的偏好是有一个你明确认为不能使用的表(代理和出版商的超级类型;雇主)

一个简单的替代方法是不强制执行外键约束。这不一定有问题,只要对数据结构的所有修改都是通过您控制的存储过程完成的。

我的最终偏好与您的建议类似,即为 AgencyEmployees 设置一个表,为 PublisherEmployees 设置一个表。但我会把它分开一步......

Table1: Agency              (id, name, etc)
Table2: Publisher           (id, name, etc)
Table3: Employee            (id, name, etc)
Table4: AgencyEmployees     (agency_id, employee_id)
Table5: PublisherEmployees  (publisher_id, employee_id)


我这样做的一个原因是让这个时间依赖变得微不足道。员工开始、离开和在公司之间移动。以下对上述内容的轻微修改将允许您跟踪...

Table1: Agency              (id, name, etc)
Table2: Publisher           (id, name, etc)
Table3: Employee            (id, name, etc)
Table4: AgencyEmployees     (agency_id,    employee_id, start_date, leave_date)
Table5: PublisherEmployees  (publisher_id, employee_id, start_date, leave_date)

这不会在任何时候对每位员工强制执行 1 个雇主,但可以通过您的存储过程、GUI 等强制执行...

于 2009-03-11T16:53:47.323 回答
0

我使用了这种方法:

Employee.EmployerType('AGENCY' 或 'PUBLISHER')

Employee.EmployerID(AgencyID 或 PublisherID)

它工作正常,但是您需要在很多 SQL 中使用 case 语句。如果您使用的是 ORM,那么您也会失去 FK 关系。

我正在将我的大部分代码移动到 n:m 关系,以便我可以利用我们的 ORMs FK 支持。

于 2009-03-11T16:53:49.290 回答
0

显然,雇主实体将是首选,但除此之外......

拥有 AgencyEmployee 和 PublisherEmployee 表意味着很难确定员工是否属于一个类别。

因此,我会将 EmployerType 列添加到Employees 表中;它为您的后续 SQL 查询增加了一点额外的复杂性,但它在您给定的约束范围内工作。

出于兴趣,您为什么可以添加 AgencyEmployee 和 PublisherEmployee 表,但不能添加 Employer 表?只是好奇...

于 2009-03-11T17:04:17.300 回答
0

Can Berk Güder 获得 +1。

从技术上讲,引入 Employer 超类型意味着您引入具有 Agency 和 Publisher 共有的所有属性的 Employer 关系,具有 Employer 键和所有 Agency 特定属性的 AgencySpecific(不知道如何调用它)关系以及作为外来的 Employer 键键,然后是 Agency 作为查询或视图,它只将 AgencySpecific 与 Employer 连接起来,对于 Publisher 也是如此。

将 Agency 和 Publisher 数据分布在您每次都必须加入的两个表中可能有点麻烦,但另一种方法是编写与员工相关的大部分查询两次,一次使用 Agency,一次使用 Publisher,然后手工编写他们的工会将结果结合起来。(我还没有看到一个查询构建器可以帮助处理像这样的基本内容。)我不得不为一个使用“无超类型”方法的项目做这件事,我不想再做一次。

如果你问我,顺便说一句,三元关系甚至 n 对 n 关系都不是好的设计实践。仅使用函数(即 1 对 n 和 1 对 1)例如约束变得更容易制定。

于 2009-03-11T17:17:37.783 回答