我通常不熟悉MySQL或数据库,所以这里有一个我的数据模型(表{cols}]),以便使我的问题连贯一致:
Domains{id, name}
注意:此处的"域"不是指web域
Subdomains{id, domain_id, name}
Items{id, subdomain_id, name}
SubdomainsItems{id, subdomain_id, item_id}
没有domain_id列
我的Items Controller
有一个函数fetchWithin($domains, $subdomains)
,它最终应该只执行两个复杂的find()
中的一个。这是我无法摆脱的肤色。
从程序上讲,我可以实现这一点,但我很确定更好的方法是通过巧妙的连接等。唉,目前这是一种方法:
如果$domains
为空,则只执行步骤2&3,否则:
foreach($domains as $d)
:得到Subdomains
的所有行,其中Subdomain.domain_id
=Domains.id
为$subdomains
foreach($subdomains as $s)
:去获取SubdomainsItems
的所有行,其中SubdomainsItems.subdomain_id
=Subdomains.id
为$item_ids
foreach($items_ids as $i)
:获取Items
的所有行,其中Items.id
=SubdomainsItems
。items_id
这是可行的,但我认为这消除了关系数据库的功能,我想了解应该如何(即,根据Cakephp约定或简单地通过MySQL语句实现这一点)。
非常感谢您的帮助,我尝试学习SQL更复杂的方面,但它超出了我的想象。:S
了解必要的查询
根据问题中描述的结构,所需的查询类型为:
SELECT
*
FROM
items
LEFT JOIN
subdomains ON (
items.subdomain_id = subdomains.id
)
LEFT JOIN
domains ON (
subdomains.domain_id = domains.id
)
WHERE
domains.name = "foo"
AND
subdomains.name IN ('some', 'list', 'of', 'subdomains');
与问题中的逻辑相比,这将所有三个表连接在一起,并允许按域名或子域名称(或涉及任何或所有三个表格的任何其他标准)查找所有项目;一般来说,如果你想在数据库中查找数据并使用多个查询来获取数据,有一种更有效的方法可以做到
实现查找调用
有很多方法可以使用Cake创建这样的查询。最简单的方法可能是使用联接键并明确指定联接:
function fetchWithin($domains = null, $subdomains = null) {
$params = array(
'joins' => array(
array('table' => 'subdomains',
'alias' => 'Subdomain',
'type' => 'LEFT',
'conditions' => array(
'Subdomain.id = Item.subdomain_id',
)
),
array('table' => 'domains',
'alias' => 'Domain',
'type' => 'LEFT',
'conditions' => array(
'Domain.id = Subdomain.domain_id',
)
)
)
);
if ($domains) { // single value or an array
$params['conditions']['Domain.name'] = $domains;
}
if ($subdomains) { // single value or an array
$params['conditions']['Subdomain.name'] = $subdomains;
}
return $this->find('all', $params);
}