11

我正在尝试建立一个订单系统,但我现在被卡住了。现在在 mysql 表中,我在名为“bestillinger”的列中使用 varchar(255),但它只能存储 255 个字符。所以我搜索了一下,并记得我可以使用长文本或只使用文本,但现在当我尝试这样做时,我收到一条错误消息:

#1170 - BLOB/TEXT column 'bestilling' used in key specification without a key length

我曾尝试在这里和谷歌搜索,但没有运气。

我的 MySQL 表是:

CREATE TABLE IF NOT EXISTS `bestillinger` (
  `id` int(11) NOT NULL,
  `bestilling` TEXT NOT NULL PRIMARY KEY,
  `accepted` varchar(255) DEFAULT NULL,
  UNIQUE KEY `id_bestilling` (`id`,`bestilling`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

我使用 UNIQUE KEY 因为我在我的 PHP 部分中使用“ON DUPLICATE KEY UPDATE”。但不要介意。

提前致谢。

4

5 回答 5

12

您不能将文本设置为主键。Mysql 只能索引一些字符,并且键入的文本可能太大而无法索引。

看看这里:

于 2012-12-04T19:24:00.790 回答
7

根据您上面的定义,以及下面这个答案中的冗长独白,我建议进行以下修订:

CREATE TABLE IF NOT EXISTS `bestillinger` (
  `id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
  `bestilling` TEXT NOT NULL,
  `hashcode` CHAR(32) AS (MD5(bestilling)),  
  `accepted` VARCHAR(255) DEFAULT NULL,
  UNIQUE KEY `id_bestilling` (hashcode,bestilling(333))
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

特定于 MySQL,单列索引键的默认最大长度为1000 字节InnoDB 表为 767 字节,除非您设置了 innodb_large_prefix )。相同的长度限制适用于任何索引键前缀(CHAR、VARCHAR、TEXT 的前 N ​​个字符或 BINARY、VARBINARY、BLOB 的前 N ​​个字节)。注意字符与字节的区别;假设一个 UTF-8 字符集和每个字符最多 3 个字节,您可能会在 TEXT 或 VARCHAR 列上使用超过333 个字符的列前缀索引来达到此限制。在实践中,333 对我来说往往是一个很好的最大值。

同样,在 SQL Server中,所有索引键列的最大总大小限制为 900 字节。

但这仅使用 TEXT 的第一个字符作为密钥,显然即将发生冲突。

在接受的答案中,建议是使用FULLTEXT index。FULLTEXT 索引是专门为文本搜索而设计的,它对 INSERT/DELETE 的性能不太好,因为它在列记录的词汇表上维护一个 N-gram 并存储结果向量。如果每个操作都在 where 子句中使用文本搜索功能,这将起作用……但不适用于唯一索引。在“id”上还定义了一个主键和一个唯一键,这似乎是多余的,或者我错过了意图。

相反,我建议使用计算哈希。您正确地指出有可能(生日悖论)会与哈希发生冲突,因此仅 UNIQUE 索引是不够的。如上所述,我们将把它与列前缀索引结合起来,让我们相信唯一性。

我收集您的 ID 列的目的是允许从其他表中正确引用外键。完全正确,但那将是该表更有用的主键。同样, int(11) 指的是列的显示宽度,而不是基础值。我也在 'id' 上放了一个未签名的 auto_increment,以阐明它对更多受众的作用。

这将我们带到了上面提出的设计。

于 2013-01-09T22:08:03.733 回答
1

用这个

CREATE TABLE IF NOT EXISTS `bestillinger` (
  `id` int(11) NOT NULL,
  `bestilling` TEXT NOT NULL PRIMARY KEY,
  `accepted` varchar(255) DEFAULT NULL,
  UNIQUE KEY `id_bestilling` (`id`,`bestilling`(767))
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

767是 mysql 在处理 blob/文本索引时的限制

参考:http ://dev.mysql.com/doc/refman/5.7/en/innodb-restrictions.html

于 2016-04-06T10:59:43.033 回答
1

我认为下面的例子将最好地解释这个问题。

我遇到了问题,因为我试图将文本字段设置为 UNIQUE。我通过将电子邮件(TEXT)的数据类型更改为电子邮件(VARCHAR(254))解决了这个问题。

mysql> desc users;
+-------------+-------------+------+-----+---------+----------------+
| Field       | Type        | Null | Key | Default | Extra          |
+-------------+-------------+------+-----+---------+----------------+
| id          | int(11)     | NO   | PRI | NULL    | auto_increment |
| fname       | varchar(50) | NO   |     | NULL    |                |
| lname       | varchar(50) | NO   |     | NULL    |                |
| uname       | varchar(20) | NO   |     | NULL    |                |
| email       | text        | NO   |     | NULL    |                |
| contact     | bigint(12)  | NO   |     | NULL    |                |
| profile_pic | text        | NO   |     | NULL    |                |
| password    | varchar(20) | NO   |     | admin   |                |
+-------------+-------------+------+-----+---------+----------------+
8 rows in set (0.00 sec)

mysql> ALTER TABLE users ADD UNIQUE(email);
ERROR 1170 (42000): BLOB/TEXT column 'email' used in key specification without a key length
mysql> 
mysql> ALTER  TABLE users MODIFY email VARCHAR(254);
Query OK, 9 rows affected (0.02 sec)
Records: 9  Duplicates: 0  Warnings: 0

mysql> ALTER TABLE users ADD UNIQUE(email);
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> desc users;
+-------------+--------------+------+-----+---------+----------------+
| Field       | Type         | Null | Key | Default | Extra          |
+-------------+--------------+------+-----+---------+----------------+
| id          | int(11)      | NO   | PRI | NULL    | auto_increment |
| fname       | varchar(50)  | NO   |     | NULL    |                |
| lname       | varchar(50)  | NO   |     | NULL    |                |
| uname       | varchar(20)  | NO   |     | NULL    |                |
| email       | varchar(254) | YES  | UNI | NULL    |                |
| contact     | bigint(12)   | NO   |     | NULL    |                |
| profile_pic | text         | NO   |     | NULL    |                |
| password    | varchar(20)  | NO   |     | admin   |                |
+-------------+--------------+------+-----+---------+----------------+
8 rows in set (0.00 sec)

mysql> 
于 2017-06-07T12:24:22.933 回答
0

截屏

尝试使用varchar中的所有长度。由于大小,不应允许使用文本。

于 2019-04-10T17:55:40.977 回答