sql >> Databáze >  >> RDS >> Mysql

Délka indexu varchar MySQL

Úprava v září 2021:Již několik let používám MySQL 8.0, takže zde jsou některé aktualizované informace.

Manuál MySQL má nyní velmi informativní stránku ohledně převodu mezi utf8mb3 (v současnosti také známý jako utf8 ) a utf8mb4 . utf8mb3 je zastaralá a bude odstraněna nakonec; a když je odstraněn, jeho aktuální alias, utf8 , bude odkazovat na utf8mb4 místo toho.

S zastaralým utf8mb3 , můžete uložit až 255 znaků v indexu, zatímco s utf8mb4 , až 191, při použití COMPACT nebo REDUNDANT formát řádku.

S COMPRESSED nebo DYNAMIC řádkový formát, předpony indexového klíče mohou mít až 3072 bajtů. Pomocí nich můžete indexovat až 1024 znaků pro utf8mb3 a 768 znaků pro utf8mb4 .

Níže je moje předchozí odpověď, která vysvětluje některé z logiky počtu znaků můžete indexovat podle počtu bajtů .

Musím svou odpověď upravit kvůli mému výzkumu. Původně jsem napsal toto (cituji sám sebe):

Věřím, že odpověď zní, že nemůžete vědět, kolik znaků bude v indexu, protože nemůžete vědět, kolik bajtů budou vaše znaky (pokud neuděláte něco pro vyloučení vícebajtových znaků).

A nejsem si jistý, ale stále to může být správné, ale ne úplně tak, jak jsem si myslel.

Zde je správná odpověď:

MySQL předpokládá 3 bajty na znak utf8. 255 znaků je maximální velikost indexu, kterou můžete zadat na sloupec, protože 256x3=768, což překračuje limit 767 bajtů.

Pokud neurčíte velikost indexu, MySQL vybere maximální velikost (tj. 255 na sloupec). UNIKÁTNÍ omezení nelze umístit na sloupec utf8, jehož délka je větší než 255, protože jedinečný index musí obsahovat celou hodnotu buňky. Ale lze použít běžný index - indexuje pouze prvních 255 znaků (nebo prvních 767 bajtů?). A to je místo, kde je pro mě stále nějaké tajemství.

MySTERY:Chápu, proč MySQL předpokládá 3 bajty na znak, kvůli bezpečnosti, protože jinak by mohlo být porušeno omezení UNIQUE. Zdá se však, že dokumenty naznačují, že velikost indexu je ve skutečnosti v bajtech, nikoli ve znacích. Předpokládejme tedy, že vložíte 255 char (765 bajtů) index na varchar(256 ) sloupec. Pokud jsou všechny uložené znaky ASCII, 1bajtové znaky, jako A-Z, a-z, 0-9, pak můžete celý sloupec umístit do indexu o velikosti 767 bajtů. A zdá se, že to by se skutečně stalo.

Níže je několik dalších informací z mé původní odpovědi o znacích, bajtech atd.

Podle wikipedie , znak UTF-8 může být dlouhý 1,2, 3 nebo 4 bajty. Ale podle tuto dokumentaci mysql , maximální velikost znaku je 3 bajty, takže jakýkoli index indexu sloupce nad 255 znaků může dosáhnout tohoto limitu bajtů. Ale jak jsem pochopil, možná ne. Pokud je většina vašich znaků v rozsahu ASCII, pak se průměrná velikost vašeho znaku bude blížit 1 bajtu. Pokud je vaše průměrná velikost znaku například 1,3 bajtu (většinou 1 bajt, ale významný počet 2–3 bajtových znaků), můžete zadat index 767/1,3

Pokud tedy ukládáte převážně 1bajtové znaky, váš skutečný limit počtu znaků by byl spíše:767 / 1,3 =590. Ale ukázalo se, že to není způsob, jakým to funguje. Limit je 255 znaků.

Jak je uvedeno v této dokumentaci MySQL ,

Limity prefixů se měří v bajtech, zatímco délka prefixu v příkazech CREATE INDEX je interpretována jako počet znaků pro nebinární datové typy (CHAR, VARCHAR, TEXT). Vezměte to v úvahu při zadávání délky předpony pro sloupec, který používá vícebajtovou sadu znaků.

Zdá se, že MySQL radí lidem, aby provedli výpočet / odhad, jako jsem to udělal já, aby bylo možné určit velikost vašeho klíče pro sloupec varchar. Ale ve skutečnosti nemůžete zadejte index větší než 255 pro sloupce utf8.

Nakonec, pokud se znovu vrátíte na můj druhý odkaz, je zde také toto:

Když je povolena možnost konfigurace innodb_large_prefix, tento limit délky se zvýší na 3072 bajtů pro tabulky InnoDB, které používají formáty řádků DYNAMIC a COMPRESSED.

Zdá se tedy, že pokud chcete, můžete s trochou úprav získat mnohem větší indexy. Jen se ujistěte, že formáty řádků jsou DYNAMICKÉ nebo KOMPRESOVANÉ. V takovém případě pravděpodobně můžete zadat index 1023 nebo 1024 znaků.

Mimochodem, ukázalo se, že můžete uložit 4bajtové znaky pomocí [znakové sady utf8mb4][4]. Znaková sada utf8 zřejmě ukládá pouze znaky ["rovina 0"][5].

EDIT:

Právě jsem se pokusil vytvořit složený index na sloupci varchar(511) se sloupcem tinyint(1) a dostal jsem chybovou zprávu, že maximální velikost indexu byla 767 bajtů. To mě vede k přesvědčení, že MySQL předpokládá, že sloupce znakové sady utf8 budou obsahovat 3 bajty na znak (maximum) a umožňuje vám použít max. 255 znaků. Ale to je možná pouze u složených indexů. Svou odpověď aktualizuji, jakmile zjistím více. Ale zatím to nechávám jako úpravu.



  1. Nainstalujte MySQL na Mac

  2. Funkce SQL velmi pomalá ve srovnání s dotazem bez funkce wrapper

  3. Jak vložit/aktualizovat větší velikost dat v tabulkách Oracle?

  4. Jak získat seznam pohledů MySQL?