Database 外键作为主键可以吗?

Database 外键作为主键可以吗?,database,foreign-keys,primary-key,Database,Foreign Keys,Primary Key,我有两张桌子: 用户(用户名、密码) 配置文件(配置文件ID、性别、出生日期等) 目前我正在使用这种方法:每个概要文件记录都有一个名为“userId”的字段作为外键,该字段链接到用户表。当用户注册时,会自动创建其配置文件记录 我对我朋友的建议感到困惑:将“userId”字段作为外键和主键,并删除“profileId”字段。哪种方法更好?我不会那样做。我将保留profileID作为表Profile 外键只是两个表之间的引用约束 有人可能会争辩说,主键作为从其他表引用它的任何外键的目标是必要的。

我有两张桌子:

  • 用户(用户名、密码)
  • 配置文件(配置文件ID、性别、出生日期等)
目前我正在使用这种方法:每个概要文件记录都有一个名为“userId”的字段作为外键,该字段链接到用户表。当用户注册时,会自动创建其配置文件记录


我对我朋友的建议感到困惑:将“userId”字段作为外键和主键,并删除“profileId”字段。哪种方法更好?

我不会那样做。我将保留
profileID
作为表
Profile

外键只是两个表之间的引用约束

有人可能会争辩说,主键作为从其他表引用它的任何外键的目标是必要的。外键是任何表(不一定是该表的候选键,更不用说主键)中的一个或多个列的集合,该表可能包含在某个其他表的主键列中找到的值。所以我们必须有一个主键来匹配外键。 还是我们必须?主键/外键对中主键的唯一用途是提供一个明确的连接,以保持关于保存被引用主键的“外键”表的引用完整性。这可以确保外键引用的值始终有效(如果允许,也可以为null)


外键几乎总是“允许重复”,这会使它们不适合作为主键

相反,请查找唯一标识表中每条记录的字段,或添加一个新字段(自动递增整数或GUID)作为主键


唯一的例外是具有关系的表,其中链接表的外键和主键是相同的。

主键始终需要唯一,如果表是一对多关系,则外键需要允许非唯一值。如果表是通过一对一关系(而不是一对多关系)连接的,那么使用外键作为主键是完全正确的。如果您希望同一用户记录有可能包含多个相关的配置文件记录,请使用单独的主键,否则请使用您现有的记录。

这取决于业务和系统


如果您的userId是唯一的并且将一直是唯一的,那么您可以使用userId作为主键。但是,如果你想扩展你的系统,这将使事情变得困难。我建议您在表用户中添加外键以与表配置文件建立关系,而不是在表配置文件中添加外键。

通常认为一对一关系是不好的做法。这是因为您可以将数据表示在一个表中,并获得相同的结果

但是,在某些情况下,您可能无法对正在引用的表进行这些更改。在这种情况下,使用外键作为主键没有问题。由自动递增的唯一主键和外键组成的复合键可能会有所帮助


我目前正在开发一个系统,在这个系统中,用户可以登录并生成用于应用程序的注册码。由于一些原因,我无法简单地将所需的列添加到users表中。因此,我将使用代码表进行一对一的操作。

是的,在这些表之间存在一对一关系的情况下,外键可以是主键。

是的,将主键作为外键是合法的。这是一种罕见的构造,但适用于:

  • 1:1的关系。这两个表不能合并在一个表中,因为不同的权限和特权仅适用于表级别(截至2017年,这样的数据库将是奇数)

  • 1:0..1的关系。配置文件可能存在,也可能不存在,具体取决于用户类型

  • 性能是一个问题,设计就像一个分区:配置文件表很少被访问,托管在单独的磁盘上,或者与用户表相比具有不同的分片策略。如果下划线存储是柱状的,则没有意义


    • 简短回答:取决于。。。。在这种特殊情况下,这可能是好的。然而,专家们几乎每次都会提出反对意见;包括你的案子

      为什么?

      当键是相关表的外来项(源自另一个表)时,它们在表中很少是唯一的。例如,项目ID在ITEMS表中可能是唯一的,但在ORDERS表中可能不是唯一的,因为同一类型的项目很可能存在于另一个订单中。同样,订单id在ORDERS表中可能是唯一的(可能),但在order_DETAILS等其他一些表中可能不是唯一的。在order_DETAILS中,可以存在具有多行项目的订单,要查询特定订单中的特定项目,需要将两个FK(order_id和item_id)串联起来作为此表的主键


      我不是DB专家,但如果你能从逻辑上证明有一个自动生成的值作为你的PK,我会这么做。如果这不实用,那么两个(或者更多)FK的串联可以作为您的PK。但是,我想不出任何一种情况下,一个FK值可以被证明是PK。

      实体框架(首先使用代码)为ZeroRoOne(和一对一)关系生成该值。所以这是可能的。这是最好的方式。。。这是另一个问题。但它是有效的。我在创建自己的数据库时从来没有这样做过(但我甚至从来没有想过)。由两个外键组成的复合主键对于实现多对多关系也非常好。@rezadru:我绝对不会不同意rightfold,但是代理键几乎总是一个更好的选择。关于外键,没有任何规定它是1对多(或“允许重复”的书面形式)。关键约束和唯一性在数据库中是两个独立的概念,可以轻松使用