2011-02-16 45 views
1

哎呀,标题是一口。我再次发现自己不知道如何问这个问题,所以我会用一个例子。假设你正在制作一款包含物品的游戏。物品有效果,奖金和要求。最好的mysql查询选择多个行,每个行需要多个子表的多个关联行

因此,items表中的每条记录在效果表,奖金表和需求表中都有多个子记录。

而你想要选择100个最近的项目,包括他们在游戏中显示的所有效果,奖金和要求。

什么是最优化的方式来完成此操作。它可以在一个查询中完成吗?而且这是否实际?谢谢。

+0

为什么你不想使用JOINS?这些桌子太大了吗? `SELECT * FROM items JOIN影响物品.ID JOIN加分物品.ID JOIN要求ON物品。ID ORDER BY items.date DESC LIMIT 100` – criticus 2011-02-16 04:33:27

+0

我需要几个效果,奖励和请求PER项目。我的理解是,这会为每件物品返回1点效果,1点奖励和1点需求。我错了吗? – Ryan 2011-02-16 04:42:30

+0

它将返回所选项目的所有效果,奖金和要求。如果你有没有效果,奖金或要求的物品,你应该使用LEFT JOIN – criticus 2011-02-16 04:51:20

回答

1

它可以在一个查询中实现,但它会相当大,并会有很多倍增。在一个查询中做这种事情的唯一真正理想的时间是如果存在“有一个”关系。即一个项目有一个效果,可以通过简单的连接来完成,而一个项目只返回一个演出。

以你给出的一个简单的例子。你有2个项目,每个项目有3个影响,有多对多的关系。

SELECT item.*, effect.* 
FROM item 
JOIN item_effect ON item.id = item_effect.item_id 
JOIN effect ON effect.id = item_effect.effect_id 

回报可能是:

item1 effect1 
item1 effect2 
item1 effect3 
item2 effect2 
item2 effect3 
item2 effect4 

然后,你将不得不通过循环和组所有项目的重新走到一起。通过与需求和修饰符的关系,查询会变得更大,但仍然相当有条理。

您可以使用某种类型的ORM(对象关系映射)。这可以使您的代码更具可读性,例如使用来自Kohana的ORM的语法。

$items = ORM::factory('item')->find_all(); 
foreach($items as $item) { 
    $effects = $item->effects->find_all(); 
    $bonuses = $item->bonuses->find_all(); 
    $requirements = $item->requirement->find_all(); 
} 

但是,对于100个项目的例子,你建议这将是301个查询。

如果您在网页上显示此信息,则分页(显示100的1-20)将降低该数字。

你使用的方法真的取决于你的情况。需要考虑的事情:

  • 多久将这种使用
  • 他们真的需要看到100个项目一次
  • 他们需要看到的所有关系的一个(点击一个项目以查看其效果等)
-1

您应该能够待办事项这样的事情...

SELECT `users`.`nickname` , `events`.`nickname` 
FROM `users` , `events` 
WHERE `events`.`aid` = `users`.`aid` 
GROUP BY `events`.`nickname` 

为了澄清,events.aid是uniq的ue用户的ID。因此,当我获取所有这些记录并按事件对它们进行分组时,我会得到所有唯一事件昵称以及创建它们的用户的列表。 enter image description here