我正在设计一个db表,它将保存用户最喜欢的食物清单。 我使用以下架构创建了最喜欢的表
id, user_id, food_id
user_id和food_id将是链接到另一个表的外键。
我只是想知道这是否有效且可扩展,如果用户有多个喜欢的东西,那么它将需要多行数据。
即。用户有5个收藏的食品,然后它将包含五行以保存该用户的清单。
效率这么高吗?可扩展?什么是优化此架构的最佳方法?
提前thnx !!!答案 0 :(得分:5)
tldr; 这称为"join table",是在关系数据库中建模MM关系的正确且可扩展方法。(根据使用的约束,它也可以模拟1 “无NULL FK”模式中的-M / 1-1关系。)
但是,我认为 id
列应该省略,以便该表仅 user_id, food_id
。在这种情况下,PK将为(user_id, food_id)
。
与其他表格不同,surrogate (aka auto-increment) PKs有时会被认为是,代理PK通常只会在连接表中添加混乱,因为它具有非常自然的复合PK。
虽然在这种情况下PK本身是复合的,但每个“连接”表仅与PK的一部分相关。根据执行的查询,在food_id
或(food_id, user_id
上添加覆盖索引可能也是有益的。
答案 1 :(得分:2)
消除代理密钥:除非代理密钥id
有specific reason,否则请将其从表格中排除。
微调索引:此时,您只需要一个复合主键,它是两个外键的组合。 PK字段的顺序应该是什么?
{user_id, food_id}
。{food_id, user_id}
。{user_id, food_id}
上的PK和{food_id, user_id}
上的索引。请注意InnoDB tables are clustered,它消除了(在这种情况下是“不必要的”)表堆。然而,上面讨论的二级索引不会导致双重查找(因为它完全covers查询),也没有隐藏的PK字段开销(因为它将相同的字段索引为PK,只是顺序相反)。
有关设计联结表的更多信息,请查看this post。
答案 2 :(得分:1)
我认为,您可以通过以下方式优化表格:
答案 3 :(得分:0)
创建以下三个表将带来有效的设计。
users : userId, username, userdesc
foods : foodId, foodname, fooddesc
userfoodmapping : ufid, userid, foodid, rowstate
rowstate的意义在于,如果将来的用户不喜欢那种食物,其状态将变为-1
答案 4 :(得分:0)
我的opnion有2个选项:
摆脱ID字段,但在这种情况下,将其他密钥(合并)作为主键
将您的ID密钥保存为表格的主键。
在任何一种情况下,我认为这是一种正确的方法。一旦你遇到效率低下的问题,那么你可能会考虑如何加载部分表或任何其他技术。这样做现在可以。