11

注文システムを作ろうとしているのですが、今行き詰っています。現在、mysql テーブルでは、「bestillinger」という名前の列で varchar(255) を使用していますが、255 文字しか格納できません。だから私は少し検索し、長いテキストまたはテキストのみを使用できることを思い出しましたが、今それをしようとすると、次のようなエラーが表示されます。

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

こことGoogleで検索しようとしましたが、うまくいきませんでした。

私の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;

PHP部分で「ON DUPLICATE KEY UPDATE」を使用しているため、UNIQUE KEYを使用しています。しかし、気にしないでください。

前もって感謝します。

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_large_prefix が設定されていない限り、 InnoDB テーブルの場合は 767 バイト)。同じ長さ制限が、すべてのインデックス キー プレフィックスに適用されます (CHAR、VARCHAR、TEXT の場合は最初の N 文字、BINARY、VARBINARY、BLOB の場合は最初の N バイト)。文字とバイトの違いに注意してください。UTF-8 文字セットと各文字の最大 3 バイトを想定すると、TEXT または VARCHAR 列で333 文字を超える列プレフィックス インデックスを使用すると、この制限に達する可能性があります。実際には、333 が私にとって良い最大値になる傾向があります。

同様に SQL Serverでは、すべてのインデックス キー列の最大合計サイズに 900 バイトの制限があります。

しかし、それは TEXT の最初の文字のみをキーとして使用するため、明らかな衝突が差し迫っています。

受け入れられた回答では、提案はFULLTEXT indexを使用することです。FULLTEXT インデックスはテキスト検索用に特別に設計されており、列レコードのボキャブラリ全体で N グラムを維持し、結果のベクトルを格納するため、INSERT/DELETE のパフォーマンスはあまり良くありません。これは、すべての操作が where 句でテキスト検索関数を使用する場合に機能しますが、一意のインデックスでは機能しません。「id」には主キーと一意のキーの両方が定義されていますが、これは冗長に見えるか、意図を見逃しています。

代わりに、計算されたハッシュを提案します。ハッシュとの衝突が発生する可能性 (Birthday Paradox) があることを指摘するのは正しいでしょう。そのため、UNIQUE インデックスだけでは十分ではありません。上記のように、列プレフィックス インデックスと組み合わせて、一意性を信頼できるようにします。

ID 列の意図は、他のテーブルからの適切な外部キー参照を許可することです。その通りですが、それがこのテーブルのより有用な主キーになります。同様に、int(11) は、基になる値ではなく、列の表示幅を参照します。'id' にも unsigned 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;

ブロブ/テキスト インデックスを処理する際の mysql の制限は767です

参照: 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 に答える