Əsas səhifə > MySQL > UTF8 vs. Latin1

UTF8 vs. Latin1

Əslində mövzunun adı uzun olmasın deyə UTF8 vs. Latin1 qoymuşam amma əsl adı “utf8 unicode problemleri çıxan insanların SET NAMES ‘utf8’ yazaraq həll yolu axtarmalarının hazin öyküsü” olmalı idi 😀
Həqiqətən də bu cür problemləri çıxan insanlara ilkin məsləhət SET NAMES ‘utf8’ olur…olmağına olur ee amma nətər? Gəlin baxaq 😛 (Əvvəldən Axıra oxumağa həvəs yoxdusa mövzunun sonuna diqqət edin!)
*)
İlk öncə system variable və session variable anlayışlarını aydınlaşdıraq. system variable—mysql server-e qoşulan bütün user-ləri əhatə edir, adı üstündə system. session variable isə yalnız həmin user-in sessiyasını əhatələyir.
Bəli məhz bu SET NAMES session variable dəyişir. SET NAMES ‘utf8’ yazmaq eyni ilə

SET character_set_client = utf8;
SET character_set_results = utf8;
SET character_set_connection = utf8;

və yaxud

SET @@session.character_set_client = utf8;
SET @@session.character_set_results = utf8;
SET @@session.character_set_connection = utf8;

yazmaq kimidir.

Söhbətin doğruluğunu yoxlamaq məqsədilə:

mysql> set names 'utf8';
Query OK, 0 rows affected (0.00 sec)

mysql> select @@session.character_set_client,
    -> @@session.character_set_results,
    -> @@session.character_set_connection\G
*************************** 1. row ***************************
    @@session.character_set_client: utf8
   @@session.character_set_results: utf8
@@session.character_set_connection: utf8
1 row in set (0.00 sec)

Bundan sonra sevinə-sevinə table yaradaq və insert edək:

mysql> create table test4(
    -> id int,
    -> istifadəçi_adı varchar(10)
    -> );
Query OK, 0 rows affected (0.17 sec)

mysql> insert into test4(id,istifadəçi_adı) values(1,'Şəhriyar');
Query OK, 1 row affected, 1 warning (0.12 sec)

mysql> select * from test4;
+------+-------------------+
| id   | istifadəçi_adı    |
+------+-------------------+
|    1 | ??hriyar          |
+------+-------------------+
1 row in set (0.00 sec)

screen_shot1

Bəli burdan belə bir dəhşətli nəticəyə gəlmək olar ki, SET NAMES ‘utf8’ yalnız column adlarını UTF8-ə çevirib bizə göstərir, column içindəki məlumatı YOX! SET NAMES ‘latin1’ yazsaq :

mysql> set names 'latin1';
Query OK, 0 rows affected (0.00 sec)

mysql> select * from test4;
+------+----------------+
| id   | istifad?�i_ad?  |
+------+----------------+
|    1 | ??hriyar       |
+------+----------------+
1 row in set (0.00 sec)

screenshot2

Eyni nəticələri biz system variable-lları dəyişdikdə də alacıq. burda artıq SET NAMES işləməyəcək. Onu da deyim ki bu system variable-lar default olaraq latin1-dədir.

mysql> select @@global.character_set_client,
    -> @@global.character_set_results,
    -> @@global.character_set_connection\G
*************************** 1. row ***************************
    @@global.character_set_client: latin1
   @@global.character_set_results: latin1
@@global.character_set_connection: latin1
1 row in set (0.00 sec)

MySQL Workbench system variables-dan da baxdıqda eyni görünür:

screenshot4

Olduğu kimi saxlayaq və select verək:

mysql> select * from test4;
+------+-------------------+
| id   | istifadəçi_adı    |   /* column adı UTF8-də görsənir */
+------+-------------------+
|    1 | ??hriyar          |   /* column içindəki məlumat yenə UTF8-də görsənmir */
+------+-------------------+   
1 row in set (0.00 sec)

