2009-02-03 81 views
0

我的数据库有一个表跟踪部门和用户ID。这里的结论是,尽管department和user_id列可以有重复,但它们的组合不能。这就是说,双主键设计

DepartmentA 0001 
DepartmentA 0002 
DepartmentB 0001 
DepartmentB 0002 

是我的表中的有效数据。但

DepartmentA 0001 
DepartmentA 0001 

有效。

部门和user_id的组合形成记录的唯一标识符。在另一个表中,我需要使用这个唯一的标识符来跟踪用户的活动,比如他们进入建筑物的时间,他们离开建筑物的时间等。

我在想的是我创建了下列表格

CREATE TABLE user (
user_id INT(4), 
department VARCHAR(25) NOT NULL , 
combined_id int(4) , 
UNIQUE (combined_id) , 
Primary key(user_id, department) 
); 



CREATE TABLE user_activity(
combined_id int(4), 
activity varchar(25), 
Foreign Key (combined_id) references user(combined_id) 
); 

所以我想为我的目的使用双主键。这是恕我直言,是保证数据完整性的最佳方式。但是根据我所知,使用双主键可能很难与ORM一起使用,即它们不完全支持,并且必须为其编写定制查询。

鉴于我的情况,上述设计是否最好?

+0

什么是平台? – 2009-02-03 11:59:27

+0

其中ORM?这比数据库更有可能重要。 – 2009-02-03 12:02:55

+0

Propel和ADO.Net实体框架 – Graviton 2009-02-03 12:05:24

回答

9

我会使用代理主键,并对这两个字段的组合应该保持唯一的唯一约束。

也就是说,我不认为我的员工编号是主键。这有利于很多场景。

所以,这是我会做什么

CREATE TABLE Employee 
(
    EmployeeId INT , 
    EmployeeNumber VARCHAR(4), 
    DepartmentId INT, 
    EmployeeName 
) 

CREATE TABLE Department 
(
    DepartmentId INT, 
    DepartmentName 
) 

在雇员表,雇员的主键。该列只包含一个数字,在问题域中没有意义。它在数据库中仅具有管理含义(唯一标识一个员工)。

EmployeeNumber包含'用于标识员工的业务/域号码'。请注意,我已将此字段设置为VARCHAR字段,因为您在示例中将LPAD的数字设为零。所以实际上,它不应该是一个数字字段。 :)

接下来,Employees表中还有一个DepartmentId列,它是Department表的外键。 在Employee表中,您应该在EmployeeNumber/DepartmentId字段上添加唯一约束。 (所以,对两列的组合有一个约束)。

然后,User_Activity表可以只是看起来像这样:

CREATE TABLE User_Activity 
(
    EmployeeId INT, 
    ActivityId INT 
) 

(我知道CREATE TABLE语句是不是真的实际正确的SQL语句,但是这仅仅是用于说明目的offcourse)。

0

我会创建您的主键作为User_ID和Department上的组合,并在该表中具有另一个字段,即身份/自动增量字段(也包含唯一索引),并将THAT值用作FK参考到其他领域。

这假设你不会经常删除并重新创建用户/部门对(因为每次都会打断与下属表的关联),在这种情况下,使用组合键作为您的组合键可能更有意义FK参考。

0

我建议让代理标识符作为主键,复合user_id和部门密钥作为备用唯一键。

4

只需创建单独的主键,并为(user_id,department)创建新的唯一索引。