我的DDBB中有下表:
CREATE TABLE subjects (
subject_id int(11) NOT NULL AUTO_INCREMENT,
subject text,
PRIMARY KEY (subject_id, subject)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 AUTO_INCREMENT=1;
这是我的桌子的一个例子:
id | subject |
1 test
2 ICT
3 ICT
键(id)不是重复的,因为它是由MySQL自动生成的,但是后两行在重复。
如何避免重复主题名称?
我已经读到可以用这样的“约束”来完成它:
ALTER TABLE subjects
ADD CONSTRAINT constraint_subject UNIQUE KEY(subject);
但是我尝试过,每次都会出错。
我知道之前已经有人问过这个问题,但是我仍然从我的PHP输入,某些主题具有相同的名称,并且程序总是允许我输入它们。
答案 0 :(得分:3)
添加约束会给您一个错误,因为由于您已经有重复的数据而无法满足要求。
您必须删除重复项,然后添加约束,然后约束将起作用。
如果您现在只想选择不同的行,即使数据库中有重复的行,也可以运行以下命令:
SELECT
*
FROM
subjects AS s1
WHERE
NOT EXISTS (
SELECT
id
FROM
subjects AS s2
WHERE
s1.subject = s2.subject
AND s1.id != s2.id
);
或
SELECT
s1.*
FROM
subjects AS s1
LEFT JOIN
subjects AS s2
ON (s1.subject = s2.subject AND s1.id != s2.id)
WHERE
s2.id IS NULL
两者都会给出相同的结果,但是我发现第一个更加明确地说明了您要实现的目标。
答案 1 :(得分:2)
您不能在数据类型为TEXT
的列上创建索引,因为对于索引而言,这太长了。
您可以在该列的前缀上创建索引,甚至是唯一索引。
ALTER TABLE subjects
ADD CONSTRAINT constraint_subject UNIQUE KEY(subject(191));
这意味着两个主题不能具有完全相同的前191个字符。
我认为您不应该声明包含该主题的主键。单独使用自动递增整数列作为主键更为常见。
因此您的表最终具有以下定义:
CREATE TABLE `subjects` (
`subject_id` int(11) NOT NULL AUTO_INCREMENT,
`subject` text,
PRIMARY KEY (`subject_id`),
UNIQUE KEY `constraint_subject` (`subject`(191))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
我选择了191的长度,因为它是InnoDB索引中767字节限制(utf8mb4个字符计为4字节)的最大长度。