数据库表中可否没有主键,只有外键

外键确保表之间的关系。

保证主键在表中是唯一的。

订单表没有主键,因此无法唯一标识订单。

客户表没有主键,因此无法唯一标识客户。

这就是洞。

表必须有主键。

数据库中的主键、超建、候选键、外键是什么?

如果你问的是数据库,我刚开始工作的时候就很困惑。
但我会告诉你我掉进的陷阱,以确保你脚踏实地。

当时我刚刚接手一个老系统,有很多表。
有一个名为users的表,用于存储有关用户的信息。
一开始主键就随便按id自增,以为这样就简单省事了。
结果后来业务扩展的时候,需要给用户名加上后缀。
ID 仍在自动递增,用户名存在冲突。
经过长时间的研究,我需要添加一个唯一索引。
你看,主键选得好的话,直接影响到以后的维护。
后来我修改系统的时候强制规定主键不能随意选择。
需要选择长期不变的,比如用手机号码或者身份证号码作为主键。
即使必须考虑唯一性约束,也避免了很多麻烦。

当时我并没有真正区分超级键和候选键。
后来我在采购订单中弄清楚了。
订单表有order_id、user_id、order_date。
起初我认为 order_id 加上 user_id 是一个很好的关键,因为一个用户每天可以下多个订单,仅 order_id 是不够的。
后来发现单凭order_id就可以唯一标识一个订单,是一个候选键。
候选键的属性比超级键少,因此 order_id 是更好的选择。
可以有多个候选键,但只有一个主键。
我们最终选择order_id作为主键,因为它是唯一的,不需要更改。

外键更方便。
我之前参与的项目有一个订单表和一个产品表。
订单表中的product_id是产品表标识符。
该product_id是orders表中的外键。
因为我没有对这个外键设置约束,所以我导入了一次数据。
结果,订单表引用了不存在的product_id,并且导入崩溃了。
后来学好了,建表的时候写了 FOREIGN KEY (product_id) REFERENCES products(id) ON DELETE CASCADE 。
这样,如果产品表中删除了某个产品,则订单表中引用该产品的订单也会自动删除,保证了数据的一致性。

你看,这些概念看似抽象,但如果使用不当,真的会造成大问题。
当时,我只是缺乏经验。
现在在处理项目时,主键和外键约束都是硬编码的,以避免发生意外。
以后创建数据库的时候,切记不要随意选择主键,并且一定要添加外键约束,以免以后出现问题。