Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
确保MYSQL/InnoDB中大于255的varchar的唯一性_Mysql_Innodb - Fatal编程技术网

确保MYSQL/InnoDB中大于255的varchar的唯一性

确保MYSQL/InnoDB中大于255的varchar的唯一性,mysql,innodb,Mysql,Innodb,我有一个包含URL的表,其中一些URL超过255个字符。我想对URL列施加唯一性约束,但MySQL不允许我在URL上创建键。我使用的是InnoDB/UTF8表。据我所知,每个字符使用多个字节,密钥限制为766字节(在InnoDB中) 基于URL保持行唯一的优雅方式是什么?您可以将URL拆分为两列或更多列,并使组合(URLpart1、URLpart2、…、URLpartN)唯一。然后,允许的最大索引长度将从767字节提高到3072字节。例如: CREATE TABLE atest ( id INT

我有一个包含URL的表,其中一些URL超过255个字符。我想对URL列施加唯一性约束,但MySQL不允许我在URL上创建键。我使用的是InnoDB/UTF8表。据我所知,每个字符使用多个字节,密钥限制为766字节(在InnoDB中)


基于URL保持行唯一的优雅方式是什么?

您可以将URL拆分为两列或更多列,并使组合
(URLpart1、URLpart2、…、URLpartN)
唯一。然后,允许的最大索引长度将从767字节提高到3072字节。例如:

CREATE TABLE atest
( id INT NOT NULL AUTO_INCREMENT 
, a VARCHAR(255) NOT NULL
, b VARCHAR(255) NOT NULL DEFAULT ''
, c VARCHAR(255) NOT NULL DEFAULT ''
, d VARCHAR(255) NOT NULL DEFAULT ''
, PRIMARY KEY (id)
, UNIQUE INDEX url_idx (a,b,c,d)
) ENGINE = InnoDB ;

对于MySQL 5.7或更高版本,请参阅,了解使用生成列的更好方法


您可以使用url的名称作为唯一键。两个URL有可能具有相同的散列,但这种可能性非常小,从实用角度来看,这种方法应该可以很好地工作


您还可以设置触发器,以便在插入以下内容时自动计算
哈希
列:

CREATE TRIGGER mytrigger
BEFORE INSERT
ON foo
FOR EACH ROW SET
    NEW.hash = SHA1(NEW.url)

在MySQL 5.7.6或更高版本中,可以使用包含要对其放置唯一性约束的列的散列的

默认情况下,生成的列是虚拟的,这意味着这些值永远不会存储在磁盘上。虚拟列只能在MySQL>=5.7.8版本中使用InnoDB引擎进行索引;对于MyISAM或MySQL的旧版本,您必须使用
存储的

mysql> CREATE TABLE url_hash_test (
    ->   url TEXT,
    ->   url_hash VARCHAR(32) AS (md5(url)),
    ->   UNIQUE(url_hash)
    -> );
Query OK, 0 rows affected (0.00 sec)

mysql> INSERT INTO url_hash_test SET url='http://example.com';
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO url_hash_test SET url='http://example.com';
ERROR 1062 (23000): Duplicate entry 'a9b9f04336ce0181a08e774e01113b31' for key 'url_hash'

对我会在第一个键列中使用主机名部分。这会起作用(在有限的场景子集中,字符串字段的最大长度需要大于767但小于3072),但这是一个非常丑陋的黑客行为。是的,我认为这是我将要采用的解决方案。这有点烦人,因为我偶尔想手动将东西插入数据库,但我认为这是正确的方法。哦,哇,还没有想到触发器。太棒了,谢谢!另一个问题是:当我现在做一个插入时,使用一个重复的键,我有SQL来处理它:插入。。。在重复键上更新id=id。奇怪的是,它告诉我这个命令正在向表中插入两行。我对此有点困惑。没有创建额外的行,这是正确的,所以我不明白为什么要插入两行。这是否与触发器有关?是的,我看到了相同的行为,但不是由于触发器。我引用,“代码>”带有重复的密钥更新,如果行被插入为新行,则每行的受影响行值为1,如果现有行被更新,则为2。“<代码> Hi Vijay-考虑接受Andre Dalcher的答案。在最新版本的MySQL中,这是一种更简洁的方式,unutbu承认这是一个更好的解决方案。