我想防止插入具有相同字段值的行,该字段不是键。
在我的情况下,可能有两种插入类型:第一种是由脚本运行的,第二种是由服务器中的某些DAO进行的。就脚本而言,username
字段是唯一的,但是服务器不应阻止多个username
-这就是为什么我无法在{{1}上拥有唯一索引的原因}字段。
例如:
username
我尝试了建议的答案,但没有用。
CREATE TABLE test(
id INT AUTO_INCREMENT,
user_name VARCHAR(255) NOT NULL,
PRIMARY KEY (id)
);
INSERT INTO test(user_name) VALUES ('alex');
答案 0 :(得分:1)
我使用了这种方法:
INSERT INTO test(user_name)
SELECT ('alex' ) WHERE NOT EXISTS (select 1 from test where user_name='alex');
答案 1 :(得分:0)
如果我理解正确,则需要Insert Ignore:
如果使用IGNORE修饰符,则在执行 INSERT语句被忽略。例如,如果没有IGNORE,则该行 复制表中现有的UNIQUE索引或PRIMARY KEY值 导致重复键错误,并且语句中止。用 忽略,该行将被丢弃,并且不会发生错误。忽略的错误 而是生成警告。
如果有相同的值,它将忽略它。
您也可以使用Replace
或Insert Into ... on Duplicate Key
,这取决于您要精确实现什么。
以下是有关该问题的好帖子:https://chartio.com/resources/tutorials/how-to-insert-if-row-does-not-exist-upsert-in-mysql/
更新:
当您更新问题时,我也必须更新我的答案。
用户名可以为Unique
吗?在这种情况下,Insert Ignore
和Replace
也可以工作。
UPDATE2:
在万不得已的情况下,您可以创建如下过程:
DROP PROCEDURE IF EXISTS InsertUserName;
DELIMITER //
CREATE PROCEDURE InsertUserName(IN name VARCHAR(255))
BEGIN
If NOT EXISTS (select user_name from test where user_name=name limit 1) then
BEGIN
insert into test (`user_name`) values (name);
END;
END IF;
END //
DELIMITER ;
您可以这样称呼它:
call InsertUserName('alex');
如果表中存在alex
,则没有alex
时将不会添加它。
但是请至少在user_name
列上添加一个普通的非唯一键,它将大大提高性能。
答案 2 :(得分:0)
如果您的目标是告诉MySQL您希望在仍然使用user_name
列作为主键的同时禁止id
中具有相同值的两行,则解决方案是UNIQUE索引:
CREATE UNIQUE INDEX <IndexName> ON test(user_name)
也就是说,如果id
和user_name
都是唯一的,那么id
毫无用处,您应该考虑放弃它而只使用user_name
(有某些原因可能会使此改进变得不太可行,但您在问题中没有提及任何这些原因。