我有一个用户表和一个地址表。用户可以有许多地址,因此地址表条目具有用户的外键。
我的问题是:该用户可以有多个地址,但只能将一个地址标记为其主要地址(出于运输目的)。最好向名为“ main_address”的用户添加一个外键,以链接到其地址之一,或者向名为“ is_main”的地址表中添加一列(默认情况下,所有地址为0,主地址为1) ?更好的是,我指的是速度和存储方式:)
编辑:根据建议,我向用户添加了外键,但这是有问题的。如果用户和地址尚未在数据库中,则将导致循环依赖:没有地址就不能添加用户,没有用户就不能添加地址。谢谢大家!
答案 0 :(得分:1)
在user
表上具有外键是一种较干净的解决方案,它是可选的,以避免相互依赖性,以防止向其中任何一个添加记录。它避免了为用户避免使用多个主要地址的情况,减少了占用的空间,并使加入使用主要地址的信息的操作更加简单。
唯一性内置于外键设计中。使用“ is_main”设计时,最简单的预防措施是将字段1或设置为null(而不是1或0),然后将复合唯一键放在(user_id,is_main)上。然后要更改默认值,则必须将旧的默认值归零,然后将新的默认值设置为1。
外键字段大约占用4个字节(假设地址为int pk,而忽略了可为空性); is_main为用户可能拥有的每个地址占用至少1个字节...如果还有其他位字段,它可能会更小,但是空间问题确实微不足道。
使用默认地址获取用户
SELECT *
FROM user AS u
LEFT JOIN address AS a
ON u.main_address_id = a.address_id
WHERE u.user_id = ?
;
vs
SELECT *
FROM users AS u
LEFT JOIN address AS a
ON u.user_id = a.user_id
AND a.is_main = 1
WHERE u.user_id = ?
;
...... AND is_main = 1
看起来似乎很琐碎,在很多情况下是这样,但是在更复杂的查询中,这种情况可能意味着不愿意接受索引。
is_main设计的一个好处是:如果您已经有user_id但没有main_address_id,则可以通过仅从地址表中进行简单(无连接)选择来获取主要地址信息。