2011-03-28 87 views
1

说我有两个表:更新一个多一对多连接器表一下子

articles 
categories 

有一个许多人连接它们的许多表。

CREATE TABLE cat2art (
    article_id INT, 
    category_id INT 
); 

对于一个特定的文章中,我有类的id的“新名单”,我们需要用这些更新cat2art表。

一些类别被删除,一些被添加,一些被保留在原来的位置。更新此表的最有效方法是什么?

我可以天真地删除指定article_id的所有记录,并简单地再次添加它们。但是,如果我要在同一张表中记录一个日期,以跟踪文章何时链接到某个类别,那么这些信息现在将被销毁。

我正在寻找一个很好的模式,可以轻松解决这个问题。这个问题专门针对PHP和MySQL,但其他语言的答案也可以,但也适用于PHP + MySQL。

回答

4

其他系统支持MERGE声明,会做你想要什么。

但是,MySQL,你至少需要两个查询(不能删除,并在单个语句插入/更新):

DELETE 
FROM cat2art 
WHERE art_id = $art_id 
     AND cat_id NOT IN ($new_cat_1, $new_cat_2, …); 

INSERT 
IGNORE 
INTO cat2art 
VALUES 
($art_id, $new_cat_1), 
($art_id, $new_cat_2), 
…; 
+0

接受此答案是为了最贴近我正在寻找的答案=) – Evert 2011-03-29 11:53:04

2

您可以将(article_id,category_id)定义为唯一键,并且在插入连接时使用INSERT IGNORE语法。这样,如果此连接已存在,则不会再次添加,也不会更新现有记录,并且create_date列保持不变。

例如:

INSERT IGNORE INTO cat2art (article_id, category_id, create_date) 
VALUES(100,200,NOW()); 
+0

我怎么会知道以后该记录删除? – Evert 2011-03-28 15:36:15

+0

@Evert - 您需要运行删除查询,类似于Quassoni的建议。我解决了插入问题,假设这是更具挑战性的部分。 – Galz 2011-03-28 15:40:02

+0

两者都不是很有挑战性,但我希望有一个很好的可重复使用的模式,可以插入/更新/删除这些记录。我发现自己多次手动做这个操作,所以我希望有一个很好的标准解决方案。 – Evert 2011-03-29 11:51:45