1

我正在尝试使用 MySQL 创建一个新闻通量...为此,我有一个表“操作”,它记录任何时候在其他 3 个表之一(“文章”、“评论”、“导演”)。现在,我在第一个表“动作”中有 4 列:

  • id_action(允许按顺序知道何时采取了行动)
  • 操作(添加/更新)
  • 表(其他 3 个表之一的名称)
  • id_table(对应上表的id)

其他 3 个表具有不同的列名和内容,因此,我有:

  • 表“文章”,列“id”、“titre”、“contenu”、“categorie”
  • 表'commentaire',列'id','contenu'
  • 表'auteur',列'id','prenom','presentation','localisation'

我尝试过像这样的连接:

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"
}

如果有人有更有效的方法来做需要的事情,那么欢迎所有答案!加入,条件,我不知道有什么办法......

4

2 回答 2

0

我不完全清楚你在这里想要实现什么 - 这是某种审计线索吗?我真的建议你避免使用这种表结构,当数据集变大时,你会遇到很大的性能问题。尝试每个数据表使用一个“历史”表,例如article_actionscomment_actions

无论如何,这里的查询将与您正在做的事情大致相同,但在普通 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在每张桌子上粘贴几列,一列用于creation_time,一列用于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 回答