Das Problem
In MySQL gibt es eine maximale Schlüssellänge.
- InnoDB - maximale Schlüssellänge ist 1.536 Bytes (für 8kb Seitengröße) und 768 (für 4kb Seitengröße) (Quelle: Dev.MySQL.de ).
- MyISAM - maximale Schlüssellänge ist 1.000 Bytes (Quelle Dev.MySQL.de ).
Diese werden gezählt in Bytes! Ein UTF-8-Zeichen kann also mehr als ein Byte benötigen, um im Schlüssel gespeichert zu werden.
Daher gibt es nur zwei unmittelbare Lösungen:
- Indexiert nur die ersten n-ten Zeichen der Textart.
- Erstellen einer
FULL TEXT
search - Alles wird innerhalb des Textes durchsuchbar sein, ähnlich wie bei ElasticSearch
Indizierung der ersten n-ten Zeichen einer Textart
Wenn Sie eine Tabelle erstellen, verwenden Sie die folgende Syntax, um die ersten 255 Zeichen eines Feldes zu indizieren: KEY
Irgendein Textschlüssel (
SomeText (255))
. Etwa so:
CREATE TABLE `MyTable` (
`id` int(11) NOT NULL auto_increment,
`SomeText` TEXT NOT NULL,
PRIMARY KEY (`id`),
KEY `sometextkey` (`SomeText`(255))
);
Wenn Sie die Tabelle bereits haben, können Sie einen eindeutigen Schlüssel zu einem Feld mit hinzufügen: ADD UNIQUE(
ConfigValue (20));
. Etwa so:
ALTER TABLE
MyTable
ADD UNIQUE(`ConfigValue`(20));
Wenn der Name des Feldes nicht reserviert ist MySQL-Schlüsselwort , dann sind die Backticks (````) um den Feldnamen nicht erforderlich.
Erstellen einer FULL TEXT Suche
Eine Volltextsuche ermöglicht es Ihnen, den gesamten Wert Ihrer TEXT
Bereich. Es wird ein Ganzwortabgleich durchgeführt, wenn Sie NATURAL LANGUAGE MODE
oder Teilwortsuche, wenn Sie einen der anderen Modi verwenden. Weitere Informationen zu den Optionen für Volltext finden Sie hier: Dev.MySQL.de
Erstellen Sie Ihre Tabelle mit dem Text, und fügen Sie den Volltextindex hinzu...
ALTER TABLE
MyTable
ADD FULLTEXT INDEX
`SomeTextKey` (`SomeTextField` DESC);
Dann durchsuchen Sie Ihre Tabelle wie folgt...
SELECT
MyTable.id, MyTable.Title,
MATCH
(MyTable.Text)
AGAINST
('foobar' IN NATURAL LANGUAGE MODE) AS score
FROM
MyTable
HAVING
score > 0
ORDER BY
score DESC;
5 Stimmen
Da es sich nicht um 520 Bytes, sondern um 2080 Bytes handelt, die weit über 767 Bytes hinausgehen, könnten Sie Spalte1 varchar(20) und Spalte2 varchar(170) verwenden. Wenn Sie eine Zeichen/Byte-Entsprechung wünschen, verwenden Sie latin1
3 Stimmen
Ich denke, Ihre Berechnung ist ein bisschen falsch hier. mysql verwendet 1 oder 2 zusätzliche Bytes, um die Werte Länge aufzeichnen: 1 Byte, wenn die maximale Länge der Spalte 255 Bytes oder weniger ist, 2, wenn es länger als 255 Bytes ist. die utf8_general_ci Codierung benötigt 3 Bytes pro Zeichen so varchar (20) verwendet 61 Bytes, varchar (500) verwendet 1502 Bytes insgesamt 1563 Bytes
3 Stimmen
Mysql> select maxlen, character_set_name from information_schema.character_sets where character_set_name in('latin1', 'utf8', 'utf8mb4'); maxlen | character_set_name ------ | ------------------- 1 | latin1 ------ | ------------------- 3 | utf8 ------ | ------------------- 4 | utf8mb4
24 Stimmen
'wenn Sie eine Zeichen/Byte-Äquivalenz wünschen, verwenden Sie latin1' Bitte Tun Sie das nicht . Latin1 ist wirklich, wirklich scheiße. Du wirst es bereuen.
0 Stimmen
Siehe stackoverflow.com/a/52778785/2137210 für die Lösung