2

独特的全球/本地ID我已阅读Eric Evans的领域驱动设计的书,我一直在尝试应用一些概念。DDD:造型骨料实体的PostgreSQL中

在他的书中,埃里克谈到总量和总如何根应该有一个全局唯一的id,而总成员应该有一个唯一的本地ID。我一直在试图将这个概念应用到我的数据库表中,并且遇到了一些问题。

我在我的PostgreSQL数据库的两个表:设施,以及员工可以分配到一个单一的工厂员工。


在过去,我会如下铺陈员工表:

CREATE TABLE "employees" (
    "employeeid" serial NOT NULL PRIMARY KEY, 
    "facilityid" integer NOT NULL, 
    ... 
    FOREIGN KEY ("facilityid") REFERENCES "facilities" ("facilityid") 
); 

其中雇员是一个独一无二的ID。然后,我会在后端添加代码以进行访问控制验证,从而防止一个设施的用户访问与其他设施有关的行。我有一种感觉,这可能不是最安全的做法。



我现在所考虑的是这个布局:

CREATE TABLE "employees" (
    "employeeid" integer NOT NULL, 
    "facilityid" integer NOT NULL, 
    ... 
    PRIMARY KEY ("employeeid", "facilityid"), 
    FOREIGN KEY ("facilityid") REFERENCES "facilities" ("facilityid") 
); 

其中雇员是唯一的(本地)对于一个给定facilityid,但需要与facilityid配对是唯一的全球性。

具体而言,这是我在寻找:

员工A(雇员:1,facilityid:1)
雇员B(雇员:2,facilityid:1)
雇员C(雇员:1, facilityid:2)

其中A,B和C是3名不同的员工和...
添加雇员d到设备1能给他键(雇员:3,facilityid:1)
加入雇员E到设施2将给他钥匙(employeeid:2,facilityid:2)


我看到实现这一目标的方式有两种:

  1. 我可以使用触发器或存储过程自动生成新的employeeids并存储在另一个表中的每个设施的最后IDS以便更快地访问,但我关注并发问题并最终得到来自同一个设施的2名具有相同ID的员工。

  2. 我可能会为每个设施创建一个新的序列来管理employeeids,但我担心最后会有数千个序列来管理,并且程序会删除这些序列以防删除设施。这有什么不对吗?这对我来说很重要。

我应该采取哪种方法?有什么我错过了吗?

+1

我对你想要达到什么(以及与DDD有什么关系)有点困惑。您首先将一对多关系描述为需求,然后在“这是我正在寻找的:”中显示多对多关系的数据。你打算在这个有界上下文中暴露Employee实体吗?通常,根据我的经验,全局ID和本地ID之间的区别仅仅是使全局成为UUID(或GUID)。然后你知道这个id在各种有界环境中是唯一的。 – 2012-04-07 08:22:04

+0

我编辑了我的问题,希望能够让它不那么含糊。我想要的关系是一对多关系,Employee实体不会暴露在有界关系之外。 我主要是寻找最佳的方式来生成这些employeeids。 – akp 2012-04-07 08:51:10

回答

1

我从你的问题,你将所有的设备上运行一个单一的数据库推断,或至少,如果你有一个本地数据库为“主”为每个设备数据将需要在组合中央数据库无冲突。

我会使facilityid 高阶主键的一部分。您可以使用简单的SELECT max(employeeid) + 1 ... WHERE facilityid = n方法分配新员工编号,因为将员工添加到任何一个工厂大概不会每秒从多个并发源中发生数百次。这可能会导致偶然的序列化失败,但我认为任何数据库访问都应该通过一个框架来识别这些数据库并自动重试交易。

1

我想你在这里夸大了总根概念。根据我对员工建模的理解(这取决于您的上下文),员工几乎总是可能由另一个聚合根设施引用的引用

员工和设施几乎都有自然钥匙。对于员工来说,这通常是一些员工ID(打印在员工身份证上,或者至少保存在人力资源软件系统中),并且设施具有这种自然密钥也几乎总是包含一些位置部分和一些数字,如“MUC-1 “位于慕尼黑的设施1。但这一切都取决于你的背景。如果员工和设施拥有这些自然键,那么您的数据库模型应该非常清晰。