sql - 关联表中的组合键

标签 sql database

我知道对于关联实体,来自相邻实体的唯一标识符必须包含在关联实体中才能具有 PK-FK 约束。我们在 SQL DDL 命令中创建 PK-FK key 与其各自邻居之间的约束。

但是,在创建 SQL DDL 命令时,我们是否还必须为该关联表创建复合键(除了 PK-FK 键约束之外)?非常感谢帮助,谢谢。

最佳答案

我认为举个例子可以更清楚地说明您的问题,但如果我理解正确,您是在询问具有外键的实体是否必须在其主键中包含外键(使其成为复合主键)?

这取决于您要实现的目标,但答案通常是否定的。

  • 您正在使用代理键(与自然键相反),这意味着主键不是来自现实世界的值,而是任意唯一值,通常是整数序列。在下面的示例中,DBA 为 Teacher 制作了唯一标识符。和 Department在现实世界中不存在。

    CREATE TABLE Teacher
    (
      Teacher_ID int PRIMARY KEY, -- e.g., 000001
      Department_ID int FOREIGN KEY REFERENCES Department(Department_ID)
    );
    
    
    CREATE TABLE Department
    (
       Department_ID int PRIMARY KEY -- e.g., 000001
    );
    
  • 您使用的是自然键,但两个实体可以彼此独立存在。在下面的示例中,这意味着在现实世界中,可以取消分配教师,并且部门可以没有教师。

    CREATE TABLE Teacher
    (
       Teacher_SSN int PRIMARY KEY,  -- social security number
       Department_Name VARCHAR(255) FOREIGN KEY REFERENCES Department(Department_Name)
    );
    
    CREATE TABLE Department
    (
       Department_Name VARCHAR(255) PRIMARY KEY
    );
    
  • 您正在使用自然键,并且业务规则使得关联实体需要一个父项才能存在,但它有自己的自然主键(由一个简单的 NOT NULL 外键约束强制执行 key )。这意味着部门经理不能没有相应的部门而存在,但其唯一标识不是由部门定义的。

    CREATE TABLE DepartmentManager
    (
       Manager_SSN int PRIMARY KEY,
       Department_Name VARCHAR(255) NOT NULL FOREIGN KEY REFERENCES Department(Department_ID)
    );
    
    CREATE TABLE Department
    (
       Department_ID VARCHAR(255) PRIMARY KEY
    );
    

  • 问题的业务规则或领域是这样的,如果不使用父实体的主键作为关联实体的复合主键的一部分,则无法唯一地描述实体,并且您不想使用代理键。在下面的示例中,房间号“001”可能存在多次,因为有多个房间标记为“001”的建筑物,但如果我们将建筑物的名称包含在复合主键中,那么我们就有了一个唯一标识符。在这种情况下,Room被称为弱实体,并且Building是一个强实体。 ( More on that here. )

    CREATE TABLE Room
    (
       Room_Number int,
       Building_Name VARCHAR(255) FOREIGN KEY REFERENCES Building(Building_Name),
       CONSTRAINT pk_Room PRIMARY KEY (Room_Number,Building_Name)
    );
    
    CREATE TABLE Building
    (
       Building_Name VARCHAR(255) PRIMARY KEY
    );
    

关于sql - 关联表中的组合键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29585451/

相关文章:

mysql - 如何组合两个不相关的 SQL 查询

mysql - SQL:将未加密值与加密值进行匹配

mongodb - 建议何时/如何将数据保存到数据库,插入到 MongoDB 时

database - 如何找出 Oracle 10g 中哪些表访问最多或使用最频繁

c# - 有没有办法将值/文本/数据从表单传递到另一个表单

mysql - 获取主键链接到外键的所有表

用于聚合/串联的 SQL 查询

mysql - SQL - 创建连接在一起的多个表的 View

database - 在什么复杂度下多次旅行会超过对对象图的单个查询?

php - 如何在 MySQL 中存储 bool 数据类型?