1

MySQL でニュース フラックスを作成しようとしています...そのために、他の 3 つのテーブル ('article','commentaire','作家」)。さて、この最初のテーブル「アクション」には4つの列があります:

  • id_action (アクションがいつ実行されたかを順番に知ることができます)
  • アクション (追加/更新)
  • テーブル (他の 3 つのテーブルのうちの 1 つの名前)
  • id_table (上のテーブルの対応する id)

他の 3 つのテーブルの列名と内容は異なるため、次のようになります。

  • 列「id」、「titre」、「contenu」、「categorie」を持つテーブル「article」
  • 列「id」、「contenu」を持つテーブル「commentaire」
  • 列「id」、「prenom」、「プレゼンテーション」、「ローカリゼーション」を持つテーブル「auteur」

私は次のような結合を試しました:

SELECT ar.*,co.*,au.*
FROM 'action' AS ac
LEFT JOIN ac.table AS tbl ON ac.id_table = tbl.id

...しかし、テーブル「ac.table」が存在しないため、何も提供しませんでした...(実際には、テーブルの名前を取り、JOINでそれを置き換えることを望んでいました... :p

したがって、成功せずに2〜3回試行した後、最終的に何かが機能することがわかりましたが、後者は非常に消費が多く遅く、より良い解決策を探しています...私が見つけた解決策は4つの関数で構成されています:

function showAllAction(){
   $preprequete = "SELECT id_table, table
   FROM 'action'";

   $requete = $this->pdo->prepare($preprequete);
   if ($requete->execute()) {
       $result = $requete->fetchAll(PDO::FETCH_ASSOC);
       $requete->closeCursor();
       return $result;
   }else{ die(print_r($requete->errorInfo()));} 
   return false;
}

foreach が続く

$actions = $this->showAllAction();
foreach ($actions as $value){
   if($value['table']=='article'){
      $article = $this->showArticle($value['id_table']);
      echo $article['titre'];
   }elseif($value['table']=='commentaire'){
      $commentaire = $this->showCommentaire($value['id_table']);
      echo $commentaire['contenu'];
   }else{
      $auteur = $this->showAuteur($value['id_table']);
      echo $auteur['prenom'];
   }
}

ここで、différentes 関数は単純な SELECT のようなものです (次のコードは説明のためだけのものです。要点を説明するために不要なものをすべて削除しました)。

function showArticle($id_table){
   "SELECT titre, contenu, categorie
   FROM 'article'
   WHERE id = :id_table"
}
function showCommentaire($id_table){
   "SELECT contenu
   FROM 'commentaire'
   WHERE id = :id_table"
}
function showAuteur($id_table){
   "SELECT prenom, presentation, localisation
   FROM 'auteur'
   WHERE id = :id_table"
}

これは、誰かが必要なことを行うためのより効率的な方法を持っている場合は、すべての回答を歓迎します! JOIN、条件、何がうまくいくかわかりません...

4

2 に答える 2

0

ここで何を達成しようとしているのか、私には完全には明らかではありません。これは何らかの監査証跡ですか? このテーブル構造は避けることを強くお勧めします。データ セットが大きくなると、大きなパフォーマンスの問題が発生します。article_actionsなどcomment_actionsなど、データ テーブルごとに 1 つの「履歴」テーブルを使用してみてください。

いずれにせよ、これはあなたが行っているのとほぼ同じことを行うクエリですが、プレーン SQL では、すべてのデータベース ラウンド トリップを節約できるので高速になるはずです (それでも、このアクション テーブルを使用することはお勧めしません)。

select ac.`table`, ar.title
from action ac join article ar on ac.table_id = ar.article_id
where `table` = 'article'
union all
select ac.`table`, co.content
from action ac join comment co on ac.table_id = co.comment_id
where `table` = 'comment'
union all
select ac.`table`, au.name
from action ac join author au on ac.table_id = au.author_id
where `table` = 'author'
;

http://sqlfiddle.com/#!9/cb31eの完全な例

于 2013-11-09T14:41:31.827 に答える
0

datetime各テーブルに 1 列と 1 列creation_timeの2 つの列を貼り付けますupdate_time。詳細な説明については、[このリンク][http://twopieceset.blogspot.com.au/2007/12/best-practices-5-ws-of-database-design.html] を参照してください。

次のようなビューを作成して、時系列のルックアップを簡素化できます。

create or replace view recent_updates as 
select 'article' as `table`, article_id from article 
where update_time > now() - interval 1 day 
union all
select 'comment' as `table`, comment_id from comment 
where update_time > now() - interval 1 day 
union all
...
order by update_time desc
limit 1000
;

これは、データベースが大きくなっても高速であり、別の追跡テーブルは必要ありません。時間列のインデックスを作成することを忘れないでください!

(注:これはコメントに収まらないため、新しい回答を追加しました)

于 2013-11-09T22:49:31.170 に答える