URL唯一的列


Column with URL unique

我有一个MySQL数据库,其中我有一个网站地址表。该网站的访问者可以发送链接,我添加到我的网站。

为了防止链接到同一页面,我想使列与url唯一。我该怎么做呢?

我发现下面的东西,但有没有办法设置这个在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 

对于此类问题有几种解决方案,但我最喜欢的是使用校验和。下面是一个示例(为了提高效率,使用高比特校验和作为二进制数据存储):

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方面有明显的优势。

您应该能够在phpMyAdmin环境中执行SQL代码使列唯一:

ALTER TABLE  `table` ADD UNIQUE ( `uniqueColumn`, `anotherUniqueColumn` )

然后,当你试图插入数据到这些列,它不会是唯一的,你会得到一个错误。

当然,您可以在PHPmyAdmin中创建唯一的列,不仅可以通过编写SQL,还可以使用图形界面,这更容易。此外,您还可以编写自己的脚本来检查该值是否已经插入到表中。您只需要使用一个函数,该函数与循环一起获取行值,并将检索到的值与用户尝试提交的值进行比较。它工作得很好,至少对于一个小数据库。

正如Dan Farrell在评论中提到的,你的问题不够精确:如果你给我们你正在使用的模式(列是什么?),它会更清楚。

另外,正如Daniel在他的回答中提到的,如果你想拥有一个唯一的列或唯一的列组合,你应该从UNIQUE索引开始。

现在说,依靠MySQL报告错误的业务决策是不完全正确的,也没有必要。实际上,MySQL提供了两个命令,可以让您在插入违反唯一索引时决定如何处理,应该使用这两个命令,而不是让MySQL抛出错误。你可以参考MySQL的INSERT文档来了解更多

  1. INSERT IGNORE INTO ...:使用这种语法,MySQL将只在没有违反唯一键的情况下插入行,即在你的情况下,如果URL不在表中。你会得到像

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

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

  2. INSERT INTO ... ON DUPLICATE KEY UPDATE ...:使用此语法,如果url已经存在,您将能够更新条目而不是插入新条目;例如,如果您有一个计数器字段存储用户提交url的次数

    ,则非常有用。
    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部分中,您可以使用VALUES(..)构造引用您在INSERT部分中指定的值(在我的示例中,这将用于维护对提交此url的最后一个用户的引用。

更新(在其他答案的评论之后)

当然,索引中可以使用的字段的大小是有限制的,对于文本字段,您必须指定长度。这回答另一个问题给出了详细的限制,但即使有下限MySQL(1000字节),这将是足够足够的url的唯一性(500个字符如果存储在unicode,你真的没有理由为url,尽管你可能会遇到一些特殊字符,现在非ascii字符中可用的域名(域名外,非ascii字符应该url编码)。

我将列类型从TEXT更改为VARCHAR,长度为200。之后我可以将它设置为唯一