Əsas səhifə > MySQL, Oracle, Oracle SQL > Constraints in Oracle and MySQL

Constraints in Oracle and MySQL

Constraint-lər bizə business qaydalarımızı cədvəllərimizdə təyin etməyə kömək edən vasitələrdir.
Sadə dillə izah etməyə çalışsaq məsələn,
Deyək ki, bizim bussines qaydamız tələb edir ki, bütün soyadlar təkrarsız olsun, bütün date-lər yalnız 2013-cü ildən böyük olsun, və yaxud da bütün istifadəçi yaşları yalnız 23-dən böyük olsun və.s
Bu kimi istəklərimizi cədvəldə constraintlər yaratmaqla həll etmiş oluruq. və yalnız bizim bu business rule-a uyğun gələn data-lar cədvələ daxil edilə biləcək.

Oracle-da aşağıdakı constraint-lər var:

UNİQUE
NOT NULL
PRİMARY KEY
FOREİGN KEY
CHECK

UNİQUE:

UNİQUE constraint adından da göründüyü kimi, ya 1 column ya da column qruplarının unikal məlumatlarla doldurulmasını təmin edir. Dolayısı ilə 1 dəfə daxil edilən məlumat 2ci dəfə ora düşə bilməz. Öz işinə görə PRİMARY KEY-ə bənzəyən UNİQUE-ın yeganə fərqi NULL datanın daxil edilməsinə icazə verməsidir. Burdan belə nəticə çıxır ki, NULL unikal sayılmır, həmçinin sonsuz sayda NULL insert etmək olar.
Burdan daha bir nəticə çıxır ki, PK(primary key) = unique + not null.

Digər tərəfdən onu da qeyd etməliyik ki, unique constraint təyin edilmiş column-lar index-li olur. Yəni, unique constraint yaradıldıqda, Oracle column-da index-in olub olmadığına baxacaq. Əgər index tapılmasa onu avtomatik olaraq yaradacaq.
Daha bir dolayı nəticəmiz bundan ibarətdir ki, unique = index + constraint.

UNİQUE ilə bağlı daha bir məlumatı da verməliyik ki, B*TREE index-lər NULL-u əhatə etmir.
Burdan belə nəticə çıxarırıq ki əgər biz cədvəldə NULL məlumat axtarsaq index istifadə olunmayacaq bu da full table scan-a gətirib çıxardacaq. Full scan ise performance killer hesab olunur.

Teorik məlumatdan sonra keçək praktikaya:

-- Oracle

-- UNİQUE

-- Syntax 1

create table t20(
id number,
firstname varchar2(15),
lastname varchar2(15),
unique key(id)
);

>>>
Error report -
SQL Error: ORA-00906: missing left parenthesis
00906. 00000 -  "missing left parenthesis"
*Cause:    
*Action:

-- Syntax 2

create table t20(
id number,
firstname varchar2(15),
lastname varchar2(15),
unique(id)
);

>>>
table T20 created.

-- Syntax 3

create table t20(
id number unique,
firstname varchar2(15),
lastname varchar2(15)
);

>>>
table T20 created.

Yuxarıdakı 3 syntax-dan 2si Oracle-da dəstəklənir.
İndi isə yaranmış constraint haqqında məlumatları əldə etmək üçün kiçik sorğudan istifadə edək.

— Oracle

select 
constraint_name,
constraint_type
from USER_CONSTRAINTS where table_name='T20';

>>>
SYS_C0011585	U

SYS_C0011585 = unique constraint-in internal generate olunan adıdır.

Əgər spesifik ad vermək istəyiriksə ki bu çox faydalı hesab olunur:

create table t20(
id number,
firstname varchar2(15),
lastname varchar2(15),
constraint id_unikal unique(id)
);

select 
constraint_name,
constraint_type
from USER_CONSTRAINTS where table_name='T20';

>>>
ID_UNIKAL	U

İndi isə eyni testləri MySQL-də edək.

-- MySQL

-- Syntax 1

mysql> create table t20(
    -> id int,
    -> firstname varchar(15),
    -> lastname varchar(15),
    -> unique key(id)
    -> );
Query OK, 0 rows affected (0.09 sec)

