如何防止重复插入 table
How to prevent duplicate inserts into a table
我想向Mysql中插入数据,当数据已经在table中时,不应再次插入。如何防止二次插入?
try {
$conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
// set the PDO error mode to exception
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql = "INSERT INTO MyGuests(firstname, lastname, email)
VALUES ('John', 'Doe', 'john@example.com')";
// use exec() because no results are returned
$conn->exec($sql);
echo "Table MyGuests created successfully";
} catch(PDOException $e) {
echo $sql . "<br>" . $e->getMessage();
}
$conn = null;
结果是这样的:
您在 电子邮件地址 上没有唯一密钥。这是你最大的希望,因为系统中可以有许多 John Doe。因此,全名的唯一复合索引从来都不是一个好主意。
可以发出 INSERT IGNORE,它在重复违规后缓慢前进,就好像什么都没发生一样(这是非常不推荐的,在您的情况下是不可能的,因为您对电子邮件的独特约束不存在)。这样做的主要问题是您倾向于(阅读:可能会)失去对正在发生的事情的所有控制并留下不需要的数据。所以不要用它,除非你是专业人士。
可以发布 INSERT ON DUPLICATE KEY UPDATE (a.k.a.IODKU),它也需要唯一的密钥(也可以是唯一的组合)。因此,不会出现新行,而是更新该行。例如,可以插入一个包含 4 列的新行,但如果出现重复冲突,则可以仅对其中两列执行更新,例如
假设在下面一个看不见的列 id int
上的主键和 emailAddr
上的唯一键
insert person(firstName,lastName,emailAddr) values 'Joe','Smith','jsmith@email.com'
on duplicate key update firstName='Joe',lastName='Smith'
emailAddr 上的唯一键使这项工作成功。每个 emailAddr 只剩下 1 行,永远。
因此,您可以有无限个 Joe Smiths,但每个电子邮件地址只能有 1 行。
上面 table 的创建 table 看起来像
create table person
( id int auto_increment primary key,
firstName varchar(50) not null,
lastName varchar(50) not null,
emailAddr varchar(150) not null,
unique key(emailAddr) -- without this, IODKU will not work
);
您还可以在创建 table 后发出 ALTER TABLE 命令来添加约束。根据其中的数据,调用可能会失败。
Mysql Insert on Duplicate Key Update, and Alter Table 手册页。
我再说一遍,如果没有正确的模式设置,IODKU 将无法工作,您将留下不需要的行。所以不要偷懒。设置架构 first 允许它成功(使用唯一键),然后 继续使用 IODKU。
您需要添加一个唯一的 constraint/index 并忽略由重复引起的错误。如果这是您的查询:
INSERT INTO MyGuests(firstname, lastname, email)
VALUES ('John', 'Doe', 'john@example.com');
并且您想防止所有三列都被重新插入,那么您可以添加唯一性为:
create unique index unq_myguests_firstname_lastname_email on myguests(firstname, lastname, email);
然后,将 insert
表述为:
INSERT INTO MyGuests(firstname, lastname, email)
VALUES ('John', 'Doe', 'john@example.com')
ON DUPLICATE KEY UPDATE firstname = VALUES(firstname);
ON DUPLICATE KEY UPDATE
部分除了忽略错误外什么都不做。
我想向Mysql中插入数据,当数据已经在table中时,不应再次插入。如何防止二次插入?
try {
$conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
// set the PDO error mode to exception
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql = "INSERT INTO MyGuests(firstname, lastname, email)
VALUES ('John', 'Doe', 'john@example.com')";
// use exec() because no results are returned
$conn->exec($sql);
echo "Table MyGuests created successfully";
} catch(PDOException $e) {
echo $sql . "<br>" . $e->getMessage();
}
$conn = null;
结果是这样的:
您在 电子邮件地址 上没有唯一密钥。这是你最大的希望,因为系统中可以有许多 John Doe。因此,全名的唯一复合索引从来都不是一个好主意。
可以发出 INSERT IGNORE,它在重复违规后缓慢前进,就好像什么都没发生一样(这是非常不推荐的,在您的情况下是不可能的,因为您对电子邮件的独特约束不存在)。这样做的主要问题是您倾向于(阅读:可能会)失去对正在发生的事情的所有控制并留下不需要的数据。所以不要用它,除非你是专业人士。
可以发布 INSERT ON DUPLICATE KEY UPDATE (a.k.a.IODKU),它也需要唯一的密钥(也可以是唯一的组合)。因此,不会出现新行,而是更新该行。例如,可以插入一个包含 4 列的新行,但如果出现重复冲突,则可以仅对其中两列执行更新,例如
假设在下面一个看不见的列 id int
上的主键和 emailAddr
insert person(firstName,lastName,emailAddr) values 'Joe','Smith','jsmith@email.com'
on duplicate key update firstName='Joe',lastName='Smith'
emailAddr 上的唯一键使这项工作成功。每个 emailAddr 只剩下 1 行,永远。
因此,您可以有无限个 Joe Smiths,但每个电子邮件地址只能有 1 行。
上面 table 的创建 table 看起来像
create table person
( id int auto_increment primary key,
firstName varchar(50) not null,
lastName varchar(50) not null,
emailAddr varchar(150) not null,
unique key(emailAddr) -- without this, IODKU will not work
);
您还可以在创建 table 后发出 ALTER TABLE 命令来添加约束。根据其中的数据,调用可能会失败。
Mysql Insert on Duplicate Key Update, and Alter Table 手册页。
我再说一遍,如果没有正确的模式设置,IODKU 将无法工作,您将留下不需要的行。所以不要偷懒。设置架构 first 允许它成功(使用唯一键),然后 继续使用 IODKU。
您需要添加一个唯一的 constraint/index 并忽略由重复引起的错误。如果这是您的查询:
INSERT INTO MyGuests(firstname, lastname, email)
VALUES ('John', 'Doe', 'john@example.com');
并且您想防止所有三列都被重新插入,那么您可以添加唯一性为:
create unique index unq_myguests_firstname_lastname_email on myguests(firstname, lastname, email);
然后,将 insert
表述为:
INSERT INTO MyGuests(firstname, lastname, email)
VALUES ('John', 'Doe', 'john@example.com')
ON DUPLICATE KEY UPDATE firstname = VALUES(firstname);
ON DUPLICATE KEY UPDATE
部分除了忽略错误外什么都不做。