【问题标题】:Can a foreign key act as a primary key?外键可以作为主键吗?
【发布时间】:2013-07-12 05:55:48
【问题描述】:

我目前正在为我们团队的项目设计一个数据库结构。我目前有这个问题:是否可以让外键充当另一个表的主键?

以下是我们系统数据库设计的一些表格:

user_accounts
students
guidance_counselors

我想要发生的是user_accounts 表应该包含学生用户和辅导员用户的 ID(假设是系统的登录凭据)和密码。简而言之,students 和guidance_counselors 表的主键也是user_accounts 表的外键。但我不确定是否允许。

另外一个问题是:一个student_rec表也存在,它需要一个student_number(也就是user_accounts表中的user_id)和一个guidance_counsellor_id(也就是表中的user_id) user_accounts) 的每条记录。如果学生和辅导员的ID都来自user_accounts table,我将如何设计student_rec表?为了将来参考,我如何手动将其编写为 SQL 代码?

这一直困扰着我,我找不到任何具体或确定的答案来回答我的问题。

【问题讨论】:

  • 虽然您的问题的答案是“是的,主键也可以充当外键”,但我的建议是避免这种情况。可以使用离散的主键和外键来表示相同的关系,并且重载具有多个职责的列可能会导致困难。例如,如果主键也是一个标识列,或者是通过 ORM 使用 GuidComb 策略自动分配的,那么您可能会查看两个或多个事务而不是一个。单一职责原则也适用于数据库设计。

标签: mysql sql database foreign-keys primary-key


【解决方案1】:

当然。这是一种称为supertyping 表的常用技术。与您的示例一样,这个想法是一个表包含实体的超集并具有描述一般实体的通用属性,而其他表包含具有特定属性的这些实体的子集。这与面向对象设计中的简单类层次结构没有什么不同。

对于第二个问题,一个表可以有两列,它们分别是同一个表的外键。当数据库构建查询时,它会连接另一个表两次。为了在 SQL 查询中进行说明(不确定 MySQL 语法,我已经很长时间没有使用它了,所以这是专门的 MS SQL 语法),您可以在选择数据时为该表指定两个不同的别名。像这样的:

SELECT
    student_accounts.name AS student_name,
    counselor_accounts.name AS counselor_name
FROM
    student_rec
    INNER JOIN user_accounts AS student_accounts
      ON student_rec.student_number = student_accounts.user_id
    INNER JOIN user_accounts AS counselor_accounts
      ON student_rec.guidance_counselor_id = counselor_accounts.user_id

这实际上将student_rec 表与user_accounts 表合并两次,每列一次,并在合并时分配两个不同的别名以便区分它们。

【讨论】:

  • 这只是列集既是 FK 又是 PK 的一种情况。每种键都是相互独立定义的。
【解决方案2】:

是的,应该没有问题。外键和主键相互正交,一列或一组列既可以作为该表的主键(这要求它们是唯一的),也可以与主键/唯一约束相关联在另一个表中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-14
    • 1970-01-01
    • 1970-01-01
    • 2010-10-19
    相关资源
    最近更新 更多