我的数据库有一个跟踪部门和用户ID的表。这里的问题是虽然department和user_id列可以有重复项,但它们的组合却不能。这就是说,
DepartmentA 0001
DepartmentA 0002
DepartmentB 0001
DepartmentB 0002
是我表格中的有效数据。但是
DepartmentA 0001
DepartmentA 0001
无效。
department和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 :(得分:9)
我会使用代理主键,并对这两个应该保持唯一的字段的组合设置唯一约束。
也就是说,我不会将我的员工编号视为主键。这有利于很多场景。
所以,这就是我要做的事情
CREATE TABLE Employee
(
EmployeeId INT ,
EmployeeNumber VARCHAR(4),
DepartmentId INT,
EmployeeName
)
CREATE TABLE Department
(
DepartmentId INT,
DepartmentName
)
在Employee表中,EmployeeId是主键。此列只包含一个数字,在问题域中没有任何意义。它在数据库中只具有管理意义(唯一标识一个Employee)。
EmployeeNumber包含用于标识员工的业务/域号。请注意,我已将此字段设为VARCHAR字段,因为您在示例中使用零来对该数字进行LPAD。所以实际上,它不应该是一个数字字段。 :)
除此之外,Employees表中还有一个DepartmentId列,它是Department表的外键。 在Employee表中,您应该在EmployeeNumber / DepartmentId字段上放置一个Unique约束。 (因此,对两个列的组合有一个约束)。
然后,User_Activity表可以如下所示:
CREATE TABLE User_Activity
(
EmployeeId INT,
ActivityId INT
)
(我知道CREATE TABLE语句实际上并不是真正正确的SQL语句,但这只是为了说明目的)。
答案 1 :(得分:4)
只需创建单独的主键,并为(user_id,department)创建新的唯一索引。
答案 2 :(得分:0)
我会在User_ID和Department上创建您的主键作为复合,并在该表中有另一个字段,它是一个标识/自动增量字段(也有一个唯一索引),并使用THAT值作为您的FK引用其他领域。
这假设您不经常删除和重新创建用户/部门对(因为您每次都会破坏与下级表的链接),在这种情况下,将组合键用作FK可能更有意义参考
答案 3 :(得分:0)
我建议将代理标识符作为主键,并将复合user_id和department键作为备用唯一键。