MySQL 触发器以防止输入重复记录

MySQL trigger to keep duplicate records from being entered

我有一个 table,其中包含以下列:

ID(primary key),
USER,
ACTION
TIME
LOCATION

我希望使用触发器或在 table 更新时运行的东西,以确保没有基于 USER、ACTION、TIME、LOCATION 分组的重复条目。我回答了一个关于如何清除导致以下结果的现有条目的先前问题:

DELETE t1.*
        FROM
  testlogins t1 INNER JOIN testlogins t2
  ON t1.user=t2.user
     AND t1.action=t2.action
     AND t1.time=t2.time
     AND t2.location=t2.location
     AND t1.id>t2.id;

这可以清除现有记录。我想我也许可以基于此创建一个触发器,然后我想出了这个:

DELIMITER $$
create trigger del_duplicates
after insert
on test.testlogins for each row
begin
    DELETE t1.*
        FROM
  testlogins t1 INNER JOIN testlogins t2
  ON t1.user=t2.user
     AND t1.action=t2.action
     AND t1.time=t2.time
     AND t2.location=t2.location
     AND t1.id>t2.id;
end 
$$

然而 returns:

Error Code: 1442. Can't update table 'testlogins' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.

我想这是因为我要求系统在插入后执行删除。我还想知道在触发器期间调用存储过程来完成此操作是否值得。

避免添加与以下四列匹配的重复行的最佳方法是什么:USER、ACTION、TIME、LOCATION

之前的回答是关于如何去除重复的,但是如果你想防止重复的发生,最好添加一个唯一索引:

CREATE UNIQUE INDEX idx_userlogins ON testlogins (USER, ACTION, TIME, LOCATION)

然后为了防止在插入重复行时出现错误,您可以使用以下语法:

INSERT INTO testlogins VALUES (value1, value2, value3, value4)
ON DUPLICATE KEY UPDATE user=user;
CREATE UNIQUE INDEX body_idx ON testlogins (action, time, location);

这将防止 (action, time, location) 的重复项存在。

就像其他人所说的那样,创建一个 UNQUE INDEX(每个用户唯一的任何字段,即用户名)

REPLACE INTO testlogins (`USER`, `ACTION`, `TIME`, `LOCATION`) VALUES (val1, val2, val3, val4)

replace into 是一个很酷的函数,如果唯一索引匹配则替换,如果唯一索引不匹配则插入