Ако някога сте работили с MySQL, неизбежно сте се натъкнали на набори от знаци и съпоставяния. В тази публикация в блога ще се опитаме да ви дадем по-задълбочен поглед върху това какво представляват тези две и как трябва да ги използвате.
Какво представляват наборите от знаци и съпоставянията?
Просто казано, наборите от знаци в MySQL са набори от символи и кодировки - съпоставянията са набори от правила за сравняване на знаци в набор от знаци. С други думи, наборите от знаци са набори от знаци, които са законни в низ, докато съпоставянията са набор от правила, използвани за сравняване на знаци в конкретен набор от знаци. Точно както всеки набор от символи има съпоставяне по подразбиране, наборите от знаци могат да имат и няколко съпоставяния. MySQL има набор от символи по подразбиране и сортиране за сървъра, както и за всяка база данни и таблица.
Набори от знаци в MySQL
По принцип наборите от знаци в MySQL работят така:
- Когато се създаде база данни, наборите от знаци се извличат от променливата character_set_server за целия сървър.
- Когато се създаде таблица, наборите от знаци се извличат от базата данни.
- Когато се създаде колона, наборите от знаци се извличат от таблицата.
Що се отнася до наборите от знаци, има няколко променливи, които трябва да следите:
- Character_set_client дефинира набора от знаци, в който операторите се изпращат от клиента.
- Character_set_connection дефинира набора от знаци, в който се превеждат изразите, след като сървърът получи изявление от клиента.
- Character_set_results дефинира набора от знаци, в който сървърът връща резултатите от заявката на клиента.
Тези три настройки могат да бъдат променени с помощта на операторите SET NAMES или SET CHARACTER SET или дори в конфигурационните файлове на MySQL.
Когато работите с набори от знаци понякога може да срещнете и грешка #1267:
ERROR 1267 (HY000): Illegal mix of collations.
Грешката по-горе обикновено се причинява от сравняване на два низа, които имат несъвместими съпоставяния или от опит за избор на данни, които имат различно съпоставяне, в комбинирана колона. Грешката се показва, защото когато MySQL сравнява две стойности с различни набори от знаци, той трябва да ги преобразува в същия набор от знаци за сравнението, но наборите от знаци не са съвместими. За да разрешите този проблем, уверете се, че съпоставянето на всяка таблица и техните колони са еднакви.
Колации в MySQL
Както вече беше споменато по-горе, съпоставянията са тясно свързани с наборите от знаци, тъй като съпоставянето е набор от правила, които определят как да се сравняват и сортират низове от знаци. Всеки набор от знаци има поне едно сортиране, някои имат и повече.
Въпреки че в тази публикация в блога няма да навлизаме в тънките подробности за всички неща, свързани с сортирането в MySQL, има някои неща, които трябва да знаете:
- Ако използвате MySQL 5.7, съпоставянето на MySQL по подразбиране обикновено е latin1_swedish_ci, тъй като MySQL използва latin1 като свой набор от знаци по подразбиране. Ако използвате MySQL 8.0, наборът от знаци по подразбиране е utf8mb4.
- Ако изберете да използвате UTF-8 като свое съпоставяне, винаги използвайте utf8mb4 (по-специално utf8mb4_unicode_ci). Не трябва да използвате UTF-8, защото UTF-8 на MySQL е различен от правилното UTF-8 кодиране. Това е така, защото не предлага пълна поддръжка на Unicode, което може да доведе до загуба на данни или проблеми със сигурността. Имайте предвид, че utf8mb4_general_ci е опростен набор от правила за сортиране, който използва преки пътища, предназначени да подобрят скоростта, докато utf8mb4_unicode_ci сортира точно в широк спектър от езици. Като цяло, utf8mb4 е „най-безопасният“ набор от знаци, тъй като поддържа и 4-байтов уникод, докато utf8 поддържа само до 3.
Избор на добър набор от знаци и съпоставяне
За да изберете добро съпоставяне и набор от знаци за вашия набор от данни на MySQL, не забравяйте да го опростите. Смесица от различни набори от знаци и (или) съпоставяния може да бъде истинска бъркотия, тъй като може да бъде много объркваща (например всичко може да работи добре, докато се появят определени знаци и т.н.), така че е най-добре да оцените нуждите си предварително и да изберете най-доброто съпоставяне и набор от знаци предварително. MySQL също има няколко ценни заявки, които могат да ви помогнат да направите точно това, например
SELECT * FROM information_schema.CHARACTER_SETS ORDER BY CHARACTER_SET_NAME;
ще върне списък с набори от знаци и налични съпоставяния заедно с описанието им, което може да бъде изключително полезно, ако планирате дизайна на вашата база данни.
Имайте предвид, че някои набори от знаци може да изискват повече операции на процесора, също така може да заемат повече място за съхранение. Използването на грешни набори от знаци може дори да попречи на индексирането – например MySQL трябва да преобразува набори от знаци, за да може да ги сравнява, когато не са еднакви:преобразуването може да направи невъзможно използването на индекс.
Освен това, имайте предвид, че някои хора препоръчват „просто да използвате UTF-8 глобално“ – това може да не е непременно страхотна идея, тъй като много приложения дори не се нуждаят от UTF-8 и в зависимост за вашите данни UTF-8 може да причини повече проблеми, отколкото си струва (например, може да използва много повече място за съхранение на диска), така че избирайте разумно.
Резюме
Наборите от символи и съпоставянията могат да бъдат ваши приятели или един от вашите кошмари - всичко зависи от това как ги използвате. Като цяло, имайте предвид, че „добрият“ набор от знаци и съпоставяне зависят от данните, които вашата база данни съдържа - MySQL предоставя някои заявки, които да ви помогнат да решите какво да използвате, но за да бъдат вашите набори от знаци и съпоставяния ефективни, трябва също да помислите за това кога има смисъл да се използва определено съпоставяне и защо.