system/global variable-ı dəyişək UTF8 edək.

mysql> set @@global.character_set_client=utf8;
Query OK, 0 rows affected (0.00 sec)

mysql> set @@global.character_set_client=utf8;
Query OK, 0 rows affected (0.00 sec)

mysql> set @@global.character_set_client=utf8;
Query OK, 0 rows affected (0.00 sec)

Və select verək:

mysql> select * from test4;
+------+-------------------+
| id   | istifadəçi_adı    |   /* column adı UTF8-də görsənir */
+------+-------------------+
|    1 | ??hriyar          |   /* column içindəki məlumat yenə UTF8-də görsənmir */
+------+-------------------+
1 row in set (0.00 sec)

adama deyərlər ki, latin1-də də UTF8-də “istifadəçi_adı” (column oz adi) qəşəngcə azərbaycan şriftləri şəklində görsəndi axı…Bəli həqiqətən də qəribədir…Mən də gözləyirdim ki latin1-də istifad?�i_ad?—bu cür görsənsin amma mən day görsənmir dəəə 🙂 Səbəb olaraq ilk ağlıma gələn bu oldu ki, ola bilsin user connect olanda ilk olaraq session variable-ı oxuyur daha sonra global-a baxır. Yoxladım və həqiqətən də elə çıxdı. Məndə session variabl-lar default olaraq UTF8-dədir. Məhz buna görə də global variabl-ları dəyişsək belə hər zaman “istifadəçi_adı” düzgün şəkildə görsənəcək.

mysql> \q
Bye
[shahriyar@sh ~]$ mysql -u monty -p
.
.
.
mysql> select @@session.character_set_client, @@session.character_set_results,@@session.character_set_connection\G
*************************** 1. row ***************************
    @@session.character_set_client: utf8
   @@session.character_set_results: utf8
@@session.character_set_connection: utf8
1 row in set (0.00 sec)

Biraz mövzudan yayındıq ama yenə də SET NAMES-in table içindəki məlumatların kodirovkasını dəyişdirmədiyini görürük. Əsas məqsəd də elə bu idi… 😀
Axırıncı və sonuncu dəfə bunu deyə bilərəm ki, əgər database-də UTF8 dəstəyi istəyirsinizsə
1.ya onu install edərkən default charset UTF8 seçin,
2.yox bunu etməmisinizsə my.cnf-də dəyişiklik edin

Stackoverflow

Character Set Configuration

3. Table yaradarkən onun sonuna default charset=utf8 əlavə edin:

create table test5 (
    id int,
    user_name varchar(10)
)  default charset=utf8;

4. Əgər hazır table-ınız varsa və onu silib yerinə təzə UTF8 dəstəklisini yaratmaq istəmirsinizsə onda ALTER-dən istifadə edin:

Table Character Set and Collation

mysql> alter table test3 default charset utf8;
Query OK, 1 row affected (0.39 sec)
Records: 1  Duplicates: 0  Warnings: 0
.
.
.
mysql> show create table test3\G
*************************** 1. row ***************************
       Table: test3
Create Table: CREATE TABLE `test3` (
  `id` int(11) DEFAULT NULL,
  `user_name` varchar(10) CHARACTER SET latin1 DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

Hətta ALTER vasitəsilə ayrıca column-un belə charset-ini dəyişmək olur:

mysql> alter table test3 modify user_name varchar(8) charset utf8;
Query OK, 3 rows affected (0.30 sec)
Records: 3  Duplicates: 0  Warnings: 0

Column Character Set Conversion

Ümidvaram ki, Bu dəhşətli həmişə soruşulan Unicode probleminə birazca da olsa aydınlıq gəldi. Təşəkkürlər 🙂

  1. Heç bir şərh yoxdur.
  1. No trackbacks yet.

Bir şərh yazın