我有一个MySQL数据库,其中有一个包含网站地址的表。该网站的访问者可以发送我添加到我网站的链接。
要阻止指向同一网页的链接,我希望将具有网址的列设为唯一。我怎么能这样做?
我找到了类似下面的内容,但有没有办法在phpmyadmin中设置这个?
INSERT INTO `table` (value1, value2)
SELECT 'stuff for value1', 'stuff for value2' FROM `table`
WHERE NOT EXISTS (SELECT * FROM `table`
WHERE value1='stuff for value1' AND value2='stuff for value2')
LIMIT 1
答案 0 :(得分:2)
这样的问题有几种解决方案,但我最喜欢的是使用校验和。这是一个例子(出于效率的原因,使用高位校验和存储为二进制数据):
create table urls (
id int unsigned not null auto_increment primary key,
binsha512 binary(64),
url text,
unique key(binsha512),
duplicates int unsigned not null default 0 ) ;
set @newurl = "http://danf.us"; -- so we only have to send it once
insert into urls set
url=@newurl,
binsha512= UNHEX( SHA2( @newurl,512))
on duplicate key update duplicates = duplicates + 1;
您可以插入带校验和的URL,也可以增加重复次数。当然,如果不更改模式和插入查询,则无法实现这一点,这可能是不合需要的。但它具有处理任意长度URL的明显优势。
答案 1 :(得分:0)
您应该能够在phpMyAdmin环境中执行SQL代码使列唯一:
ALTER TABLE `table` ADD UNIQUE ( `uniqueColumn`, `anotherUniqueColumn` )
然后,当您尝试向此列插入数据时,它将不会是唯一的,您将收到错误。
答案 2 :(得分:0)
当然,您可以在PHPmyAdmin中创建唯一列,而不仅仅是编写SQL,而是使用图形界面,这更容易。此外,您可以创建自己的脚本来检查该值是否已插入表中。您只需使用一个函数来获取行的值以及循环,并将检索到的值与用户尝试提交的值进行比较。它工作得非常好,至少对于一个小型数据库。
答案 3 :(得分:0)
正如Dan Farrell在评论中提到的那样,你的问题缺乏精确性:如果你给了我们你正在使用的模式(列是什么?),那就更清楚了。
此外,正如丹尼尔在他的回答中提到的,如果你想拥有一个独特的列或一个独特的列组合,你应该使用UNIQUE
索引来开始。
现在有了这样说,依靠MySQL报告错误来做出业务决策是不对的,而且不需要。实际上,MySQL提供了两个命令,可以让您决定在插入违反唯一索引时要执行的操作,并且应该使用它而不是让MySQL抛出错误。您可以参考MySQL documentation on INSERT了解更多
INSERT IGNORE INTO ...
:使用此语法,只有在没有违反唯一键的情况下,MySQL才会插入行,即在您的情况下,如果URL尚未包含在表中。你会得到像
INSERT IGNORE INTO `yourtable` (field1, field2, ..., url)
VALUES ('f1', 'f2', ..., 'http://example.com');
执行查询后,MySQL会告诉你有多少行受到影响,因此如果网址已经存在,它会告诉你没有行受到影响。
INSERT INTO ... ON DUPLICATE KEY UPDATE ...
:使用此语法,如果网址已存在,您将能够更新条目而不是插入新条目;例如,如果您有一个计数器字段,用于存储用户提交的网址的次数
INSERT INTO `yourtable` (last_submitted_by, counter, url)
VALUES ('joe', 1, 'http://example.com')
ON DUPLICATE KEY UPDATE
counter = counter + 1,
last_submitted_by = VALUES(last_submitted_by) ;
请注意,在UPDATE
部分中,您可以使用INSERT
构造引用您在VALUES(..)
部分中指定的值(在我的示例中,这将用于维护对最后一个的引用)提交此网址的用户。
更新(在对其他答案发表评论后)
当然,您可以在索引中使用的字段大小有限制,对于文本字段,您必须指定长度。 This answer on another SO question提供了有关限制的详细信息,但即使有下限(MySQL为1000字节),这对于网址唯一性来说也足够了(如果存储在unicode中则为500个字符,你不会这样做真的有理由为网址做,虽然现在你可能会遇到一些特殊字符,因为域名中有非ascii字符(域名外,非ascii字符应该是url编码)。
答案 4 :(得分:0)
我将columntype从TEXT更改为VARCHAR,长度为200.之后我可以将其设置为唯一。