Arxiv

Archive for İ

AUTO_INCREMENT

AUTO_INCREMENT-dən mənə elə gəlir ki, hamı istifadə edir çox məhşurdur. Artıq əl də öyrəşib id int AUTO_INCREMENT yazmağa. Bir çox maraqlı xüsusiyyətləri var ki, onları yazmağa çalışıram.
Bəli Adı üstündə auto increment yəni avtomatik artırma. Bu attribute bizləri, əziyyətli manual increment-dən azad edir. Həqiqətən də çox işimizə yarayır. Adi misallarla izah etməyə çalışaq. Table yaradaq:

create table auto_increment_test (
    id int auto_increment,
    name varchar(10)
);

🙂 ERROR-da da deyildiyi kimi, AUTO_INCREMENT olan column mütləq index-lənməlidir(ordakı key bu mənadadır). Bu index də adətən\həmişə PRİMARY KEY olur.

mysql> create table auto_increment_test (
    ->     id int auto_increment,
    ->     name varchar(10),
    ->     primary key (id)
    -> );
Query OK, 0 rows affected (0.15 sec)

Table yaratdıq indi də onun üzərində biraz işləyək.
İnsert edək:

insert into auto_increment_test(name) values('Shahriyar');

insert into auto_increment_test(name) values('Orxan');

insert into auto_increment_test(name) values('Elvin');

Və select edək:

mysql> select * from auto_increment_test;
+----+-----------+
| id | name      |
+----+-----------+
|  1 | Shahriyar |
|  2 | Orxan     |
|  3 | Elvin     |
+----+-----------+
3 rows in set (0.00 sec)

Həqiqətən də görürük ki, AUTO_INCREMENT İD-ni avtomatik artırır…Çox əlverişlidir…Manual olaraq:

insert into auto_increment_test(id,name) values(1,'Shahriyar');

insert into auto_increment_test(id,name) values(2,'Orxan');

insert into auto_increment_test(id,name) values(3,'Elvin');

yazmağa ehtiyac yoxdu…
İnsert-lərimizə dava edək:


insert into auto_increment_test(id,name) values(NULL,'Vusal');

insert into auto_increment_test(id,name) values(0,'Natiq');

mysql> select * from auto_increment_test;
+----+-----------+
| id | name      |
+----+-----------+
|  1 | Shahriyar |
|  2 | Orxan     |
|  3 | Elvin     |
|  4 | Vusal     |
|  5 | Natiq     |
+----+-----------+
5 rows in set (0.00 sec)

Gördüyümüz kimi AUTO_INCREMENT-li column-a 0 və NULL insert etmək istədikdə, 0 və NULL sadəcə iqnor edilir və adi qaydada avtomatik artırma baş verir.
*****************************************
İndiki halda bizim table-da 5 id var, yəni bunlar 1,2,3,4,5-dir…Indi isə İD-si 5 olan yəni sonuncı record-u silək:

delete from auto_increment_test where id=5;

mysql> select * from auto_increment_test;
+----+-----------+
| id | name      |
+----+-----------+
|  1 | Shahriyar |
|  2 | Orxan     |
|  3 | Elvin     |
|  4 | Vusal     |
+----+-----------+
4 rows in set (0.00 sec)

Və yeni bir insert edək:

insert into auto_increment_test(name) values('Mahmud');

mysql> select * from auto_increment_test;
+----+-----------+
| id | name      |
+----+-----------+
|  1 | Shahriyar |
|  2 | Orxan     |
|  3 | Elvin     |
|  4 | Vusal     |
|  6 | Mahmud    |
+----+-----------+
5 rows in set (0.00 sec)

Bəli yeni İD=6 oldu…Əslində fikirləşmək olardı ki, 4-dən sonra 5 gəlir və yeni İD də 5 olacaq amma baxmayaraq ki biz İD=5-i sildik MySQL internal olaraq increment-i yadda saxlayır…Yəni table-dan silinsə belə bir sonrakı increment məhz o silinən yerdən başlayır.

Mövzunu davam etdirək…Update edərək İD-3 olan recordun İD-sini=15 edək:

update auto_increment_test set id=15 where name='Elvin';

mysql> select * from auto_increment_test;
+----+-----------+
| id | name      |
+----+-----------+
|  1 | Shahriyar |
|  2 | Orxan     |
|  4 | Vusal     |
|  6 | Mahmud    |
| 15 | Elvin     |
+----+-----------+
5 rows in set (0.00 sec)

daha sonra insert edək:


insert into auto_increment_test(name) values('Necef');

mysql> select * from auto_increment_test;
+----+-----------+
| id | name      |
+----+-----------+
|  1 | Shahriyar |
|  2 | Orxan     |
|  4 | Vusal     |
|  6 | Mahmud    |
|  7 | Necef     |
| 15 | Elvin     |
+----+-----------+
6 rows in set (0.00 sec)

Qəribədir 🙂 Əslində mən də gözləyirdim ki, yeni İD=16 olacaq çünki sonuncu İD=15 idi amma yox elə olmadı..Məncə Update zamanı biz İD-ni birbaşa qeyd etdiyimiz üçün bu zaman MySQL bunu increment kimi qəbul etmir və öz implicit increment-inə qaldığı yerdən davam edir.
İndi isə İD-ni biz explicit olaraq insert zamanı verək:

insert into auto_increment_test(id,name) values(20,'Behmen');

mysql> select * from auto_increment_test;
+----+-----------+
| id | name      |
+----+-----------+
|  1 | Shahriyar |
|  2 | Orxan     |
|  4 | Vusal     |
|  6 | Mahmud    |
|  7 | Necef     |
| 15 | Elvin     |
| 20 | Behmen    |
+----+-----------+
7 rows in set (0.00 sec)

Və daha sonra da adi qaydada insert verək:

insert into auto_increment_test(name) values('Resad');

mysql> select * from auto_increment_test;
+----+-----------+
| id | name      |
+----+-----------+
|  1 | Shahriyar |
|  2 | Orxan     |
|  4 | Vusal     |
|  6 | Mahmud    |
|  7 | Necef     |
| 15 | Elvin     |
| 20 | Behmen    |
| 21 | Resad     |
+----+-----------+
8 rows in set (0.00 sec)

İndi isə bayaqkının tam əksi olaraq təzə İD=21-dir 🙂 Explicit insert zamanı yəqin ki, MySQL-in implicit increment saygaci həmin yeni İD-yə keçir və məhz bu səbəbdəndir ki,yeni insert-lər zamanı increment yeni İD-dən başlayır.
****************************************
Daha bir maraqlı hadisə var. Bəs deyək ki, update vasitəsilə hər hansı bir İD-yə NULL qiymətini vermək istəyirik onda nə baş verəcək:

update auto_increment_test set id=null where name='Vusal';

mysql> select * from auto_increment_test;
+----+-----------+
| id | name      |
+----+-----------+
|  0 | Vusal     |
|  1 | Shahriyar |
|  2 | Orxan     |
|  6 | Mahmud    |
|  7 | Necef     |
| 15 | Elvin     |
| 20 | Behmen    |
| 21 | Resad     |
+----+-----------+
8 rows in set (0.00 sec)

Görürük ki, bu zaman yuxarıda bir yerlərdə qeyd etdiyimiz kimi NULL iqnor edilib, əvəzinə adi qaydada auto increment olunmur…İndiki halda NULL iqnor edilir və İD-nin qiyməti =0 olur. Və həmçinin Warning də qeydə alınır.

show warnings;

Warning', '1048', 'Column \'id\' cannot be null'

Çünki auto_increment column NOT NULL-dur. Yəni NULL qiymətlər qəbul edə bilməz…
Mövzuda Əsas yerlərə toxunduq 1 xırda mövzu qalıb ki onu da documentation-dan copy eliyib atıram bura :

When you reach the upper limit of an AUTO_INCREMENT column, an attempt to generate the next sequence value results in a duplicate-key error. This is a manifestation of MySQL’s general out-of-range value clipping behavior. For example, assume that you have a TINYINT UNSIGNED column as an AUTO_INCREMENT column and that it currently contains 254 as the maximum sequence value. The upper limit for this data type is 255, so the next insert generates a sequence value of 255 and successfully stores it in the new record. However, the insert after that fails because MySQL generates the next sequence value, which is 256. Because 256 is higher than the column’s upper limit of 255, MySQL clips 256 down to 255 and attempts to insert that value. But because 255 is already present in the table, a duplicate-key error occurs.”

Təşəkkürlər 🙂

Kateqoriyalar: MySQL Etiketlər: , ,

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 🙂

Using Script Files with mysql

Adətən sorğuları və.s əllə yazırıq ama MySQL bunları həm də hər hansı file-dan da oxuya bilir. Bu həm adi .txt, həm də .sql file ola bilər. Maraqlı hadisə var onu paylaşmaq istəyirəm 🙂
2 table lazım olacaq bizə.

create table singer (
    id int not null auto_increment,
    name varchar(12),
    primary key (id)
);

insert into singer(name) values('Shakira'),('Rihanna'),('Nicole');

