1

我一般不熟悉 MySQL 或数据库,所以这是我的数据模型 (table{cols}]),以使我的问题连贯:

Domains{id, name} 注意:此处的“域”不是指网络域

Subdomains{id, domain_id, name}

Items{id, subdomain_id, name}

SubdomainsItems{id, subdomain_id, item_id} 没有 domain_id 列!

MyItems Controller有一个功能,fetchWithin($domains, $subdomains)最终应该只执行两个 complexish 之一find()。这是我无法克服的复杂。

以编程方式我可以实现这一点,但我很确定更好的方法是通过巧妙的连接等。唉,目前这是方法:

如果$domains为空,则只执行步骤 2&3,否则:

  1. foreach($domains as $d)Subdomains: 获取where Subdomain.domain_id= Domains.idas的所有行$subdomains
  2. foreach($subdomains as $s)SubdomainsItems: 去获取where SubdomainsItems.subdomain_id= Subdomains.idas的所有行$item_ids
  3. foreach($items_ids as $i)Items:获取where Items.id=的所有行SubdomainsItemsitems_id

这行得通,但我认为这消除了关系数据库的力量,我想了解这应该如何完成(即根据 Cakephp 约定或简单地通过任何 MySQL 语句来实现这一点)。

非常感谢您的帮助,我尝试学习 SQL 更复杂的方面,但它就在我的脑海中。:S

4

1 回答 1

1

了解必要的查询

使用问题中描述的结构,必要的查询类型为:

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);
}
于 2013-07-14T17:24:19.223 回答