1

私には2つのエンティティがpostあり、categoryどちらが1:n関係です。

2つの列を持つ参照テーブルがありますpost_idcategory_id

categoriesテーブルには、id列、status列、および列がありparent_idます

カテゴリが別のカテゴリ(n-depth)の子である場合、それparent_idはnullではありません。

カテゴリがオンラインの場合、ステータスは1です。それ以外の場合は、0です。

私がする必要があるのは、投稿が表示されているかどうかを確認することです。

これには以下が必要です。

投稿に参加したForeachカテゴリは、ルートノードまでのツリーをトレースします(カテゴリがparent_id==になるまでnull)。これらのカテゴリのいずれかがstatus0の場合、そのパスはオフラインと見なされます。

いずれかのパスがオンラインの場合、投稿は表示されていると見なされ、そうでない場合は非表示になります。

これを(半擬似コードとして)行うことを考えることができる唯一の方法は次のとおりです。

function visible(category_ids){
  categories = //select * from categories where id in(category_ids)
  online = false
  foreach(categories as category){
    if(category.status == 0)
      continue;

    children = //select id from categories where parent_id = category.id
    if(children)
      online = visible(children)
  }
  return online
}

categories = //select c.id from categories c join posts_categories pc on pc.category_id = c.id where pc.post_id = post.id

post.online = visible(categories)

しかし、それは多くのSQLクエリになる可能性がありますが、より良い方法はありますか?

4

2 に答える 2

0

ネストされたセットがオプションでない場合、私は次のことを知っています。

  • 親の子が常に親の後に続くようにデータが順序付けられている場合、出力の非表示ノードをスキップすることで、すべてのデータに対して1つのデータベースクエリでこれを解決できます。

これは、並べ替えられたネストされたセットでも同様に機能します。原則はこの回答で概説されていますが、深さを取得するためのアルゴリズムは機能せず、非表示のアイテムを削除できる再帰的イテレーターをお勧めします。

また、データが順序付けされていない場合は、ネストされた配列への回答で概説されているように、すべての行の(並べ替えられていない)クエリからツリー構造を作成できます。3番目のレベルが消えています。再帰は必要なく、簡単に出力できる構造が得られます<ul>/<li>。htmlスタイルの出力についても別の回答で説明する必要があります。

于 2012-10-06T10:33:50.913 に答える
0

従来のデータベースとメモリのトレードオフ。あなたがやっていることは、葉のある木を作ることです。ツリーを構築するには、リーフを再帰的にループする必要があります。データベースからの場合、次の 2 つのシナリオがあります。

  1. リーフごとにクエリを使用してツリーを再帰的に構築します。あなたは記憶に1本の木を持っています。それがあなたがしていることです。
  2. データベースからフラットな構造を取得し、メモリ内で再帰的にツリーを構築します。フラット ツリーと実際のツリーをメモリに保持します。それがあなたの別の方法です。

ハードウェア (ディスクアクセスとメモリ)、ツリーのサイズなど、多くのことに依存します。

于 2012-10-06T10:21:55.017 に答える