在SQL中,向多对多表添加一个关系“类型”是一种不好的做法吗?
在SQL中,向多对多表添加一个关系“类型”是一种不好的做法吗?
我正在构建一个Postgres数据库,其中包含以下两个表:
Projects(id,startDate等...)
和
Employees(id,name等...)
我想跟踪员工对项目的贡献类型。例如,员工#1可能是项目1的“工程师”,项目2的“经理”。我也不想限制员工对某个项目的贡献次数。所以员工#1可以同时是单个项目的“工程师”和“经理”。
我最初的想法是在两个表之间建立多对多的关系,称为ProjectEmployees之类的表,并将projectId,employeeId和contributionType作为字符串存储。这个字符串只能取自一个枚举值,以避免处理拼写错误或其他相关问题。
我的主要问题只是这样做是否是一种不好的做法。我另一个想法是将每种贡献类型拆分成自己的表。所以不再有一个EmployeeProjects表,而是会有像ProjectEngineers,ProjectManagers等表,而且不再将contributionType存储为列,而是隐含在我使用的表中,并且该表只需存储projectId和employeeId。在这个数据库中有许多其他表具有类似的关系,其中不同表之间存在多对多的关系,但每个关系可以是多种“类型”之一。将所有这些拆分成每种关系类型的单独表是否更明智?还是最好在一个更通用的表中跟踪关系类型,就像我第一个想法那样?
我希望的结果只是能够有效地查看员工参与并工作的所有项目贡献(及其类型),以及查看项目的所有贡献者和贡献者类型。
在SQL中,向多对多表中添加关系类型是否是一种不好的做法?
这个问题的出现是因为在设计数据库表时,有人提出了两种不同的方法来存储贡献类型。一种方法是将贡献类型存储为字符串,并通过在贡献表中添加一个字符串列来表示贡献类型。另一种方法是将贡献类型存储为数字,并通过在贡献表中添加一个数字列来表示贡献类型。
这个问题的解决方法是:
1. 将贡献类型存储为字符串,并在贡献表中添加一个字符串列来表示贡献类型。这种方法可以防止拼写错误,并且更容易阅读。可以通过在字符串列上添加检查约束来防止拼写错误。
2. 将贡献类型存储为数字,并在贡献表中添加一个数字列来表示贡献类型。这种方法可以节省磁盘空间,并且可以通过将贡献类型作为数字引用到一个贡献类型表中来避免拼写错误。这个贡献类型表可以在贡献表中添加一个外键参考,并在贡献类型表中添加一个唯一约束来确保贡献类型的唯一性。
总之,无论是使用字符串还是数字,都必须避免拼写错误。如果贡献类型的数量较少且稳定,可以使用检查约束或枚举类型。如果预计贡献类型的数量会增加,可以使用外键参考一个贡献类型表,并在贡献类型表中添加一个唯一约束。
以下是一个示例代码:
-- 创建贡献类型表 CREATE TABLE ContributionTypes ( ContributionTypeId INT PRIMARY KEY, ContributionTypeName VARCHAR(50) UNIQUE ); -- 创建贡献表 CREATE TABLE Contributions ( EmployeeId INT, ProjectId INT, ContributionTypeId INT, CONSTRAINT FK_Contributions_Employee FOREIGN KEY (EmployeeId) REFERENCES Employees (EmployeeId), CONSTRAINT FK_Contributions_Project FOREIGN KEY (ProjectId) REFERENCES Projects (ProjectId), CONSTRAINT FK_Contributions_ContributionType FOREIGN KEY (ContributionTypeId) REFERENCES ContributionTypes (ContributionTypeId), CONSTRAINT PK_Contributions PRIMARY KEY (EmployeeId, ProjectId, ContributionTypeId) );
通过上述代码,可以创建一个贡献类型表和一个贡献表,并通过外键约束来确保数据的完整性和一致性。