MySQL表 - 设计高效表

时间:2012-11-28 06:51:18

标签: mysql sql database database-design

我正在设计一个db表,它将保存用户最喜欢的食物清单。 我使用以下架构创建了最喜欢的表

id, user_id, food_id

user_id和food_id将是链接到另一个表的外键。

我只是想知道这是否有效且可扩展,如果用户有多个喜欢的东西,那么它将需要多行数据。

即。用户有5个收藏的食品,然后它将包含五行以保存该用户的清单。

效率这么高吗?可扩展?什么是优化此架构的最佳方法?

提前thnx !!!

5 个答案:

答案 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)

消除代理密钥:除非代理密钥idspecific reason,否则请将其从表格中排除。

微调索引:此时,您只需要一个复合主键,它是两个外键的组合。 PK字段的顺序应该是什么?

  • 如果您的应用程序主要执行以下查询:“对于给定用户,给我食物”,则PK应为{user_id, food_id}
  • 如果主要查询是“给定食物,请给我用户”,那么PK应为{food_id, user_id}
  • 如果两个查询“方向”都很常见,请添加一个UNIQUE INDEX,其字段与PK相同,但方向相反。因此,您将{user_id, food_id}上的PK和{food_id, user_id}上的索引。

请注意InnoDB tables are clustered,它消除了(在这种情况下是“不必要的”)表堆。然而,上面讨论的二级索引不会导致双重查找(因为它完全covers查询),也没有隐藏的PK字段开销(因为它将相同的字段索引为PK,只是顺序相反)。

有关设计联结表的更多信息,请查看this post

答案 2 :(得分:1)

我认为,您可以通过以下方式优化表格:

  1. 作为与2个foreighkeys的关系表,您不必使用“id”字段。
  2. 使用“innodb”引擎到你的桌子
  3. 将您的关系表命名为“user_2_food”,这将使其更加清晰。
  4. 尝试使用尽可能小的数据类型,即“smallint”优于“int”,并且不要忘记“UNSIGNED”属性。

答案 3 :(得分:0)

创建以下三个表将带来有效的设计。

users : userId, username, userdesc
foods : foodId, foodname, fooddesc
userfoodmapping : ufid, userid, foodid, rowstate

rowstate的意义在于,如果将来的用户不喜欢那种食物,其状态将变为-1

答案 4 :(得分:0)

我的opnion有2个选项:

  1. 摆脱ID字段,但在这种情况下,将其他密钥(合并)作为主键

  2. 将您的ID密钥保存为表格的主键。

  3. 在任何一种情况下,我认为这是一种正确的方法。一旦你遇到效率低下的问题,那么你可能会考虑如何加载部分表或任何其他技术。这样做现在可以。