假设我有这些模型:
TABLE trainers (
id -- PK
-- many fields here...
);
TABLE players (
id -- PK,
trainer_id -- FK,
-- many fields here...
);
TABLE tournaments (
id -- PK,
player_id -- FK
-- many fields here...
);
TABLE games (
id -- PK,
tournament_id -- PK,
-- many fields here...
);
TABLE goals (
id -- PK,
game_id -- FK
-- many fields here...
);
很多时候(使用ORM)我有复杂的查询,如:
SELECT
-- many fields here...
"goal"."id",
"goal"."game_id",
-- many fields here...
"game"."tournament_id" AS "game__tournament_id",
-- many fields here...
"game__tournament"."id" AS "game__tournament__id",
"game__tournament"."player_id" AS "game__tournament__player_id",
"game__tournament__player"."trainer_id" AS "game__tournament__player__trainer_id",
-- many fields here...
"game__tournament__player"."id" AS "game__tournament__player__id",
-- many fields here...
FROM
"goals" AS "goal"
LEFT JOIN "games" AS "game" ON ( "game"."id" = "goal"."game_id" )
LEFT JOIN "tournaments" AS "game__tournament" ON ( "game__tournament"."id" = "game"."tournament_id" )
LEFT JOIN "players" AS "game__tournament__player" ON ( "game__tournament__player"."id" = "game__tournament"."player_id" )
WHERE
( "goal"."game_id" IN ( 1, 2, 3 ) )
,所有这些只是因为我需要在我的服务逻辑中与goals
一起工作的trainer_id
。
你有什么建议?
我应该在goal
表中为trainer_id
创建一个列吗?这种重复不是很糟糕吗?
是否有其他方法来避免复杂的查询?
好吧,它可能违反了依赖于完整表结构的正常形式之一。
然而,数据库的一个方面是,遵守严格的设计有时是不可行的。
多个频繁连接的情况在复杂性和速度方面都是相当不合理的。
此外,您很幸运,因为目标或多或少是静态信息。它是由特定的玩家在特定的游戏中完成的,之后关于这个目标的信息通常不会改变。
因此,我可能要做的是创建另一个查找表,其中包含您经常使用的所有相关信息,已经插入。
Create table goal_lookup
( Id, goal_id, player_id, trainer_id, ...);
还请注意,如果你使用完整的参考球员表,在你的原始设计,然后,除非你记录教练与目标,你可能会得到错误的教练ID为目标,当球员的教练已经改变了,因为游戏!