共享主键、外键、关联表在表达对象关联关系时的微妙语义差别

本文探讨了数据库中外键与关联表的不同应用场景。外键用于建立表间的强参照关系,适用于描述父子关系;关联表则适合表达更为宽松的关联关系,如一对多或多对多的情况。此外还讨论了共享主键的使用场景。

外键作为一种做用在表上的参照性约束,自然是要求表中所有纪录必须遵守此约束,而如果允许外键列为空,那就等同打开一个扇后门,允许某些数据不必遵守这一约束。这是与外键的初衷是相违背的。如果说:两张表之间的数据存在一种“部分”参照关系,也就是说的如果A表中有部分数据是需要参照B表中的数据,而有的则可以没有参照,那么,使用关联表对两张表之间的数据进行关联可能是更好的选择!这种关系的微妙之外在于,它即表明两表数据之间有“一定的”参照关系,但又不是必须的,它们也可以没有这种参照,显然,这表达的是一种更为宽松的关系,体现到对象间的关系上时,它可以表达一般意义上的关联关系,即A可以依赖于B(为至多个都可以),反之亦然。它不像外键约束,我们知道,外键约束最适用于描述的是父子关系:即:每一个孩子都必定有一个父亲(多对一,且非空),每一个父亲可能有0至多个孩子(一对多,可空。注:考虑到没有孩子的人不可以称之为父亲,因此说用父子关系形容这一类对象间关系也有一点点为妥)

对于关联表来说,除去上面所讲到的情况,通过给关联表中的外键设定唯一约束,还可以表达出“部分的”一对一关系,也即optional one-to-one,典型的例子就是桌子员工分配关系!

对于共享主键,可能描述的是最为严格的关系了:一对一,且双方均不得为空,并且同时存在,同时消亡,有同样的生命周期。像Thread和Subject Post之间的关系一样。

最后简单归纳如下:

对于共享主键方式:单向/双向一对一关系(关联双方均不可为空且有一致的生命周期)

外键方式:单向多对一(一端不能为空),单/双向一对一(通过对外键加唯一约束来模拟,同样外键所在一端不能为空)

关联表:双向一对一,一对多/多对一,(特别是单向一对多建议使用关联表),多对多

### 数据库中主键关联的概念与用法 #### 主键(Primary Key) 主键是一种特殊的约束条件,用于唯一标识数据库中的每一行记录。它由一个或多个列组成,其值在整个范围内必须是唯一的,并且不允许为空值。通过设置主键,可以确保每条记录具有独一无二的身份标识。 在 MySQL 中,可以通过 `PRIMARY KEY` 关字定义主键[^1]。例如: ```sql CREATE TABLE Users ( UserID INT PRIMARY KEY, UserName VARCHAR(50), Email VARCHAR(100) ); ``` 上述代码创建了一个名为 `Users` 的,其中 `UserID` 列被指定为主键。 #### 超与候选的关系 超是指能够唯一标识中某一行的一个或一组属性集合。如果从某个超中移除某些属性后仍然能唯一标识该行,则这个较小的集合称为候选。最终,在这些候选中选定一个作为主键[^2]。 #### (Foreign Key) 是用来建立加强两个之间关系的一种机制。它是当前中指向其他主键的一列或多列组合。允许存在重复值或者 NULL 值,这取决于具体的设计需求。设定的主要目的是维护参照完整性,即防止非法的数据操作破坏不同之间的逻辑联系[^3]。 下面是一个关于如何在上应用的例子: 假设我们有两个格:一个是存储用户的 `Users` ;另一个是保存订单信息的 `Orders` 。我们可以这样构建它们之间的关系: ```sql CREATE TABLE Orders ( OrderID INT PRIMARY KEY, UserID INT, Amount DECIMAL(10, 2), FOREIGN KEY (UserID) REFERENCES Users(UserID) ); ``` 在这个例子中,`Orders` 里的 `UserID` 字段作为一个连接到 `Users` 上的 `UserID` 主键。这种结构保证了每一个订单都对应着一位实际存在的用户。 #### 关联 当两张通过某种方式相互链接起来就形成了所谓的“关联”。最常见的形式是一对多关系(one-to-many),比如上面提到过的单个客户可能拥有多个订单的情况。除此之还有一对一(one-to-one) 多对多(many-to-many) 这两种基本类型的关联模式。 实现一对多关联通常只需要在一个子实体集中加入父实体集的主键作为即可完成配置过程。而对于更复杂的场景如多对多则往往需要引入额的中间件来辅助处理双方间的映射情况。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值