我有两个表:
- User(用户名,密码)
- Profile(profileId,性别,出生日期,...)
目前我采用的方法是:每个Profile记录都有一个名为“userId”的字段,作为外键链接到User表。当用户注册时,他的Profile记录会自动创建。
我对我的朋友的建议感到困惑:将“userId”字段作为外键和主键,并删除“profileId”字段。哪种方法更好?
我有两个表:
目前我采用的方法是:每个Profile记录都有一个名为“userId”的字段,作为外键链接到User表。当用户注册时,他的Profile记录会自动创建。
我对我的朋友的建议感到困惑:将“userId”字段作为外键和主键,并删除“profileId”字段。哪种方法更好?
外键几乎总是“允许重复”,这使它们不适合作为主键。
相反,找到一个可以唯一标识表中每个记录的字段,或者添加一个新字段(自增整数或GUID)作为主键。
唯一的例外是具有一对一关系的表,其中链接表的外键和主键是相同的。
主键始终需要是唯一的,如果表是一对多关系,则外键需要允许非唯一值。如果表通过一对一关系连接,则使用外键作为主键是完全可以的,而不是一对多关系。如果您希望相同的用户记录具有可能拥有多个相关配置文件记录,请选择单独的主键,否则请坚持现有方案。
是的,将主键设置为外键是合法的。这是一种罕见的结构,但适用于以下情况:
1:1关系。由于不同的权限和特权仅适用于表级别(截至2017年,这样的数据库会很奇怪),因此两个表不能合并成一个。
1:0..1关系。个人资料可能存在也可能不存在,这取决于用户类型。
性能是一个问题,并且设计作为分区:个人资料表很少被访问,托管在单独的磁盘上或具有与用户表不同的分片策略。如果底层存储是列式存储,则没有意义。
profileID
作为表Profile
的主键。这取决于业务和系统。
如果您的userId是唯一的,并且始终是唯一的,那么您可以使用userId作为主键。但是,如果您想要扩展您的系统,这将使事情变得困难。我建议您在用户表中添加一个外键,与档案表建立关系,而不是在档案表中添加一个外键。
简短回答:取决于情况……在这种特定情况下,可能是可以的。然而,专家们几乎每次都会建议不要这样做,包括你的情况。
为什么呢?
当键是外键(来自另一个表)时,在表中很少是唯一的。例如,一个项目ID在ITEMS表中可能是唯一的,但在ORDERS表中可能不是,因为同一类型的项目很可能存在于另一个订单中。同样,订单ID在ORDERS表中可能是唯一的(可能),但在其他表中如ORDER_DETAILS中却不是,因为一个具有多个行项目的订单可以存在,并且要查询特定订单中的特定项目,您需要将两个FK(order_id和item_id)连接起来作为此表的PK。
我不是数据库专家,但如果您可以逻辑上证明自动生成值作为您的PK,那么我会这样做。如果这不可行,则两个(或更多)FK的串联可以作为您的PK。但是,我无法想到任何情况下单个FK值可以被证明为PK的情况。
虽然这并不完全适用于问题的情况,但由于我在寻找其他信息时进入了这个问题,并阅读了一些评论,我可以说,在一个表中只有一个FK并获得唯一值是可能的。 您可以使用具有类别的列,该列只能分配1次,它几乎像ID一样工作,但是如果您想要使用唯一的分类值来区分每个记录,则可以在此情况下完成。