Mysql
 sql >> база данни >  >> RDS >> Mysql

Дължина на индекса на MySQL varchar

Редактиране от септември 2021 г.:Използвам MySQL 8.0 от няколко години, така че ето малко актуализирана информация.

Ръководството за MySQL вече има много информативна страница относно преобразуването между utf8mb3 (понастоящем известен също като utf8 ) и utf8mb4 . utf8mb3 е оттеглено и ще бъде премахнато в крайна сметка; и когато бъде премахнат, текущият му псевдоним, utf8 , ще се отнася до utf8mb4 вместо това.

С остарял utf8mb3 , можете да съхранявате до 255 знака в индекс, докато с utf8mb4 , до 191, когато използвате COMPACT или REDUNDANT формат на ред.

С COMPRESSED или DYNAMIC формат на ред, префиксите на индексния ключ могат да бъдат до 3072 байта. С тях можете да индексирате до 1024 знака за utf8mb3 и 768 знака за utf8mb4 .

По-долу е предишният ми отговор, който обяснява част от логиката зад броя на знаците можете да индексирате спрямо броя на байтовете .

Трябва да преразгледам отговора си поради моето проучване. Първоначално публикувах това (цитирам себе си):

Вярвам, че отговорът е, че не можете да знаете колко знака ще има в индекса, защото не можете да знаете колко байта ще бъдат вашите знаци (освен ако не направите нещо, за да изключите многобайтови знаци).

И не съм сигурен, но може и да е вярно, но не по начина, по който си мислех.

Ето верния отговор:

MySQL приема 3 байта на символ utf8. 255 знака е максималният размер на индекса, който можете да посочите за колона, тъй като 256x3=768, което нарушава ограничението от 767 байта.

Ако не посочите размер на индекса, MySQL избира максималния размер (т.е. 255 на колона). УНИКАЛНО ограничение не може да бъде поставено върху utf8 колона, чиято дължина е по-голяма от 255, тъй като уникалният индекс трябва да съдържа цялата стойност на клетката. Но може да се използва обикновен индекс - той просто ще индексира първите 255 знака (или първите 767 байта?). И това е мястото, където все още има някаква мистерия за мен.

Мистерията:Виждам защо MySQL приема 3 байта на знак, за безопасност, защото в противен случай ограничението UNIQUE може да бъде нарушено. Но документите изглежда предполагат, че индексът всъщност е оразмерен в байтове, а не в знаци. И така, да предположим, че сте поставили 255 char (765 байта) индекс на varchar(256). ) колона. Ако всички знаци, които съхранявате, са ASCII, 1-байтови знаци, като A-Z, a-z, 0-9, тогава можете да поставите цялата колона в индекса от 767 байта. И изглежда, че това всъщност ще се случи.

По-долу има още информация от първоначалния ми отговор за знаци, байтове и т.н.

Според wikipedia , UTF-8 символът може да бъде с дължина 1, 2, 3 или 4 байта. Но според тази mysql документация , максималният размер на знаците е 3 байта и така всеки индекс на колона над 255 знака може да достигне това ограничение за байтове. Но както разбирам, може и да не е така. Ако повечето от вашите знаци са в диапазона на ASCII, тогава средният ви размер на знаците ще бъде по-близък до 1 байт. Ако средният ви размер на знаците е например 1,3 байта (предимно 1 байт, но значителен брой от 2-3 байта), тогава можете да посочите индекс от 767/1,3

Така че, ако съхранявате предимно 1-байтови знаци, действителното ви ограничение ще бъде по-скоро:767 / 1.3 =590. Но се оказва, че не работи така. 255 знака е ограничението.

Както е посочено в тази MySQL документация ,

Ограниченията на префикса се измерват в байтове, докато дължината на префикса в изразите CREATE INDEX се интерпретира като брой знаци за недвоични типове данни (CHAR, VARCHAR, TEXT). Вземете това предвид, когато задавате дължина на префикса за колона, която използва набор от няколко байта.

Изглежда, че MySQL съветва хората да направят изчисление/преценка, както току-що направих, за да определят размера на вашия ключ за колона varchar. Но всъщност вие не можете посочете индекс, по-голям от 255 за колони utf8.

И накрая, ако се върнете отново към втората ми връзка, има и това:

Когато опцията за конфигурация innodb_large_prefix е активирана, това ограничение за дължина се повишава до 3072 байта за таблици InnoDB, които използват форматите на DYNAMIC и COMPRESSED ред.

Така че изглежда, че можете да получите много по-големи индекси, ако искате, с малко настройване. Просто се уверете, че форматите на редовете са ДИНАМИЧНИ или КОМПРЕСИРАНИ. В този случай вероятно можете да посочите индекс от 1023 или 1024 знака.

Между другото, оказва се, че можете да съхранявате 4-байтови знаци, като използвате [набора от символи utf8mb4][4]. Наборът от символи utf8 очевидно съхранява само ["равнина 0"] [5].

РЕДАКТИРАНЕ:

Току-що се опитах да създам съставен индекс в колона varchar(511) с колона tinyint(1) и получих съобщението за грешка, че максималният размер на индекса е 767 байта. Това ме кара да вярвам, че MySQL предполага, че колоните за набор от символи utf8 ще съдържат 3 байта на знак (максимум) и ви позволява да използвате максимум 255 символа. Но може би това е само със съставни индекси. Ще актуализирам отговора си, когато разбера повече. Но засега оставям това като редакция.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как да шифровате трафика от хибридна облачна база данни

  2. Как да конвертирате MySQL база данни в UTF-8 кодиране

  3. Как да се уверите, че вашата база данни MySQL е защитена

  4. Изявление на казус в MySQL

  5. Как се свързвате с множество MySQL бази данни на една уеб страница?