MySQL-ში utf8 არ არის UTF-8. ეს utf8mb3-ის ფსევდონიმია, სამბაიტიანი ქვესიმრავლე, რომელიც ვერ ინახავს ვერცერთ სიმბოლოს Basic Multilingual Plane-ის გარეთ - მათ შორის ყველა emoji-ს, ბევრ CJK სიმბოლოს და მათემატიკური თუ ისტორიული დამწერლობების ნაწილს. utf8mb4 ნამდვილი UTF-8-ია და MySQL 8.0-დან ნაგულისხმევი სიმბოლოების ნაკრებია, utf8mb4_0900_ai_ci ნაგულისხმევი collation-ით. თუ ბაზას დღეს ქმნი, ყველგან utf8mb4 გამოიყენე: ბაზაში, ცხრილებში, სვეტებში და კავშირში. თუ utf8-ზე ან latin1-ზე მყოფი ბაზა მემკვიდრეობით მიიღე, მისი კონვერტაცია შესაძლებელია, მაგრამ როგორ გააკეთებ, დამოკიდებულია იმაზე, სწორადაა თუ არა მასში მონაცემები შენახული, და ამაში შეცდომა სწორედ ის გზაა, რომლითაც ტექსტი é-ად იქცევა.
ეს სახელმძღვანელო ხსნის განსხვავებას, როგორ აირჩიო collation, კავშირის რომელი პარამეტრები უნდა ემთხვეოდეს, და როგორ გადაიყვანო არსებული ბაზა უსაფრთხოდ MySQL 8.0-ზე ან 8.4 LTS-ზე.
utf8, utf8mb3 და utf8mb4#
UTF-8 ყოველ სიმბოლოს ერთიდან ოთხ ბაიტამდე აკოდირებს. ASCII ერთ ბაიტს იკავებს, ევროპული და ახლო აღმოსავლეთის ასოების უმეტესობა - ორს, ჩინური, იაპონური და კორეული სიმბოლოების უმეტესობა - სამს, ხოლო ყველაფერი U+FFFF-ის ზემოთ - emoji, იშვიათი CJK, მუსიკალური სიმბოლოები - ოთხს. როცა MySQL-მა 2002 წელს Unicode-ის მხარდაჭერა დაამატა, ადგილის დასაზოგად თავისი utf8 სიმბოლოზე სამ ბაიტამდე შეზღუდა, და ეს გადაწყვეტილება მას შემდეგ ხალხს ფეხს უდებს.
| სახელი | ბაიტი სიმბოლოზე | Emoji | სტატუსი |
|---|---|---|---|
latin1 | 1 | არა | მხოლოდ დასავლეთ ევროპული; ძველი ნაგულისხმევი 8.0-მდე |
utf8mb3 | 1-3 | არა | მოძველებული |
utf8 | 1-3 | არა | utf8mb3-ის ფსევდონიმი 8.4-ში |
utf8mb4 | 1-4 | კი | ნაგულისხმევი 8.0-დან; ეს გამოიყენე |
MySQL 8.0.30-დან სერვერი SHOW CREATE TABLE-სა და information_schema-ში utf8-ის ნაცვლად utf8mb3-ს აჩვენებს, რაც მდგომარეობას ბოლოს და ბოლოს ხილულს ხდის. გეგმა ისაა, რომ მომავალ ვერსიაში utf8 utf8mb4-ის ფსევდონიმი გახდეს; სანამ ეს მოხდება, არასოდეს დაწერო utf8 სქემაში, კონფიგურაციის ფაილში ან კავშირის სტრიქონში. დაწერე utf8mb4.
emoji-ს შენახვის მცდელობა utf8mb3 სვეტში ნაგულისხმევი მკაცრი SQL რეჟიმით ხმამაღლა მარცხდება:
ERROR 1366 (HY000): Incorrect string value: '\xF0\x9F\x98\x80' for column 'body' at row 1\xF0 ოთხბაიტიანი მიმდევრობის პირველი ბაიტია. მკაცრი რეჟიმის გარეშე MySQL სიმბოლოს წყვეტს ან ?-ით ცვლის და აგრძელებს, რაც უარესია: მონაცემები ჩუმად ზიანდება. თუ კითხვის ნიშნებს ხედავ იქ, სადაც მომხმარებლებმა emoji აკრიფეს, ან სვეტი, ან კავშირი არ არის utf8mb4.
Collation-ები: რას ნიშნავს სახელები#
სიმბოლოების ნაკრები ამბობს, როგორ ინახება სიმბოლოები. collation ამბობს, როგორ ედრება და ლაგდება ისინი: უდრის თუ არა a A-ს, უდრის თუ არა e é-ს, და სად მიდის ß. ყოველ ტექსტურ სვეტს ორივე აქვს. collation-ის სახელი მის ქცევას აკოდირებს:
| Collation | მნიშვნელობა |
|---|---|
utf8mb4_0900_ai_ci | Unicode 9.0-ის წესები, აქცენტისა და რეგისტრის მიმართ არამგრძნობიარე. 8.0+-ის ნაგულისხმევი |
utf8mb4_0900_as_ci | აქცენტის მიმართ მგრძნობიარე, რეგისტრის მიმართ არამგრძნობიარე |
utf8mb4_0900_as_cs | აქცენტისა და რეგისტრის მიმართ მგრძნობიარე |
utf8mb4_0900_bin | code point-ებს ადარებს; სწრაფი, ენობრივი წესების გარეშე |
utf8mb4_bin | ბაიტების ბინარული შედარება, ბოლო ჰარეებით შევსებით |
utf8mb4_unicode_ci | ძველი Unicode 4.0-ის წესები; გავრცელებულია 5.7-ის ეპოქის სქემებში |
utf8mb4_general_ci | ძველი, გამარტივებული წესები; სწრაფი, მაგრამ ბევრი ენისთვის არასწორი |
utf8mb4_de_pb_0900_ai_ci | გერმანული სატელეფონო წიგნის რიგი; ბევრი ლოკალისთვის არსებობს ენობრივი ვარიანტი |
0900 collation-ები Unicode Collation Algorithm-ის 9.0.0 ვერსიას ეფუძნება და MySQL 8-ში ძველ unicode_ci-ებზე უფრო სწორიც არის და უფრო სწრაფიც. ძველი collation-ებისგან ორი რამით განსხვავდება, რაც ღირს, რომ იცოდე:
- BMP-ის გარეთ მყოფი სიმბოლოები სწორად ლაგდება და ედრება.
utf8mb4_unicode_ci-სა დაutf8mb4_general_ci-ში ყველა ოთხბაიტიანი სიმბოლო ერთმანეთის ტოლია - უნიკალური index-ის მქონე სვეტი ვერ დაიტევს ერთდროულად სუშის emoji-სა და ლუდის emoji-ს, რადგან collation-ისთვის ისინი ერთი და იგივე სიმბოლოა.0900collation-ები მათ განსხვავებულად თვლის. - ბოლო ჰარეები ითვლება.
0900collation-ებიNO PAD-ია:'abc'და'abc 'განსხვავებულია. ძველებიPAD SPACE-ია და მათ ტოლად თვლის. ეს ცვლის შედარებებისა და უნიკალურობის შემოწმებების შედეგს მონაცემებზე, რომლებსაც შემთხვევითი ბოლო ჰარეები აქვს.
არჩევა
აპლიკაციების უმეტესობისთვის დატოვე ნაგულისხმევი utf8mb4_0900_ai_ci. რეგისტრისა და აქცენტის მიმართ არამგრძნობიარე დამთხვევა სწორედ ისაა, რასაც ხალხი ძებნის ველისა და შესვლის ფორმისგან ელის: Ana@Example.com პოულობს ana@example.com-ს, cafe პოულობს café-ს.
არამგრძნობიარობის ფასი უნიკალურ index-ებში ჩანს. ai_ci-ით resume და résumé ტოლია, ასე რომ username-ის სვეტზე უნიკალური index მეორეს უარყოფს. username-ებისთვის ეს ჩვეულებრივ სასურველია - აქცენტით სხვის თავად გასაღებას აჩერებს - და ზოგჯერ მოულოდნელი სხვა მონაცემებისთვის. სვეტებისთვის, რომლებსაც ზუსტი დამთხვევა სჭირდება (token-ები, hash-ები, რეგისტრის მიმართ მგრძნობიარე კოდები), გამოიყენე utf8mb4_0900_bin ან utf8mb4_0900_as_cs მხოლოდ იმ სვეტზე:
CREATE TABLE api_tokens ( id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, token VARCHAR(64) CHARACTER SET ascii COLLATE ascii_bin NOT NULL, name VARCHAR(100) NOT NULL, UNIQUE KEY uq_token (token)) DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;token-ები და hash-ები სუფთა ASCII-ია, ამიტომ ascii ascii_bin-ით მათ სიმბოლოზე ერთ ბაიტად ინახავს და ზუსტად ადარებს. ენაზე სპეციფიკური collation-ები ღირს, როცა დალაგების რიგი ერთი ენის მომხმარებლებისთვის მნიშვნელოვანია - თურქული წერტილიანი და უწერტილო i, შვედური å ä ö z-ის შემდეგ, ესპანური ñ.
სიმბოლოების ნაკრები ყველა დონეზე#
სიმბოლოების ნაკრები და collation ხუთ დონეზე შეიძლება დაყენდეს, და თითოეული, თუ მითითებული არ არის, ზედა დონიდან მემკვიდრეობით იღებს:
- სერვერი:
character_set_serverდაcollation_server, ნაგულისხმევი ახალი ბაზებისთვის. - ბაზა:
CREATE DATABASE appdb CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci, ნაგულისხმევი ახალი ცხრილებისთვის. - ცხრილი:
DEFAULT CHARSET=..., ნაგულისხმევი ახალი სვეტებისთვის. - სვეტი: ის, რაც შენახვისთვის რეალურად გამოიყენება.
- კავშირი: როგორ მოგზაურობს ტექსტი კლიენტსა და სერვერს შორის.
სვეტის დონე წყვეტს, რა ინახება. ბაზის ნაგულისხმევის შეცვლა ALTER DATABASE-ით არსებულ ცხრილებში არაფერს ცვლის; ის მხოლოდ შემდეგ შექმნილ ცხრილებზე მოქმედებს. ეს იჭერს ხალხს, ვინც ბაზა „გადაიყვანა“ და ისევ Incorrect string value შეცდომებს იღებს.
-- Every text column in a database that is not utf8mb4SELECT table_name, column_name, character_set_name, collation_nameFROM information_schema.columnsWHERE table_schema = 'appdb' AND character_set_name IS NOT NULL AND character_set_name <> 'utf8mb4'ORDER BY table_name, ordinal_position;-- Tables whose default differsSELECT table_name, table_collationFROM information_schema.tablesWHERE table_schema = 'appdb' AND table_collation NOT LIKE 'utf8mb4%';კავშირის სიმბოლოების ნაკრები#
სერვერი ბაიტებს სვეტის სიმბოლოების ნაკრებში ინახავს, მაგრამ უნდა იცოდეს, რა სიმბოლოების ნაკრებში აგზავნის კლიენტი. ამას სამი session ცვლადი აღწერს: character_set_client (რას აგზავნის კლიენტი), character_set_connection (რაში ინტერპრეტირდება ბრძანებები) და character_set_results (რა სახით ბრუნდება შედეგები). SET NAMES utf8mb4 სამივეს აყენებს, და ყველა დრაივერს აქვს ოფცია, რომელიც ამას დაკავშირებისას აკეთებს:
| კლიენტი | როგორ დავაყენოთ |
|---|---|
mysql CLI | --default-character-set=utf8mb4 (8.x კლიენტში ნაგულისხმევია) |
| PHP PDO | charset=utf8mb4 DSN-ში |
| PHP mysqli | $mysqli->set_charset('utf8mb4') |
Node mysql2 | charset ოფცია; utf8mb4 collation ნაგულისხმევია |
| Python PyMySQL / mysqlclient | charset='utf8mb4' |
| JDBC | characterEncoding=UTF-8 |
| .NET MySqlConnector | ყოველთვის utf8mb4; დასაყენებელი არაფერია |
SHOW SESSION VARIABLES LIKE 'character_set_%';SHOW SESSION VARIABLES LIKE 'collation_connection';კავშირი, რომელიც latin1-ს აცხადებს, მაშინ როცა აპლიკაცია სინამდვილეში UTF-8-ს აგზავნის, mojibake-ის უმეტესობის ძირეული მიზეზია: MySQL ერთგულად გარდაქმნის UTF-8 ტექსტის ყოველ ბაიტს, თითქოს ის Latin-1 სიმბოლო იყოს, და é (UTF-8-ში ორი ბაიტი) é-ად ჩადის. charset კავშირის სტრიქონში დააყენე და არა SET NAMES query-ით დაკავშირების შემდეგ, რომ ხელახლა დაკავშირებულმა pool-მა ის არ დაკარგოს. PHP PDO და MySQL და MySQL-ის დისტანციური კავშირები კავშირის სრულ დაყენებას თითოეული runtime-ისთვის აჩვენებს.
index-ის ზომა და VARCHAR(191)-ის ფოლკლორი#
utf8mb4 index-ის გასაღების სიგრძის გამოთვლისას სიმბოლოზე ოთხ ბაიტს იტოვებს. InnoDB-ის index-ის მაქსიმალური გასაღები 3072 ბაიტია DYNAMIC row format-ით, რომელიც 5.7-დან ნაგულისხმევია, და ეს VARCHAR(768)-ზე სრულ index-ს უშვებს. ძველი COMPACT და REDUNDANT ფორმატები, ისევე როგორც MySQL 5.6 ნაგულისხმევად, გასაღებებს 767 ბაიტით ზღუდავდა - utf8mb4-ის 191 სიმბოლო - და სწორედ ამიტომ იყენებს ამდენი framework და სახელმძღვანელო დღემდე VARCHAR(191)-ს index-ირებული სვეტებისთვის.
MySQL 8-ზე DYNAMIC ცხრილებით 191 არ გჭირდება. გამოიყენე ის სიგრძე, რაც შენს მონაცემებს სჭირდება. თუ ძველი ცხრილი index-ს უარყოფს შეცდომით Specified key was too long; max key length is 767 bytes, შეამოწმე მისი row format:
SELECT table_name, row_format FROM information_schema.tablesWHERE table_schema = 'appdb' AND row_format IN ('Compact', 'Redundant');ALTER TABLE legacy_table ROW_FORMAT=DYNAMIC;არსებული ბაზის კონვერტაცია#
ჯერ გაარკვიე, სინამდვილეში რა არის სვეტებში, რადგან ორი ძალიან განსხვავებული სიტუაცია არსებობს:
- სწორად შენახული მონაცემები არასწორ charset-ში.
latin1სვეტი Latin-1 ტექსტით, ანutf8mb3სვეტი ვალიდური ტექსტით. MySQL-მა იცის, რა სიმბოლოებია და შეუძლია მათი გარდაქმნა. გამოიყენეCONVERT TO. - არასწორად მონიშნული მონაცემები.
latin1სვეტი, რომელიც სინამდვილეში UTF-8 ბაიტებს შეიცავს, რადგან აპლიკაცია წლების განმავლობაში UTF-8-ს წერდაlatin1კავშირით. აპლიკაციაში ყველაფერი კარგად ჩანს (ის მონაცემებს იმავე არასწორი გზით კითხულობს უკან), ხოლო phpMyAdmin-ში ან dump-ში - არასწორად.CONVERT TOმას ორმაგად დააკოდირებდა. ამას ქვემოთ აღწერილი ბინარული წრე სჭირდება.
რომ გაიგო, რომელი გაქვს, შეხედე ცნობილ აქცენტიან მნიშვნელობას HEX()-ით:
SELECT name, HEX(name) FROM customers WHERE id = 42;-- 'José' correctly stored in latin1: 4A6F73E9-- 'José' as UTF-8 bytes in a latin1 column: 4A6F73C3A9E9 არის é Latin-1-ში. C3A9 არის é UTF-8-ში, რომელიც ზის სვეტში, რომელსაც ჰგონია, რომ ორ Latin-1 სიმბოლოს ინახავს.
სწორად შენახული: CONVERT TO
ALTER DATABASE appdb CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;ALTER TABLE customers CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;CONVERT TO ცვლის ცხრილის ნაგულისხმევს და ყოველ ტექსტურ სვეტს, მონაცემების გარდაქმნით. ის ცხრილს copy ალგორითმით ხელახლა აგებს, ასე რომ ჩაწერები მთელი ამ დროის განმავლობაში დაბლოკილია და სრული ასლისთვის თავისუფალი ადგილი გჭირდება დისკზე. latin1-იდან გარდაქმნამ შეიძლება TEXT სვეტები MEDIUMTEXT-მდეც აწიოს, რომ იმავე რაოდენობის სიმბოლოს დატევა შეძლონ; შემდეგ სქემა შეამოწმე, თუ შენს ORM-ს ეს აინტერესებს. დააგენერირე ბრძანებები ყველა ცხრილისთვის:
SELECT CONCAT('ALTER TABLE `', table_name, '` CONVERT TO CHARACTER SET utf8mb4 ', 'COLLATE utf8mb4_0900_ai_ci;') AS stmtFROM information_schema.tablesWHERE table_schema = 'appdb' AND table_type = 'BASE TABLE';არასწორად მონიშნული: ბინარული წრე
რომ MySQL-ს უთხრა, ბაიტები გარდაქმნის გარეშე ხელახლა ინტერპრეტირება მოახდინოს, ბინარულ ტიპზე უნდა გაიარო, რომელსაც სიმბოლოების ნაკრები არ აქვს:
ALTER TABLE customers MODIFY name VARBINARY(255);ALTER TABLE customers MODIFY name VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL;VARCHAR გადის VARBINARY-ზე, TEXT - BLOB-ზე, MEDIUMTEXT - MEDIUMBLOB-ზე. უკან გზაზე სვეტის სრული განსაზღვრება ხელახლა მიუთითე, NOT NULL-ისა და ნაგულისხმევი მნიშვნელობების ჩათვლით, რადგან MODIFY მას ცვლის. სვეტზე არსებული index-ები გადარჩება. შემდეგ გაასწორე აპლიკაციის კავშირის charset, სანამ ის რამეს ჩაწერს, თორემ ახალი ხაზები საპირისპირო მიმართულებით იქნება არასწორი.
კონვერტაციის გეგმა მოქმედი აპლიკაციისთვის#
ALTER ბრძანებები მარტივი ნაწილია. რიგი მათ გარშემო ინარჩუნებს მოქმედ საიტს მუშა მდგომარეობაში.
- ინვენტარიზაცია. გაუშვი ზემოთ მოცემული
information_schemaquery-ები და ჩამოწერე ყველა ცხრილი და სვეტი, რომელიცutf8mb4არ არის, ზომებით. პატარა ცხრილები წამებში გარდაიქმნება; მრავალგიგაბაიტიან ცხრილს შეიძლება იმდენი დრო დასჭირდეს, რომ ტექნიკური სამუშაოების ფანჯარა გჭირდებოდეს, რადგანCONVERT TOკოპირებისას ჩაწერებს ბლოკავს. - დიაგნოზი. არა-ASCII ტექსტის მქონე ყოველი ცხრილისთვის შეამოწმე რამდენიმე ცნობილი მნიშვნელობა
HEX()-ით და გადაწყვიტე, სწორადაა შენახული თუ არასწორადაა მონიშნული. ერთ ბაზაში შეიძლება ორივე იყოს, თუ აპლიკაციის კავშირის პარამეტრები მის ისტორიაში რაღაც მომენტში შეიცვალა. - ჯერ კავშირი გაასწორე, სადაც ეს უსაფრთხოა. თუ მონაცემები სწორადაა შენახული, აპლიკაციის კავშირის
utf8mb4-ზე გადართვა ცხრილების კონვერტაციამდე უვნებელია: MySQL კავშირსა და სვეტს შორის გარდაქმნას თავად აკეთებს. თუ მონაცემები არასწორადაა მონიშნული, კავშირის ცვლილება და ბინარული წრე ერთად უნდა მოხდეს, შუაში შეჩერებული ჩაწერებით. - გაიმეორე ასლზე. აღადგინე წუხანდელი dump სატესტო ბაზაში, გაუშვი სრული კონვერტაცია და შეამოწმე იგივე ცნობილი მნიშვნელობები, დალაგების რიგი და ძებნა. გაზომე დრო - ეს შენი ფანჯარაა.
- გაუშვი რეალურად, ცხრილ-ცხრილ, უდიდესი ბოლოს, უშუალოდ წინ აღებული ახალი backup-ით.
- დააყენე ნაგულისხმევები ბაზის დონეზე, რომ ახალი ცხრილები სწორად დაიბადოს, და დააფიქსირე charset და collation შენს migration-ებში, რომ framework-მა შემდეგი ცხრილი ჩუმად სხვა რამით არ შექმნას.
- მოძებნე ნარჩენები: შენახული პროცედურები და view-ები ინარჩუნებს იმ სიმბოლოების ნაკრებს, რომელიც მათი შექმნისას იყო მიმდინარე, და
SHOW CREATE PROCEDUREმას აჩვენებს. კონვერტაციის შემდეგ ხელახლა შექმენი ისინი.
framework-ები ცალკე ყურადღებას იმსახურებს. Laravel-ის config/database.php აყენებს charset-სა და collation-ს კავშირისთვის და იმ ცხრილებისთვის, რომლებსაც მისი migration-ები ქმნის; ძველ პროექტებში ხშირად დაფიქსირებულია utf8mb4_unicode_ci, რაც კარგია, მაგრამ ყველა სხვა ცხრილს უნდა ემთხვეოდეს, რომ ქვემოთ აღწერილი შერეული collation-ის შეცდომა აიცილო. Django-ს MySQL backend იყენებს OPTIONS-ის charset გასაღებს. WordPress wp-config.php-ში აყენებს DB_CHARSET-სა და DB_COLLATE-ს და 4.2 ვერსიიდან utf8mb4-ს იყენებს; ძველ საიტს, რომელიც იმ განახლებამდე არსებობდა, შეიძლება ჯერ კიდევ ჰქონდეს utf8mb3-ში ცხრილები, რომლებიც განახლების პროცედურამ index-ის სიგრძის ლიმიტების გამო გამოტოვა. ყველა შემთხვევაში framework-ის პარამეტრი და ცხრილების რეალური განსაზღვრებები ერთმანეთს უნდა ემთხვეოდეს - პარამეტრი მხოლოდ იმაზე მოქმედებს, რასაც framework შემდეგ შექმნის.
Collation-ის შეცდომები და მათი გამოსწორება#
ERROR 1267 (HY000): Illegal mix of collations (utf8mb4_unicode_ci,IMPLICIT) and(utf8mb4_0900_ai_ci,IMPLICIT) for operation '='განსხვავებული collation-ის მქონე ორი სვეტი join-ში ან WHERE-ში ედრება. ეს ჩვეულებრივ ნაწილობრივი migration-ის შემდეგ ხდება: ძველი ცხრილები utf8mb4_unicode_ci-ში, ახლები 8.0-ის ნაგულისხმევში. დარჩენილი ცხრილების ერთ collation-ზე გადაყვანა ნამდვილი გამოსწორებაა; COLLATE utf8mb4_0900_ai_ci შედარების ერთ მხარეს სწრაფი გამოსწორებაა და იმ მხარეს index-ის გამოყენებას უშლის ხელს.
ERROR 1273 (HY000): Unknown collation: 'utf8mb4_0900_ai_ci'MySQL 8-ის dump იტვირთება MySQL 5.7-ში ან სხვა ოჯახის სერვერში. 0900 collation-ები მხოლოდ MySQL 8-ში არსებობს. თუ შეგიძლია, MySQL 8-ში აღადგინე; სხვა შემთხვევაში collation-ის სახელი მთელ dump-ში ჩაანაცვლე. MySQL-ის გადატანა ახალ ჰოსტზე ვერსიების შეუსაბამობას ზოგადად განიხილავს.
FAQ#
utf8mb4_unicode_ci გამოვიყენო თუ utf8mb4_0900_ai_ci?
MySQL 8-ზე - utf8mb4_0900_ai_ci. ის Unicode-ის წესების უფრო ახალ ვერსიას მიჰყვება, ასხვავებს emoji-სა და სხვა ოთხბაიტიან სიმბოლოებს და MySQL 8-ის იმპლემენტაციაში უფრო სწრაფია. unicode_ci მხოლოდ იქ დატოვე, სადაც ბაზა MySQL 5.7-შიც ან სხვა ოჯახის სერვერშიც უნდა ჩაიტვირთოს, რომელსაც 0900 collation-ები არ აქვს.
utf8mb4 utf8-ზე მეტ ადგილს იკავებს?
იმავე ტექსტისთვის - არა. UTF-8 ყოველ სიმბოლოს იმდენ ბაიტში ინახავს, რამდენიც სჭირდება, ასე რომ ASCII ორივეში ერთი ბაიტია. განსხვავება მხოლოდ ის სიმბოლოებია, რომლებსაც utf8mb3 საერთოდ ვერ ინახავს. იზრდება index-ებისა და მეხსიერებაში მყოფი დროებითი ცხრილებისთვის დარეზერვებული ზომა, რომლებიც სიმბოლოზე ოთხ ბაიტს ვარაუდობს.
რატომ ვხედავ კითხვის ნიშნებს emoji-ს ნაცვლად?
ტექსტმა გაიარა რაღაც, რაც utf8mb4 არ არის - სვეტი, ცხრილი ან, ყველაზე ხშირად, კავშირი - და MySQL მკაცრ რეჟიმში არ იყო, ამიტომ სიმბოლოები უარყოფის ნაცვლად ჩაანაცვლა. შეამოწმე სვეტი SHOW CREATE TABLE-ით, კავშირი SHOW SESSION VARIABLES LIKE 'character_set_%'-ით და დააყენე charset=utf8mb4 დრაივერში.
შემიძლია ერთი query რეგისტრის მიმართ მგრძნობიარე გავხადო სვეტის შეცვლის გარეშე?
კი: WHERE code = 'AbC' COLLATE utf8mb4_0900_as_cs. მუშაობს, მაგრამ ვერ იყენებს სვეტის საკუთარი collation-ით აგებულ index-ს, ამიტომ scan-ს აკეთებს. სვეტისთვის, რომელიც ყოველთვის რეგისტრის გათვალისწინებით ედრება, მის ნაცვლად collation შეცვალე.
ALTER DATABASE ჩემს ცხრილებს გარდაქმნის?
არა. ის მხოლოდ შემდეგ შექმნილი ცხრილების ნაგულისხმევს ცვლის. არსებული ცხრილები და მათი სვეტები თავიანთ სიმბოლოების ნაკრებს ინარჩუნებს, სანამ თითოეულზე ALTER TABLE ... CONVERT TO-ს არ გაუშვებ.




კომენტარები
სრულიად ანონიმურად: ანგარიშის, ელფოსტის და cookie-ის გარეშე. ინახება მხოლოდ სახელი, ტექსტი და დრო - სხვა არაფერი. ბმულების რაოდენობა ლიმიტირებულია.