URL唯一的列

时间:2014-03-08 17:46:54

标签: php mysql phpmyadmin

我有一个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 

5 个答案:

答案 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了解更多

  1. INSERT IGNORE INTO ...:使用此语法,只有在没有违反唯一键的情况下,MySQL才会插入行,即在您的情况下,如果URL尚未包含在表中。你会得到像

    这样的东西
    INSERT IGNORE INTO `yourtable` (field1, field2, ..., url)
    VALUES ('f1', 'f2', ..., 'http://example.com');
    

    执行查询后,MySQL会告诉你有多少行受到影响,因此如果网址已经存在,它会告诉你没有行受到影响。

  2. 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(..)部分中指定的值(在我的示例中,这将用于维护对最后一个的引用)提交此网址的用户。

  3. 更新(在对其他答案发表评论后)

    当然,您可以在索引中使用的字段大小有限制,对于文本字段,您必须指定长度。 This answer on another SO question提供了有关限制的详细信息,但即使有下限(MySQL为1000字节),这对于网址唯一性来说也足够了(如果存储在unicode中则为500个字符,你不会这样做真的有理由为网址做,虽然现在你可能会遇到一些特殊字符,因为域名中有非ascii字符(域名外,非ascii字符应该是url编码)。

答案 4 :(得分:0)

我将columntype从TEXT更改为VARCHAR,长度为200.之后我可以将其设置为唯一。