关于关系型数据库的设计,一般有两种主要方式:
使用自然键时,你使用给定的键:一个项目通过其项目编号来识别,一个用户通过其登录名或编号来识别,等等。这通常会导致复合(或组合)键:
- project (project_no, name, ...)
- user (user_name, first_name, last_mname, ...)
- project_user (project_no, user_name, role, ...)
表project_user具有复合键:项目编号加上用户名唯一地标识记录,告诉我们谁在哪个项目上工作。
使用ID时,通常会添加一个仅用于链接记录且对用户没有意义的技术ID:
- project (project_id, project_no, name, ...)
- user (user_id, user_name, first_name, last_mname, ...)
- project_user (project_user_id, project_id, user_id, role, ...)
表包含相同的字段以及ID,并且需要与自然键相同的唯一和非空约束以及关于ID的约束。
当然,在project_user中,只有在需要引用该参考的任何表格时才需要project_user_id。但通常会给每个表格都分配一个ID,无论是否需要,只是为了使它们看起来都一样(并且这些ID在以后可能会用到)。
乍一看,基于ID的数据库似乎只是更多的工作和索引,并没有什么收益,但情况并非如此。经常选择ID概念,因为它提供了更多的自由。例如:如果项目编号可以更改会发生什么?使用自然键,项目编号存在于许多表格中,并且必须以某种级联方式进行更新,这可能变得非常繁琐。在ID数据库中,您只需在一个位置更改项目编号即可。
如果项目编号只在公司内部唯一,那会发生什么?在基于ID的数据库中,您需要将company_id添加到projects表中,并在company_id和project_no上添加唯一索引即可完成。使用自然键,则需要在主键中添加公司编号(ILN?人造编号?),并且必须在所有子表中引入该编号。因此:当使用自然键设计数据库时,必须仔细考虑以获得稳定的自然键-有时没有,那么您就必须发明一些。对于ID,您不太关心字段是否可以更改。因此,基于ID的数据库更容易实现。
然后是层次结构。假设数据库中有几个公司,每个公司都有自己的物品和仓库。
自然键:
- 公司(company_code,name,...)
- 商品(company_code,item_no,name,...)
- 仓库(company_code,warehouse_no,address,...)
- 库存(company_code,warehouse_no,item_no,amount,...)
IDs:
- 公司(company_id,name,...)
- 商品(item_id,item_no,name,company_id,...)
- 仓库(warehouse_id,address,company_id,...)
- 库存(stock_id,warehouse_id,item_id,amount,...)使用ID概念,您不需要在股票表中再次命名company_id,因为它是从父表已知的。将其存储在那里甚至是多余的,而在自然键概念中是必需的,因为它是复合键的一部分,没有它我们将失去与其父表的链接。有些人认为这种纯净性是ID概念相对于自然键的巨大优势。但是,它也会带来一个缺点。在自然键数据库中,保证公司物品在公司的仓库中,因为公司是库存表的关键部分。使用ID概念,链接的仓库记录可能属于公司1,而链接的物品记录可能属于公司2。由于某些错误的插入语句引起的不一致数据,DBMS无法防止我们。使用自然键就不会出现此类错误。
如果我想知道一家公司有多少库存,我只需使用自然键从库存选择即可。但是,在ID数据库中,我需要从库存加上另一个表来获取公司。
当数据库基于ID时,你可能会遇到涉及许多更多表的查询。到目前为止,我还没有看到ID数据库比自然键数据库表现更好。但是,我确实看到自然键数据库远远优于ID数据库。这可能是因为我主要看到的是具有许多层次的大型数据库。
关于您的数据库:假设项目ID和用户ID仅是技术内部编号,则它似乎是ID基础数据库-否则,您的数据库将是混合概念(自然项目号,自然用户ID,ProjectUserBooleanAttribute的技术ID)。因此,您的问题实际上与是否使用复合键无关。
PUAT_ID和UserID都必须在ProjectUserBooleanAttribute中,它们不为空,并且您应该对它们进行唯一约束(唯一索引)。因此,它们具有所有主键所需的特性,无论您是否称其为“主键”。添加技术ID仅仅是为了外观而已。它并没有真正改变任何东西。概念保持不变。
在自然键概念中,您会将字段作为主键。但是,您将没有PUAT_Id,而是某个复合键(ProjectId加上AttributeType?)。
在技术ID概念中,您不会将其作为主键,而是使字段非空并添加唯一约束(这使其成为关键字,只是不称为"primary")。然后,要么添加技术ID作为主键,要么将表格设置为没有ID,因此没有主键。这无关紧要。如果有人要求关键字,请给他们ID,如果不需要,则可以不使用它。只要其他表不需要它,它就是多余的。