0

3つのメインテーブルがあるとしましょう: category, tag,url

categorytagMANY_MANY 関係があります。

tagurlMANY_MANY 関係があります。

categoryリンクされているすべての を取得したいと思いますurl

これを行うための最も簡単で効率的な方法は何ですか?

MANY_MANY_MANY 関係のようなものを宣言できますか? または、これは基準で実行可能ですか?それとも、純粋な SQL で行う必要がありますか?

私は基準のアイデアが好きです。なぜなら、後でページネーションの目的で「オフセット」および「制限」パラメーターを渡すからです...

4

2 に答える 2

0

I may have found a trick: VIEWS

I created the following view:

CREATE VIEW category_url AS
(SELECT DISTINCT category.id AS category_id, url.id AS url_id 
FROM category
LEFT JOIN category_tag ON category_tag.category_id=category.id
LEFT JOIN url_tag ON url_tag.tag_id = category_tag.tag_id
LEFT JOIN url ON url.id = url_tag.url_id)

And I added the following relation to Category:

self::MANY_MANY, 'Url', 'category_url(category_id, url_id)'

I haven't done extensive testing yet. Comments welcomed.

于 2012-11-19T16:58:33.237 に答える
0

たとえば、多対多の情報を保持するための中間テーブルを作成するのが最善の方法だと思います。

CREATE TABLE `categories_tags` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `id_categories` int(11) NOT NULL,
  `id_tags` int(11) NOT NULL,
  PRIMARY KEY (`id`)
);
ALTER TABLE `categories_tags`
  ADD CONSTRAINT `categories_tags_ibfk_1` FOREIGN KEY (`id_categories`) REFERENCES `categories` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
  ADD CONSTRAINT `categories_tags_ibfk_2` FOREIGN KEY (`id_tags`) REFERENCES `tags` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;

と...

CREATE TABLE `tags_urls` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `id_tags` int(11) NOT NULL,
  `id_urls` int(11) NOT NULL,
  PRIMARY KEY (`id`)
);
ALTER TABLE `tags_urls`
  ADD CONSTRAINT `tags_urls_ibfk_1` FOREIGN KEY (`id_tags`) REFERENCES `tags` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
  ADD CONSTRAINT `tags_urls_ibfk_2` FOREIGN KEY (`id_urls`) REFERENCES `urls` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;

これらのテーブル間の関係でスルーを使用できます。

あなたのカテゴリモデルでは:

public function relations()
{
    return array(
        'categoryTags' => array(self::_MANY, 'CategoriesTags', 'id_categories'),
        'tags' => array(self::HAS_MANY, 'Tag', 'id_tags', 'through'=>'categoryTags'),
        'tagsUrls' => array(self::HAS_MANY, 'TagUrl', 'id_tags', 'through'=>'tags'),
        'urls' => array(self::HAS_MANY, 'Url', 'id_url', 'through'=>'tagsUrls'),
    );
}

特定のカテゴリのすべての URL を呼び出すには、次のことができるはずです。

$model = Category::model()->findByPk($categoryId);

$model->urls; // will be an array of url models that belong to the category.

[編集] 質問を読み直した後、上記の編集を追加しました。私はテストしていません。コードをいくつか (または多く) 編集する必要があるかもしれませんが、原則は理論的には機能するはずです。「スルー」リレーション データを取得するためのより迅速な方法があるかもしれませんが、実際には以前に 2 つの多対多リレーションシップでスルーを使用したことがないため、自分で試す必要はありませんでした。

于 2012-11-19T16:15:57.647 に答える