Birinci hissə
Biz sadə birja emulyatorumuzu yaratmağa davam edirik. Biz nə edəcəyik:
- Verilənlər bazasının təşkili diaqramını yaradaq.
- Nə, necə və harada saxlandığını təsvir edəcəyik.
- Verilənlərin bir-biri ilə necə əlaqəli olduğunu öyrənək.
- SQL dilinin CREATE TABLE , Data Definition Language ( DDL ) SQL cədvəlinin yaradılması əmrinin nümunəsindən istifadə edərək SQL-in əsaslarını öyrənməyə başlayaq .
- Java proqramını yazmağa davam edək. Biz JDBC və üç səviyyəli arxitekturadan istifadə edərək, verilənlər bazamızı proqramlı şəkildə yaratmaq üçün java.sql baxımından DBMS-nin əsas funksiyalarını həyata keçiririk.
Bu iki hissə daha həcmli oldu, çünki SQL-in əsasları və DBMS-nin təşkili ilə içəridən tanış olmalıyıq və Java ilə analogiyalar çəkməliyik. Sizi kod siyahıları ilə bezdirməmək üçün sonunda proqramla müvafiq commit github repozitoriyasına keçidlər var.
DBMS dizaynı
Tətbiq təsviri
Məlumatların saxlanmasının təşkilinin proqramlaşdırmanın ayrılmaz hissəsi olduğunu artıq eşitmisiniz. Nəzərinizə çatdırım ki, tətbiqimizin məqsədi ən sadə mübadilə emulyasiyasıdır:
- Verilmiş qaydalara uyğun olaraq ticarət günü ərzində dəyəri dəyişə bilən səhmlər var;
- ilkin kapitalı olan treyderlər var;
- treyderlər alqoritmlərinə uyğun olaraq səhmləri alıb sata bilərlər.
Mübadilə
gənələrdə işləyir - müəyyən edilmiş müddətlərdə (bizim vəziyyətimizdə - 1 dəqiqə). Gənə zamanı səhm qiyməti dəyişə bilər və sonra treyder səhmləri ala və ya sata bilər.
Mübadilə emulyasiya məlumat strukturu
Fərdi mübadilə qurumlarını modellər adlandıraq. Yuvarlaqlaşdırma səhvlərinin qarşısını almaq üçün bir sinif vasitəsilə maliyyə məbləğləri ilə işləyəcəyik
BigDecimal
(ətraflı məlumatı məqalənin sonundakı linkdə tapa bilərsiniz). Hər bir modelin strukturunu daha ətraflı təsvir edək:
Təqdimat:
Atribut |
Növ |
Təsvir |
name |
Srting |
ad |
changeProbability |
int |
Hər bir işarədə faiz kimi nisbət dəyişməsi ehtimalı |
startPrice |
BigDecimal |
İlkin xərc |
delta |
int |
Cari dəyərin dəyişə biləcəyi faizlə maksimum məbləğ |
Səhm qiyməti:
Atribut |
Növ |
Təsvir |
operDate |
LocalDateTime |
Məzənnəni təyin etmək üçün vaxt (işarə). |
share |
Promosyon |
Tanıtım üçün keçid |
rate |
BigDecimal |
Səhm qiyməti |
Treyder:
Atribut |
Növ |
Təsvir |
name |
Simli |
Məzənnəni təyin etmək üçün vaxt (işarə). |
sfreqTick |
int |
Əməliyyatların tezliyi. Treyder əməliyyatları həyata keçirdikdən sonra gənə ilə dövr ilə müəyyən edilir |
cash |
BigDecimal |
Səhmlərdən başqa pul məbləği |
traidingMethod |
int |
Treyder tərəfindən istifadə edilən alqoritm. Onu sabit ədəd kimi təyin edək, alqoritmin icrası (aşağıdakı hissələrdə) Java kodunda olacaq. |
changeProbability |
int |
Əməliyyatın tamamlanma ehtimalı, faiz |
about |
Simli |
Hər bir işarədə faiz dərəcəsinin dəyişmə ehtimalı |
Treyder hərəkətləri:
Atribut |
Növ |
Təsvir |
operation |
int |
Əməliyyat növü (almaq və ya satmaq) |
traider |
Treyder |
Treyder bağlantısı |
shareRate |
Səhm qiyməti |
Səhm qiyməti ilə əlaqə (müvafiq olaraq, səhmin özü, dərəcəsi və buraxıldığı vaxt) |
amount |
Uzun |
Əməliyyatda iştirak edən səhmlərin sayı |
Hər bir modelin unikallığını təmin etmək üçün longid
tipli bir atribut əlavə edəcəyik .
Bu atribut model nümunələri daxilində unikal olacaq və onu unikal şəkildə müəyyən edəcək. Digər modellərə istinad edən atributlar (treyder, səhm, səhm qiyməti) müvafiq modeli unikal şəkildə müəyyən etmək üçün bundan istifadə edə bilər . Dərhal ağlımıza gəlir ki, bu cür məlumatları saxlamaq üçün istifadə edə bilərik, uyğun model haradadır. Bununla belə, aşağıdakı şərtlər altında bunu kodda həyata keçirməyə çalışın:
id
Map<Long, Object>
Object
- məlumat ölçüsü mövcud RAM miqdarını əhəmiyyətli dərəcədə üstələyir;
- məlumatlara giriş onlarla müxtəlif yerlərdən gözlənilir;
- məlumatları eyni vaxtda dəyişdirmək və oxumaq imkanı tələb olunur;
- məlumatların formalaşması və bütövlüyü qaydalarını təmin etmək lazımdır;
...və siz müvafiq ixtisas və həyata keçirmək üçün vaxt tələb edən vəzifələrlə qarşılaşacaqsınız. “Çəkəri yenidən kəşf etməyə” ehtiyac yoxdur. Artıq bizim üçün çox şey düşünülmüş və yazılmışdır. Beləliklə, biz illər ərzində artıq sınaqdan keçirilmiş şeylərdən istifadə edəcəyik.
Java-da verilənlərin saxlanması
Fəaliyyəti nəzərdən keçirək. Java-da biz bu model üçün , , , sahələri
Share
ilə xüsusi bir sinif yaratdıq . Və bir çox paylaşımlar kimi saxlanılırdı , burada açar hər bir paylaşım üçün unikal identifikatordur.
name
changeProbability
startPrice
delta
Map<Long, Share>
public class Share {
private String name;
private BigDecimal startPrice;
private int changeProbability;
private int delta;
}
Map<Long, Share> shares = new HashMap<>();
shares.put(1L, new Share("ibm", BigDecimal.valueOf(20.0), 15, 10));
shares.put(2L, new Share("apple", BigDecimal.valueOf(14.0), 25, 15));
shares.put(3L, new Share("google", BigDecimal.valueOf(12.0), 20, 8));
...
shares.put(50L, new Share("microsoft", BigDecimal.valueOf(17.5), 10,4 ));
ID ilə istədiyiniz təşviqata daxil olmaq üçün metoddan istifadə edin
shares.get(id)
. Adına və ya qiymətinə görə səhm tapmaq tapşırığı üçün biz lazım olanı axtarırıq və s. Ancaq biz başqa yolla gedəcəyik və dəyərləri DBMS-də saxlayacağıq.
DBMS-də məlumatların saxlanması
DBMS üçün məlumatların saxlanması qaydalarının ilkin dəstini formalaşdıraq:
- DBMS-dəki məlumatlar qeydlər dəsti olan cədvəllərdə ( TABLE ) təşkil edilir.
- Bütün qeydlər eyni sahələr dəstinə malikdir. Cədvəl yaratarkən təyin olunurlar.
- Sahə standart dəyərə təyin edilə bilər ( DEFAULT ).
- Cədvəl üçün, onların bütövlüyünü təmin etmək üçün onun məlumatlarına olan tələbləri təsvir edən məhdudiyyətlər ( CONSTRAINT ) təyin edə bilərsiniz. Bu, cədvəlin yaradılması mərhələsində edilə bilər ( CREATE TABLE ) və ya daha sonra əlavə edilə bilər ( ALTER TABLE ... ADD COSTRAINT ).
- Ən çox görülən MƏHDUD :
- Əsas açar PRIMARY-dir (bizim vəziyyətimizdə Id).
- Unikal dəyər sahəsi UNİKAL (avtomobil cədvəli üçün VIN).
- CHECK sahəsi yoxlanılır (faiz dəyəri 100-dən çox ola bilməz). Sahədə özəl məhdudiyyətlərdən biri NULL və ya NULL deyil , cədvəl sahəsində NULL-un saxlanmasını qadağan edir/icazə verir.
- Üçüncü tərəf cədvəlinə keçid XARİCİ KEY (səhm qiymət cədvəlindəki səhmə keçid).
- İndeks INDEX (ondakı dəyərlərin axtarışını sürətləndirmək üçün bir sahənin indeksləşdirilməsi).
- Sahələrinin dəyərləri məhdudiyyətlərlə (CONSTRAINT) ziddiyyət təşkil edərsə, qeydin dəyişdirilməsi ( INSERT , UPDATE ) baş verməyəcək.
- Hər bir cədvəldə qeydi unikal şəkildə müəyyən etmək üçün istifadə edilə bilən əsas sahə (və ya bir neçə) ola bilər. Belə bir sahə (və ya sahələr, əgər kompozit açar meydana gətirirlərsə) cədvəlin əsas açarını təşkil edir - PRIMARY KEY .
- İlkin açar cədvəldəki qeydin unikallığını təmin edir, onun üzərində indeks yaradılır ki, bu da açar dəyərinə əsaslanaraq bütün qeydə sürətli çıxış imkanı verir.
- Əsas açarın olması cədvəllər arasında əlaqə yaratmağı xeyli asanlaşdırır. Sonra, biz süni əsas açardan istifadə edəcəyik: ilk qeyd üçün
id = 1
hər bir sonrakı qeyd id dəyəri bir artaraq cədvələ daxil ediləcək. Bu açar tez-tez AutoIncrement və ya AutoIdentity adlanır .
Əslində səhmlər cədvəli:
Bu halda fond adını açar kimi istifadə etmək mümkündürmü? Ümumiyyətlə - bəli, lakin bəzi şirkətlərin müxtəlif səhmlər buraxması və onları yalnız öz adı ilə çağırması ehtimalı var. Bu halda, artıq unikallıq olmayacaq. Təcrübədə süni əsas açar olduqca tez-tez istifadə olunur. Razılaşın, insanların qeydlərini ehtiva edən cədvəldə tam adın unikal açar kimi istifadə edilməsi unikallığı təmin etməyəcək. Tam adın və doğum tarixinin birləşməsindən istifadə etməklə yanaşı.
DBMS-də məlumat növləri
Hər hansı digər proqramlaşdırma dilləri kimi, SQL-də də məlumatların yazılması var. Ən çox yayılmış SQL məlumat növləri bunlardır:
Tam ədəd növləri
SQL növü |
SQL sinonimləri |
Java-da uyğunluq |
Təsvir |
INT |
INT4, BÜTÜN |
java.lang.Integer |
4 bayt tam, -2147483648 … 2147483647 |
BULEAN |
BOOL, BIT |
java.lang.Boolean |
Doğru yalan |
TINYINT |
|
java.lang.Byte |
1 bayt tam, -128 … 127 |
KIÇIQ |
INT2 |
java.lang.Qısa |
2 bayt tam, -32768 … 32767 |
BÖYÜK |
INT8 |
java.lang.Long |
8 baytlıq tam ədəd, -9223372036854775808 … 9223372036854775807 |
AUTO_INCREMENT |
ARTIM |
java.lang.Long |
Cədvəl üçün unikal artan sayğac. Əgər ona yeni dəyər daxil edilərsə, o, bir artırılır.Yaradılan dəyərlər heç vaxt təkrarlanmır. |
Real
SQL növü |
SQL sinonimləri |
Java-da uyğunluq |
Təsvir |
DECIMAL(N,M) |
DEKA, NUMBER |
java.riyaziyyat.BigDecimal |
Sabit dəqiqlikli onluq (N tam rəqəm və M fraksiya rəqəmi). Əsasən maliyyə məlumatları ilə işləmək üçün nəzərdə tutulmuşdur. |
İKİLİ |
FLOAT8 |
java.lang.Double |
İkiqat dəqiqlikli real ədəd (8 bayt). |
REAL |
FLOAT4 |
java.lang.Real |
Tək dəqiqlikli real ədəd (4 bayt). |
Simli
SQL növü |
SQL sinonimləri |
Java-da uyğunluq |
Təsvir |
VARÇAR(N) |
NVARCHAR |
java.lang.String |
N uzunluqlu UNICODE sətri. Uzunluq 2147483647 ilə məhdudlaşır. Sətin bütün məzmununu yaddaşa yükləyir. |
Tarix və saat
SQL növü |
SQL sinonimləri |
Java-da uyğunluq |
Təsvir |
TIME |
|
java.time.LocalTime, java.sql.Time |
Saxlama vaxtı (nanosaniyələrə qədər), DATETIME-a çevrildikdə, tarix 1970-ci il yanvarın 1-nə təyin edilir. |
TARİX |
|
java.time.LocalDate, java.sql.Timestamp |
Tarixlər yyyy-aa-gg formatında saxlanılır, vaxt 00:00 olaraq təyin olunur |
TARİX VAXT |
ZAMAN ŞÜRTASI |
java.time.LocalDateTime, java.sql.Timestamp |
Saxlama tarixi + vaxt (vaxt zonalarını nəzərə almadan). |
Böyük həcmli məlumatların saxlanması
SQL növü |
Java-da uyğunluq |
Təsvir |
BLOB |
java.io.InputStream, java.sql.Blob |
İkili məlumatların saxlanması (şəkillər, fayllar...). |
CLOB |
java.io.Reader, java.sql.Clob |
Böyük mətn məlumatlarının (kitablar, məqalələr...) saxlanması VARCHAR-dan fərqli olaraq, məlumatları hissə-hissə yaddaşa yükləyir. |
SQL yazı üslubu
Bir çox dillər üçün kod formatlaşdırma qaydaları mövcuddur. Tipik olaraq, belə sənədlərdə dəyişənlərin, sabitlərin, metodların və digər dil strukturlarının adlandırılması qaydaları var.
Beləliklə, Python üçün PEP8, Java üçün - Java üçün Oracle Kod Konvensiyaları var . SQL üçün bir-birindən bir qədər fərqli olan bir neçə müxtəlif dəstlər yaradılmışdır. Nə olursa olsun, kodunuzu formatlayarkən qaydalara riayət etmək vərdişini inkişaf etdirməlisiniz, xüsusən də komandada işləyirsinizsə. Qaydalar, məsələn, aşağıdakılar ola bilər (əlbəttə ki, özünüz üçün fərqli qaydalar dəsti hazırlaya bilərsiniz, əsas odur ki, gələcəkdə onlara əməl edin):
- Açar sözlər və qorunan sözlər, o cümlədən əmrlər və operatorlar böyük hərflərlə yazılmalıdır: CREATE TABLE, COSTRAINT...
- Cədvəllərin, sahələrin və digər obyektlərin adları SQL dilinin açar sözləri ilə üst-üstə düşməməlidir (məqalənin sonundakı linkə baxın), lakin onları ehtiva edə bilər.
- Cədvəl adları onların məqsədini əks etdirməlidir. Onlar kiçik hərflərlə yazılır. Addakı sözlər bir-birindən alt xətt ilə ayrılır. Sonda olan söz cəm şəklində olmalıdır : treyderlər (treyderlər), pay_stavkaları (pay dərəcəsi).
- Cədvəl sahələrinin adları onların məqsədini əks etdirməlidir. Onlar kiçik hərflərlə yazılmalı, addakı sözlər Camel Case üslubunda formatlaşdırılmalı və sonundakı söz tək hərfdə istifadə edilməlidir : ad (ad), pay_stavkaları (pay dərəcəsi).
- Süni açar sahələrində id sözü olmalıdır.
- CONSTRAINT adları cədvəl adlandırma konvensiyalarına uyğun olmalıdır. Onlar həmçinin onlara daxil olan sahələri və cədvəlləri daxil etməli, semantik prefikslə başlamalıdırlar: check_ (sahə dəyərinin yoxlanılması), pk_ (əsas açar), fk_ (xarici açar), uniq_ (sahənin unikallığı), idx_ (indeks). Nümunə: pk_traider_share_actions_id (trader_share_actions cədvəli üçün id sahəsində əsas açar).
- Və s., SQL-i öyrəndikcə, qaydaların siyahısı doldurulacaq/dəyişdiriləcək.
DBMS dizaynı
DBMS yaratmazdan dərhal əvvəl onu tərtib etmək lazımdır. Yekun sxem cədvəllər, sahələr dəsti, MƏHDUD, açarlar, sahələr üçün standart şərtlər, cədvəllər və digər verilənlər bazası obyektləri arasında əlaqələri ehtiva edir. İnternetdə kiçik DBMS-lərin dizaynı üçün çoxlu pulsuz onlayn/oflayn dizaynerlər tapa bilərsiniz. Axtarış motoruna “Verilənlər bazası dizayneri pulsuz” kimi bir şey yazmağa çalışın. Bu cür tətbiqlər faydalı əlavə xüsusiyyətlərə malikdir:
- DBMS yaratmaq üçün SQL əmrləri yarada bilər.
- Parametrləri diaqramda vizual olaraq göstərin.
- Daha yaxşı vizuallaşdırma üçün cədvəlləri köçürməyə imkan verir.
- Diaqramda açarları, indeksləri, əlaqələri, standart dəyərləri və s. göstərin.
- Onlar DBMS sxemini uzaqdan saxlaya bilərlər.
Məsələn,
dbdiffo.com açarları vurğulayır, boş olmayan sahələri və NN etiketi ilə AI (AutoIncrement) sayğaclarını göstərir:
DBMS-də cədvəllərin yaradılması
Beləliklə, bir diaqramımız var. İndi cədvəllərin yaradılmasına keçək (CREATE TABLE). Bunun üçün ilkin məlumatlara sahib olmağımız məsləhətdir:
- masa adı
- sahə adları və növü
- sahələr üzrə məhdudiyyətlər (MƏHDUDLƏR).
- sahələr üçün standart dəyərlər (əgər varsa)
- varsa, əsas açar (PRIMARY KEY).
- cədvəllər arasında əlaqə (XARİCİ KEY)
CREATE TABLE əmrinin bütün variantlarını ətraflı öyrənməyəcəyik, treyderlər üçün cədvəl yaratmaq nümunəsindən istifadə edərək SQL-in əsaslarına baxacağıq:
CREATE TABLE traiders(
id BIGINT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
freqTiсk INTEGER NOT NULL,
cash DECIMAL(15,2) NOT NULL DEFAULT 1000,
tradingMethod INTEGER NOT NULL,
changeProbability INTEGER NOT NULL DEFAULT 50,
about VARCHAR(255) NULL
);
ALTER TABLE traiders ADD CONSTRAINT check_traiders_tradingMethod
CHECK(tradingMethod IN (1,2,3));
ALTER TABLE traiders ADD CONSTRAINT check_traiders_changeProbability
CHECK(changeProbability <= 100 AND changeProbability > 0)
Gəlin daha yaxından nəzər salaq:
CREATE TABLE traiders
(sahənin təsviri) - göstərilən adla cədvəl yaradır, təsvirdə sahələr vergüllə ayrılır. İstənilən əmr nöqtəli vergüllə bitir.
- Sahənin təsviri onun adı ilə başlayır, ardınca onun növü, CONSTRAINT və default dəyəri gəlir.
id BIGINT AUTO_INCREMENT PRIMARY KEY
– tam ədəd tipli id sahəsi əsas açar və artımlı sayğacdır (id sahəsi üçün hər yeni qeyd üçün bu cədvəl üçün əvvəllər yaradılmışdan bir böyük dəyər yaradılacaq).
cash DECIMAL(15,2) NOT NULL DEFAULT 1000
– kassa sahəsi, onluq, onluqdan əvvəl 15 rəqəm və sonra iki rəqəm (maliyyə məlumatları, məsələn, dollar və sent). NULL dəyərləri qəbul etmək mümkün deyil. Heç bir dəyər verilməsə, 1000 dəyərini alacaq.
about VARCHAR(255) NULL
– haqqında sahəsi, uzunluğu 255 simvola qədər olan sətir boş dəyərləri qəbul edə bilər.
Qeyd edək ki, Cədvəl yaratdıqdan sonra
COSTRAINT şərtlərinin bir hissəsini təyin edə bilərik . Cədvəl strukturunun və onun sahələrinin dəyişdirilməsi üçün konstruksiyaya nəzər salaq:
ALTER TABLE table_name ADD COSTRAINT constraint_name CHECK (şərt) nümunələrdən istifadə edərək:
CHECK(tradingMethod IN (1,2,3))
– tradingMethod sahəsi yalnız 1,2,3 dəyərləri qəbul edə bilər
CHECK(changeProbability <= 100 AND changeProbability > 0)
– dəyişiklikEhtimal sahəsi 1-dən 100-ə qədər aralıqda tam dəyərlər qəbul edə bilər
Cədvəllər arasındakı əlaqə
Cədvəllər arasında əlaqələrin təsvirini təhlil etmək üçün pay_stavkalarının yaradılmasına baxaq:
CREATE TABLE share_rates(
id BIGINT AUTO_INCREMENT PRIMARY KEY,
operDate datetime NOT NULL,
share BIGINT NOT NULL,
rate DECIMAL(15,2) NOT NULL
);
ALTER TABLE share_rates ADD FOREIGN KEY (share) REFERENCES shares(id)
Başqa bir cədvəlin dəyərlərinə istinad aşağıdakı kimi təyin edilə bilər:
ALTER TABLE
cədvəl_hansı_istinad edilən
ADD FOREIGN KEY
(istənilən_sahə)
REFERENCES
cədvəl_hansı_istinad edilən (sahə_istənilən_sahə) Səhmlərdə
səhmlər haqqında qeydlərimiz olsun, məsələn, id=50 üçün Microsoft səhmlərini ilkin qiyməti ilə saxlayırıq. 17.5, delta 20 və dəyişmə şansı 4%.
Share_rates cədvəli üçün üç əsas xüsusiyyət əldə edirik:
- Paylaşımlar cədvəlindən qalan məlumatları (ad və s.) əldə etmək üçün istifadə etmək üçün yalnız səhmlər cədvəlindəki id açarının dəyərini paylaşma sahəsində saxlamalıyıq.
- Mövcud olmayan tanıtım üçün tarif yarada bilmərik. Siz paylaşma sahəsinə mövcud olmayan dəyər daxil edə bilməzsiniz (bunun üçün bu id ilə səhmlər cədvəlində heç bir qeyd yoxdur), çünki cədvəllər arasında heç bir yazışma olmayacaqdır.
- Biz tarifləri share_rates bölməsində müəyyən edilmiş paylaşımlardakı paylaşım qeydini silə bilmərik.
Son iki nöqtə saxlanılan məlumatların bütövlüyünü təmin etməyə xidmət edir. Məqalənin sonundakı github repozitoriyasına keçiddən istifadə edərək, müvafiq siniflərin metodlarının Java tətbiqində emulyasiyamızın SQL cədvəllərinin yaradılmasını və SQL sorğularının nümunələrini görə bilərsiniz.
Üçüncü hissə
GO TO FULL VERSION