CREATE TABLE composer (
    id int(11) NOT NULL AUTO_INCREMENT,
    name varchar(15),
    lastname varchar(25),
    PRIMARY KEY (id)
); 

insert into composer(name,lastname) values('Emin','Sabitoglu'),('Fikret','Emirov'),('Xanim','Ismayilqizi');


Və indi də bir fayl yaradaq faylın adı məndə batch_file…adi .txt file-dır.
File-da yazılıb:

use music;

select * from composer;

və bu file-ı oxuyaq

mysql> source /home/shahriyar/batch_file

Database changed
+----+--------+-------------+
| id | name   | lastname    |
+----+--------+-------------+
|  1 | Emin   | Sabitoglu   |
|  2 | Fikret | Emirov      |
|  3 | Xanim  | Ismayilqizi |
+----+--------+-------------+
3 rows in set (0.00 sec)

File-da olan butun sorğular ardıcıllıqla icra olundu.
İndi isə 2ci file-ımızı yaradaq və 1ci-dən o birinə məhz elə source vasitəsilə keçid qoyaq (əgər belə demək mümükündürsə). Yəni biz bir komanda ilə 2 file oxuyacıq 🙂 1ci faylımız batch_file:

use music;

select * from composer;

source /home/shahriyar/batch_file2

2ci fayl batch_file2:

select * from singer;

Və oxuyaq:

mysql> source /home/shahriyar/batch_file
Database changed
+----+--------+-------------+
| id | name   | lastname    |
+----+--------+-------------+
|  1 | Emin   | Sabitoglu   |
|  2 | Fikret | Emirov      |
|  3 | Xanim  | Ismayilqizi |
+----+--------+-------------+
3 rows in set (0.00 sec)

+----+---------+
| id | name    |
+----+---------+
|  1 | Shakira |
|  2 | Rihanna |
|  3 | Nicole  |
+----+---------+
3 rows in set (0.00 sec)

Və bu şəkildə biz sonsuz sayda fayllara keçid qoya-qoya gedə bilərik. Ama mən sınaq üçün 2 faylda bir-birinə keçid qoydum 🙂

1ci faylımız batch_file:

use music;

select * from composer;

source /home/shahriyar/batch_file2

2ci faylımız batch_file2:

select * from singer;

source /home/shahriyar/batch_file

Və yenidən oxumağa çalışsaq görərik ki, 1ci fayl 2cini 2ci fayl birincini aca-aca gedir. Yani hər 2 fayl bir-birinə keçir. Və nəticədə aşağıdakı error çıxır:

ERROR: 
Failed to open file '/home/shahriyar/batch_file', error: 24

Error nömrəmiz 24-dür. MySQL-də faydalı utility var ismi perror 🙂 onunla bu error-un nə olduğunu müəyyənləşdirək:

[shahriyar@sh ~]$ perror 24
OS error code  24:  Too many open files

Həqiqətən də too many file açdıq…Təşəkkürlər 🙂

Kateqoriyalar: MySQL Etiketlər: , , ,

MySQL-in Fedora 17-yə qurulması

Dünən Windows 7 yerinə Fedora 17 yazdım. Çox xoşuma gəldi heyratamizdir.
Və dərhal da mənə lazım olanları yazmağa çalışdım. Bu yazı MySQL server 5.5.28-in Fedora 17-yə qurulması haqqındadır. Komandaları ardıcıl daxil edərək buna çox asand nail olunur, onsuz da mən də heç başa düşmürəm nə komandalarıdır:)

*)
ilk öncə root olaraq qoşuluruq

su -

*)
daha sonra Remi Repository-ni install edirik


rpm -Uvh http://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-stable.noarch.rpm 

rpm -Uvh http://download1.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-stable.noarch.rpm
rpm -Uvh http://rpms.famillecollet.com/remi-release-17.rpm

*)
Daha sonra MySQL-in hansı versiyalarının mövcud olduğuna baxırıq.

yum --enablerepo=remi list mysql mysql-server

*)
Və install edirik.

yum --enablerepo=remi install mysql mysql-server

*)

Complete!

Gördükdən sonra, MySQL-i start edirik:

systemctl start mysqld.service

və dərhal da root user-in parolunu dəyişirik.

mysqladmin -u root password [sizin_parolunuz]
 
## Misal üçün bax belə ##
mysqladmin -u root password zzzzzz

Yoxlamaq üçün connect oluruq.

[shahriyar@sh ~]$ mysql -u root -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 6
Server version: 5.5.28 MySQL Community Server (GPL) by Remi

Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

Hazırdı… Təşəkkürlər 🙂

Kateqoriyalar: Linux Etiketlər: , ,