我有3张桌子:
foo(id, ..., user_id)
bar(id, ...)
foo_bar(foo_id, bar_id)
我需要从'foo_bar'中选择一行,并检查记录是否属于特定用户。将'user_id'列添加到'foo_bar'表中是一种好习惯,这样我可以运行查询:
// 1 query only
$foobar = SELECT * FROM foo_bar WHERE foo_id = ? AND bar_id = ? AND user_id = ?
不是先查询“ foo”表来检查“ foo”记录是否属于用户,然后运行第二个查询来选择“ foo_bar”记录,而不是? 像这样:
// 2 queries
$userId = SELECT user_id FROM foo WHERE foo_id = ?;
if ($userId === $userIdToCompareTo) {
$foobar = SELECT * FROM foo_bar WHERE foo_id = ? AND bar_id = ?
}
这有意义还是通常通过更复杂的查询以另一种方式处理?
答案 0 :(得分:2)
不,您不应该。您应该使用join
查找值:
select . . .
from foo_bar fb join
foo f
on fb.foo_id = f.id
where f.user_id = ?;
数据建模的关键原则是您应该将数据仅存储在一个地方。也就是说,如果将user_id
存储在foo_bar
中,那么如果user_id
发生变化会怎样?还是删除foo
记录?
在某些情况下,您需要复制用户ID。特别是,如果用户ID 做了更改,则可能需要在创建记录时在user_id
上捕获foo_bar
。我之所以提出这一点,是因为重要的是要理解原理并了解它们何时不一定适用。