MySQL SELECT DISTINCT 行(不是列)以过滤 $_POST 重复项

MySQL SELECT DISTINCT rows (not columns) to filter $_POST for duplicates

我正在尝试过滤 MySQL table 中的行,其中所有 $_POST 数据都存储在在线表单中。有时用户的 Internet 连接停止或浏览器出现故障,并且不显示表单提交后的新页面(尽管 INSERT 有效并且创建了 table 行)。然后他们点击刷新,并提交他们的表单两次,创建一个重复的行(时间戳和自动增量 ID 列除外)。

我想要 select 独特的表单提交。这必须是一项非常常见的任务,但我似乎无法找到让我调用 DISTINCT 的东西以简洁的方式应用于除时间戳和 id 之外的每一列(有点像 SELECT id, timestamp, DISTINCT everything_else FROM table; . 目前,我可以做到:

CREATE TEMPORARY TABLE IF NOT EXISTS temp1 AS (
  SELECT DISTINCT everything,except,id,and,timestamp 
  FROM table1
);
SELECT * FROM table1 LEFT OUTER JOIN temp1 
  ON table1.everything = temp1.everything
  ...
;

我的 table 有 20k 行,大约 25 列(机器学习练习的分类特征)。此查询需要 forever(因为我假设它遍历 20k 行 20K 次?)我什至从未让它 运行 完成。执行此操作的标准做法是什么?

注意:This question建议对相关列加索引,但一个索引最多可以有16个关键部分。我应该只选择最有可能独特的吗?通过这种方式,我可以在 2 秒内找到大约 700 个重复项,但我不能确定没有丢弃唯一行,因为在指定索引时我还必须忽略一些列。

我会首先尝试消除问题。有一些技术可以消除这个问题。我想到的第一个是您可以生成一个随机字符串并将其存储在会话中并作为表单中的隐藏字段。每次显示表单时都应生成此随机字符串。当用户提交表单时,您需要检查会话密钥和输入密钥是否匹配。确保为每个请求生成不同的密钥。因此,当用户刷新页面时,他将提交一个旧密钥,但它不会匹配。

另一种解决方案是,如果此数据在数据库中应始终是唯一的,请在插入之前先检查数据库中是否存在该确切数据。如果数据是唯一的,比如电子邮件地址,您可以创建一个唯一的键索引。因此,该字段在 table.

中必须是唯一的

如果您有 UNIQUE 键(AUTO_INCREMENT 除外),只需使用 INSERT IGNORE ... 即可避免重复行。如果您没有 UNIQUE 键,您是否永远不需要再次查找行?

如果您已经允许重复项并且需要删除它们,那就是另一个问题了。