Arxiv

Archive for İ

Exploring Sequence in Oracle and MySQL

Bu yazıda hər 2 RDBMS-də Sequence (ardıcıllıq) anlayışlarına baxacıq.
İstifadə olunan versiyalar Oracle 11g R2, MySQL 5.6.x.
İlk öncə biraz teorik məlumatlar.
Sequence avtomatik olaraq bizim yerimizə, DB tərəfindən yaradılan unique rəqəmlər ardıcıllığıdır.
Çox zaman Primary Key (id) column-lar üçün istifadə olunan bu rəqəmlər, bizə təkrarsız ardıcıllıq verir ki, PK anlayışı da elə bundan ibarətdir.
Dolayısı ilə çox faydalıdır və demək olar ki əhəmiyyətli bütün cədvəllərdə istifadə olunur.
Ilk öncə Oracle-dan başlayacıq. Nümunə cədvəlimiz:

-- Oracle

create table t1(
id numeric,
firstname varchar2(25),
lastname varchar2(25),
primary key(id)
);

Gördüyümüz kimi, id bizdə PK-dır və biz istəyirik ki, hər dəfə ardıcıl ədədlər insert olunsun.
Sequence yaradaq:

create sequence id_seq;
>>>
sequence ID_SEQ created.

Yuxarıdakı create-imiz faktiki olaraq default olaraq aşağıdakı kimi icra olundu:

CREATE SEQUENCE  
"HR"."ID_SEQ"  
MINVALUE 1
MAXVALUE 9999999999999999999999999999
INCREMENT BY 1 
START WITH 1 
CACHE 20 
NOORDER  
NOCYCLE ;

Bunu biraz izah edək. Default sequence creation:
* “HR”.”ID_SEQ” = burdan təbii ki, aydın olur ki, bizim sequence owner-i HR-dır.
* MINVALUE 1 = yəni bizim sequence-in minimum qiyməti 1 ola bilər.
* MAXVALUE 9999999999999999999999999999 = maximum qiymət
* INCREMENT BY 1 = yəni 1-1 artır.
* START WITH 1 = artırmağa 1-dən başla
* CACHE 20 = hər növbəti 20 ardıcıllığı cache-də saxla
* NOORDER = only relevant to clustered database
* NOCYCLE = dövr etmə. MINVALUE və yaxud MAXVALUE-ya çatdıqda error verəcək.

Və çox zaman elə bizə lazım olan göstəricilərlə sequence yaradıldı. Təkcə performance üçün CACHE size-ı artıra bilərsiniz.

* QEYD N1:
Sequence heç bir cədvələ təhkim olunmur, rollback və yaxud commit-ə tabe deyildir, hər hansı transaction-dan azaddır müstəqil olaraq artır.
*

Yuxarıdakı qeyddən belə nəticə çıxır ki, əgər 1 cədvəl üçün 10 ardıcıl rəqəm generate olunubsa 2ci bir cədvəl bundan sonra sequence-dən istifadə etsə 11-dən başlamalı olacaq.
Praktiki istifadəsinə baxaq. Sequence-dən ardıcıl rəqəmi əldə etmək məqsədilə nextval-dan istifadə etmək lazımdır:

insert into t1(id,firstname,lastname) values(id_seq.nextval,'shahriyar','rzayev');

Məlumata baxırıq:

SQL> select * from t1;

	ID FIRSTNAME		     LASTNAME
---------- ------------------------- -------------------------
	 1 shahriyar		     rzayev

Eyni datanı 5 dəfə daha insert edək.

SQL> select * from t1;

	ID FIRSTNAME		     LASTNAME
---------- ------------------------- -------------------------
	 1 shahriyar		     rzayev
	 2 shahriyar		     rzayev
	 3 shahriyar		     rzayev
	 4 shahriyar		     rzayev
	 5 shahriyar		     rzayev
	 6 shahriyar		     rzayev

6 rows selected.

Dahiyanə işləyir 😉

Sequence creation üzərində işləyərək artımın hansı ardıcıllıqla nədən başlayacağını və.s təyin edə bilərik.

Məsələn aşağıdakı sequence 10-dan 5-5 arta-arta davam edir.

-- 1
create sequence id_seq2 start with 10 increment by 5;

-- 2
truncate table t1;

-- 3
insert into t1(id,firstname,lastname) values(id_seq2.nextval,'shahriyar','rzayev');
insert into t1(id,firstname,lastname) values(id_seq2.nextval,'shahriyar','rzayev');
insert into t1(id,firstname,lastname) values(id_seq2.nextval,'shahriyar','rzayev');
-- 4

SQL> select * from t1;

	ID FIRSTNAME		     LASTNAME
---------- ------------------------- -------------------------
	10 shahriyar		     rzayev
	15 shahriyar		     rzayev
	20 shahriyar		     rzayev