-- Syntax 2

mysql> create table t20(
    -> id int,
    -> firstname varchar(15),
    -> lastname varchar(15),
    -> unique(id)
    -> );
Query OK, 0 rows affected (0.11 sec)

-- Syntax 3

mysql> create table t20(
    -> id int unique,
    -> firstname varchar(15),
    -> lastname varchar(15)
    -> );
Query OK, 0 rows affected (0.11 sec)

Hər 3 syntax dəstəklənir.
Oracle-da constraint metadatanı oxumağı göstərdik indi də MySQL üçün göstərək.

-- MySQL

-- 1ci usul 

mysql> show create table t20;
>>>
CREATE TABLE `t20` (
  `id` int(11) DEFAULT NULL,
  `firstname` varchar(15) DEFAULT NULL,
  `lastname` varchar(15) DEFAULT NULL,
  UNIQUE KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1

-- 2ci usul

mysql> select constraint_name, constraint_type from information_schema.table_constraints where table_schema='join_test' and table_name='t20';
+-----------------+-----------------+
| constraint_name | constraint_type |
+-----------------+-----------------+
| id              | UNIQUE          |
+-----------------+-----------------+
1 row in set (0.00 sec)

Və təbii ki yenə Oracle-da olduğu kimi özümüz constraint name verə bilərik.

-- MySQL

 
create table t20(
id int,
firstname varchar(15),
lastname varchar(15),
constraint id_unikal unique key(id)
);


-- metadata

mysql> select constraint_name, constraint_type from information_schema.table_constraints where table_schema='join_test' and table_name='t20';
+-----------------+-----------------+
| constraint_name | constraint_type |
+-----------------+-----------------+
| id_unikal       | UNIQUE          |
+-----------------+-----------------+
1 row in set (0.00 sec)

Düşünürəm ki, UNİQUE constraint haqqında bu qədər kifayətdir davam edirik.

CHECK

-- Oracle

-- Syntax 1

create table t20(
id number,
firstname varchar2(15),
lastname varchar2(15),
check (id in(1,2,3,4))
);

>>>
table T20 created.

-- insert edek

insert into t20(id,firstname,lastname) values(5,'shahriyar','rzayev');

>>>
insert into t20(id,firstname,lastname) values(5,'shahriyar','rzayev')
Error report -
SQL Error: ORA-02290: check constraint (HR.SYS_C0011140) violated
02290. 00000 -  "check constraint (%s.%s) violated"
*Cause:    The values being inserted do not satisfy the named check
           
*Action:   do not insert values that violate the constraint.

-- Syntax 2

create table t20(
id number,
firstname varchar2(15),
lastname varchar2(15),
constraint id_check check (id in(1,2,3,4))
);
>>>
table T20 created.

2 Syntax dəstəklənir. Bundan əlavə gördüyümüz kimi, id CHECK constraint-ə uyğun olaraq yalnız 1, 2, 3, 4 daxil etməyə icazə verir biz 5 insert etməyə çalışdığımız üçün error çıxır. Çox gözəl.

Constraint siyahısına baxaq:

-- Oracle

select 
constraint_name,
constraint_type
from USER_CONSTRAINTS where table_name='T20';

>>>
ID_CHECK	C

CHECK-dan danışdığımız üçün NOT NULL-U qeyd etməliyik. Faktiki olaraq Oracle-da NOT NULL elə CHECK constraintdir.

-- Oracle

-- firstname-e not null verek

create table t20(
id number,
firstname varchar2(15) not null,
lastname varchar2(15),
constraint id_check check (id in(1,2,3,4))
);

-- constraint siyahısına baxaq

select 
constraint_name,
constraint_type
from USER_CONSTRAINTS where table_name='T20';

>>>
SYS_C0011142	C
ID_CHECK	C

Bizim nümunədə SYS_C0011142 = NOT NULL-un necə deyərlər adıdır və Diqqət yetirsək görərik ki,
her iki constraint-in type-ı C-dir yəni CHECK.
Çox kədərli hal kimi onu qeyd etməliyik ki, MySQL-də CHECK constraint dəstəklənmir dolayısı ilə nəzərə alsaq ki, NOT NULL = CHECK o zaman burdan belə bir nəticə çıxartmaq olar ki, NOT NULL MySQL-də ayrıca constraint kimi götürülmür gəlin test edək.

-- MySQL

create table t20(
id int,
firstname varchar(15) not null,
lastname varchar(15),
constraint id_check check (id in(1,2,3,4))
);

Cədvəl definition-nunda not null və check olmağına baxmayaraq MySQL üçün bunlar constraint hesab olunmur.
Datadictionary-dən constraint list-ə baxmaq istədikdə də bunun şahidi oluruq.

mysql> select constraint_name, constraint_type from information_schema.table_constraints where table_schema='join_test' and table_name='t20';
Empty set (0.00 sec)

Dokumentasiyada da bu açıq şəkildə qeyd olunub:

The CHECK clause is parsed but ignored by all storage engines.

Çox təəssüf.

PRİMARY KEY:

-- Oracle

-- Syntax 1

create table t20(
id number,
firstname varchar2(15),
lastname varchar2(15),
primary key(id)
);

select 
constraint_name,
constraint_type
from USER_CONSTRAINTS where table_name='T20';

>>>
SYS_C0011147	P


-- Syntax 2

create table t20(
id number,
firstname varchar2(15),
lastname varchar2(15),
constraint pk_id primary key(id)
);

select 
constraint_name,
constraint_type
from USER_CONSTRAINTS where table_name='T20';

>>>
PK_ID	P

Ümumi olaraq Burdan aşağıdakı nəticə çıxır:
Oracle-da PK yaradarkən ayrıca olaraq NOT NULL qeyd etməyə ehtiyac yoxdur.
Suggested by Adigozalov Qurban:
From Oracle DOC:
A primary key constraint combines a NOT NULL constraint and a unique constraint in a single declaration. That is, it prohibits multiple rows from having the same value in the same column or combination of columns and prohibits values from being null.

Həmçinin yuxarıdakı nümunədə də göstərildiyi kimi, PK-ya name verə bilirik.
indi isə eyni testləri MySQL-də edək:

-- MySQL

-- Syntax 1

create table t20(
id int,
firstname varchar(15) not null,
lastname varchar(15),
primary key(id)
);

-- Metadata

mysql> select constraint_name, constraint_type from information_schema.table_constraints where table_schema='join_test' and table_name='t20';
+-----------------+-----------------+
| constraint_name | constraint_type |
+-----------------+-----------------+
| PRIMARY         | PRIMARY KEY     |
+-----------------+-----

-- Syntax 2

create table t20(
id int,
firstname varchar(15) not null,
lastname varchar(15),
constraint pk_id primary key(id)
);

-- Metadata

mysql> select constraint_name, constraint_type from information_schema.table_constraints where table_schema='join_test' and table_name='t20';
+-----------------+-----------------+
| constraint_name | constraint_type |
+-----------------+-----------------+
| PRIMARY         | PRIMARY KEY     |
+-----------------+-----------------+
1 row in set (0.00 sec)

Yuxarıdan belə nəticə çıxarırıq ki, MySQL-də Primay Key constraint-in adını dəyişmək olmur.

From Documentation:
The name of a PRIMARY KEY is always PRIMARY, which thus cannot be used as the name for any other kind of index.

Foreign Key-lə bağlı əlavə yazı olacaq.

Təşəkkürlər😉

  1. Hələlik heç bir şərh yoxdur
  1. No trackbacks yet.

Bir cavab yazın

Sistemə daxil olmaq üçün məlumatlarınızı daxil edin və ya ikonlardan birinə tıklayın:

WordPress.com Loqosu

WordPress.com hesabınızdan istifadə edərək şərh edirsinz. Çıxış / Dəyişdir )

Twitter rəsmi

Twitter hesabınızdan istifadə edərək şərh edirsinz. Çıxış / Dəyişdir )

Facebook fotosu

Facebook hesabınızdan istifadə edərək şərh edirsinz. Çıxış / Dəyişdir )

Google+ foto

Google+ hesabınızdan istifadə edərək şərh edirsinz. Çıxış / Dəyişdir )

%s qoşulma

%d bloqqer bunu bəyənir: