防止mysql db中的重复行,IGNORE无法正常工作

时间:2012-06-24 13:48:05

标签: php mysql

我试图阻止将重复的行插入到mysql数据库中。表名是收藏夹,我的表中有两列:company_id和user_id,我想阻止用户尝试将同一公司添加到数据库中作为“收藏”两次。

这就是我的尝试:

$query  = "INSERT IGNORE INTO favorites (item_id, user_id) VALUES ( $item_id, $user_id )";
    mysql_query($query,$conn);

但是不起作用。

我也试图'改变表'来添加主键,但是,我需要user_id和item_id都是键,因为同一个被收藏的项可以被多个'user_id'和相同的'user_id'所支持。可以插入许多不同的收藏项,以便数据可以“重复”,但我试图阻止完全相同的'user_id'和'item_id'插入两次。

我很感激任何帮助。

4 个答案:

答案 0 :(得分:2)

我所知道的最简单的方法是在user_id-item_id对上添加一个UNIQUE约束,这可以通过以下查询来完成:

ALTER TABLE favorites 
ADD UNIQUE(item_id,user_id)

每当您尝试插入已存在于表中的user_id-item_id对时,您的插入查询就会返回错误,因此您的INSERT查询应该被修改:

INSERT INTO favorites(item_id,user_id) 
     VALUES ($item_id,$user_id) 
ON DUPLICATE KEY UPDATE item_id=item_id

我不建议使用“INSERT IGNORE”,因为它会忽略所有错误。只要检测到重复的密钥,我的查询就会设置item_id = item_id(无变化),因此数据不会重复。

我也强烈建议你研究一下使用MySQLi而不是mysql_ *函数。如果您忘记检查这两个用户输入变量,那么您发布的PHP非常容易受到mysql注入的影响。甚至PHP手册也出于同样的原因主动阻止这些功能。

答案 1 :(得分:1)

尝试将复合主键(从item_iduser_id)添加到表格中。

如果您的表中已有违反此约束的数据,则会出现错误,在这种情况下,您需要创建一个新表并将数据迁移到新表中。

答案 2 :(得分:1)

您可以使用列的复合主键,如下所示:

ALTER TABLE table ADD PRIMARY KEY ( 'item_id' , 'user_id' )

这意味着允许使用相同的user_ids和item_id,并且只有它们的组合才需要是唯一的。

答案 3 :(得分:0)

INSERT IGNORE仅适用于密钥。通常,您拥有的唯一密钥是表上的主键。

因此,首先搜索匹配的行,如果存在,则不要插入新记录。

$search_q = "SELECT `id` FROM `favorites` WHERE `item_id` = ";
$search_q .= mysql_real_escape_string($item_id);
$search_q .= " AND `user_id` = ";
$search_q .= mysql_real_escape_string($user_id);


$r = mysql_query($search_q);
if (!mysql_num_rows($r)) {
   # This combination doesn't exist
   $insert_q = "INSERT INTO `favorites` (`item_id`,`user_id`) VALUES (";
   $insert_q .= mysql_real_escape_string($item_id).",";
   $insert_q .= mysql_real_escape_string($user_id).")"
   mysql_query($insert_q);  
}