* QEYD N2:
Sequence sıfırlamaq mümkün deyildir, bunun yeganə üsulu sequenci droplamaq və yenidən yaratmaqdır.
*

Burdan belə nəticə çıxır ki, hər hansı cədvəldə delete-dən yaranmış gap-ləri reorder etməklə doldurmaq mümkün deyil.
Yəni, 1, 2, 3, 4, 5, 20, 50 — gəlirsə deməli elə də gedəcək.

İndi isə MySQL-də sequence anlayışına baxaq..
AUTO_İNCREMENT = SEQUENCE.
MySQL-də fərqlər:
* AUTO_İNCREMENT hər cədvələ təhkim olunur.
* PK olmayan column-da create oluna bilmir.
* insert etdikdə auto_increment column-u qeyd etməyə ehtiyac yoxdur.
* NULL insert etdikdə increment olunaraq yeni value insert olunur.
* Ardıcıllığı reorder etmək olur.
və.s

Digər fərqlərə də baxacıq.
Nümunə cədvəlimiz:

-- MySQL

create table t1(
id int not null auto_increment,
firstname varchar(25),
lastname varchar(25),
primary key(id)
);

Gördüyümüz kimi, PK olan İD column-a cədvəli yaradarkən qeyd olunur.
İnsertlər edək:

insert into t1(firstname,lastname) values('shahriyar','rzayev');
insert into t1(firstname,lastname) values('shahriyar','rzayev');
insert into t1(firstname,lastname) values('shahriyar','rzayev');
insert into t1(firstname,lastname) values('shahriyar','rzayev');
insert into t1(firstname,lastname) values('shahriyar','rzayev');

mysql> select * from t1;
+----+-----------+----------+
| id | firstname | lastname |
+----+-----------+----------+
|  1 | shahriyar | rzayev   |
|  2 | shahriyar | rzayev   |
|  3 | shahriyar | rzayev   |
|  4 | shahriyar | rzayev   |
|  5 | shahriyar | rzayev   |
+----+-----------+----------+
5 rows in set (0.00 sec)

İnsert zamanı İD column-u qeyd etmədik.
İndi isə İD 3 və 4 olan sətrləri silək:

-- 1

delete from t1 where id=3 or id=4;

-- 2

mysql> select * from t1;
+----+-----------+----------+
| id | firstname | lastname |
+----+-----------+----------+
|  1 | shahriyar | rzayev   |
|  2 | shahriyar | rzayev   |
|  5 | shahriyar | rzayev   |
+----+-----------+----------+
3 rows in set (0.00 sec)

1, 2, 5 = biz istəyirik ki, 1, 2, 3 kimi sıralansın.

-- 1
ALTER TABLE t1 DROP `id`;

-- 2
ALTER TABLE t1 AUTO_INCREMENT = 1;

-- 3
ALTER TABLE t1 ADD `id` int NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST;

mysql> select * from t1;
+----+-----------+----------+
| id | firstname | lastname |
+----+-----------+----------+
|  1 | shahriyar | rzayev   |
|  2 | shahriyar | rzayev   |
|  3 | shahriyar | rzayev   |

Çox gözəl məqsədə çatdıq.
Oracle-da göstərdiyimiz kimi, MySQL-də də sequence-in hansı ədəddən başlıyacağını və nə qədər artacağını göstərə bilərik. Burda maraqlı məqam ondan ibarətdir ki, Global və Session olaraq verə bilərik. Global olaraq verildikdə RDBMS-də bütün cədvəllərdə olan auto_increment-lərə şamil olunacaq. Session based isə təbii ki, yalnız aktiv sessiya üçün geçərlidir.

-- 1 

mysql> set @@session.auto_increment_increment=10;
Query OK, 0 rows affected (0.01 sec)

-- 2

mysql> set @@session.auto_increment_offset=5;
Query OK, 0 rows affected (0.00 sec)

-- 3
drop table t1;

-- 4

create table t1(
id int not null auto_increment,
firstname varchar(25),
lastname varchar(25),
primary key(id)
);

-- 5

mysql> insert into t1(firstname,lastname) values('shahriyar','rzayev'),('shahriyar','rzayev'),('shahriyar','rzayev'),('shahriyar','rzayev');
Query OK, 4 rows affected (0.05 sec)
Records: 4  Duplicates: 0  Warnings: 0

-- 6

mysql> select * from t1;
+----+-----------+----------+
| id | firstname | lastname |
+----+-----------+----------+
|  5 | shahriyar | rzayev   |
| 15 | shahriyar | rzayev   |
| 25 | shahriyar | rzayev   |
| 35 | shahriyar | rzayev   |
+----+-----------+----------+
4 rows in set (0.00 sec)

Beləliklə auto_increment_incrementauto_increment_offset system dəyişənlərinin köməyi ilə biz 5-dən başlayaraq 10-10 artım əldə etdik.

Düşünürəm ki, ümumi mövzumuzu yekunlaşdırdıq.

Təşəkkürlər 😉