SQL, nima oddiyroq bo'lishi mumkin? Har birimiz oddiy so'rov yozishimiz mumkin - biz yozamiz tanlash, kerakli ustunlarni ro'yxatlang, keyin dan, jadval nomi, ba'zi shartlar qayerda va bu hammasi - foydali ma'lumotlar bizning cho'ntagimizda va (deyarli) o'sha paytda qaysi DBMS kaput ostida bo'lishidan qat'i nazar (yoki ehtimol
Va to'g'ridan-to'g'ri boshlaylik
Ob'ektga aloqador xaritalash
ORM tarafdorlari an'anaviy ravishda tezlik va rivojlanish qulayligini, DBMSdan mustaqillikni va toza kodni qadrlashadi. Ko'pchiligimiz uchun ma'lumotlar bazasi bilan ishlash uchun kod (va ko'pincha ma'lumotlar bazasining o'zi)
odatda shunday ko'rinadi ...
@Entity
@Table(name = "stock", catalog = "maindb", uniqueConstraints = {
@UniqueConstraint(columnNames = "STOCK_NAME"),
@UniqueConstraint(columnNames = "STOCK_CODE") })
public class Stock implements java.io.Serializable {
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "STOCK_ID", unique = true, nullable = false)
public Integer getStockId() {
return this.stockId;
}
...
Model aqlli izohlar bilan osilgan va sahna ortida bir joyda jasur ORM tonnalab SQL kodlarini ishlab chiqaradi va bajaradi. Aytgancha, ishlab chiquvchilar o'zlarining ma'lumotlar bazasidan kilometrlarcha abstraktsiyalar bilan ajralib turishga harakat qilmoqdalar, bu ba'zi narsalarni ko'rsatadi.
Barrikadalarning boshqa tomonida sof "qo'lda ishlangan" SQL tarafdorlari qo'shimcha qatlamlar va abstraktsiyalarsiz o'zlarining DBMSlaridan barcha sharbatni siqib chiqarish qobiliyatini ta'kidlashadi. Natijada "ma'lumotlarga asoslangan" loyihalar paydo bo'ladi, bu erda ma'lumotlar bazasiga maxsus o'qitilgan odamlar jalb qilinadi (ular ham "bazachilar", ular ham "bazachilar", ular ham "basdenatorlar" va boshqalar) va ishlab chiquvchilar. Tafsilotlarga kirmasdan, faqat tayyor ko'rinishlarni va saqlangan protseduralarni "tortib olish" kerak.
Agar biz ikkala dunyoning eng yaxshisiga ega bo'lsak-chi? Bu hayotni tasdiqlovchi ism bilan ajoyib vositada qanday amalga oshiriladi
Clojure - bu DSL yaratish uchun ajoyib til, lekin SQLning o'zi ajoyib DSL va bizga boshqa til kerak emas. S-ifodalari ajoyib, lekin ular bu erda yangi hech narsa qo'shmaydi. Natijada, biz qavslar uchun qavslarni olamiz. Rozi emasmisiz? Keyin ma'lumotlar bazasi ustidan abstraksiya oqishi va siz funktsiya bilan kurashishni boshlagan paytni kuting (raw-sql)
Xo'sh, nima qilishim kerak? Keling, SQLni oddiy SQL sifatida qoldiraylik - har bir so'rov uchun bitta fayl:
-- name: users-by-country
select *
from users
where country_code = :country_code
... va keyin ushbu faylni oddiy Clojure funktsiyasiga aylantirib o'qing:
(defqueries "some/where/users_by_country.sql"
{:connection db-spec})
;;; A function with the name `users-by-country` has been created.
;;; Let's use it:
(users-by-country {:country_code "GB"})
;=> ({:name "Kris" :country_code "GB" ...} ...)
"SQL o'z-o'zidan, Clojure o'z-o'zidan" tamoyiliga rioya qilib, siz quyidagilarni olasiz:
- Sintaktik kutilmagan hodisalar yo'q. Sizning ma'lumotlar bazasi (boshqalar kabi) SQL standartiga 100% mos kelmaydi - lekin bu Yesql uchun muhim emas. SQL ekvivalenti sintaksisi bilan funksiyalarni qidirishga hech qachon vaqt sarflamaysiz. Siz hech qachon funktsiyaga qaytishingiz shart emas (raw-sql "ba'zi('funky'::SYNTAX)")).
- Eng yaxshi muharrirni qo'llab-quvvatlash. Muharriringiz allaqachon mukammal SQL yordamiga ega. SQLni SQL sifatida saqlash orqali siz undan oddiygina foydalanishingiz mumkin.
- Jamoa muvofiqligi. Sizning DBA'laringiz Clojure loyihangizda foydalanadigan SQL-ni o'qishi va yozishi mumkin.
- Ishlashni oson sozlash. Muammoli so'rov uchun reja tuzish kerakmi? So'rovingiz oddiy SQL bo'lsa, bu muammo emas.
- So'rovlarni qayta ishlatish. Xuddi shu SQL fayllarini boshqa loyihalarga sudrab olib tashlang, chunki bu oddiy eski SQL - shunchaki baham ko'ring.
Menimcha, g'oya juda zo'r va ayni paytda juda oddiy, buning natijasida loyiha ko'pchilikni qo'lga kiritdi
IDE va ββDB menejerlari
Keling, oddiy kundalik vazifadan boshlaylik. Ko'pincha ma'lumotlar bazasida ba'zi ob'ektlarni qidirishga to'g'ri keladi, masalan, sxemada jadvalni topib, uning tuzilishini o'rganishimiz kerak (qanday ustunlar, kalitlar, indekslar, cheklovlar va boshqalar ishlatiladi). Va har qanday grafik IDE yoki kichik DB-menejerdan, birinchi navbatda, biz aynan shu qobiliyatlarni kutamiz. Bu tez bo'lishi va kerakli ma'lumotlarga ega oyna paydo bo'lguncha (ayniqsa masofaviy ma'lumotlar bazasiga sekin ulanishda) yarim soat kutishingizga to'g'ri kelmasligi va shu bilan birga olingan ma'lumotlar yangi va dolzarb bo'lishi uchun, va keshlanmagan keraksiz narsalar. Bundan tashqari, ma'lumotlar bazasi qanchalik murakkab va katta bo'lsa va ularning soni qanchalik ko'p bo'lsa, buni qilish shunchalik qiyin bo'ladi.
Lekin odatda men sichqonchani tashlab, shunchaki kod yozaman. Aytaylik, siz "HR" sxemasida qaysi jadvallar (va qaysi xususiyatlar bilan) mavjudligini aniqlashingiz kerak. Ko'pgina DBMSlarda kerakli natijaga information_schema dan ushbu oddiy so'rov yordamida erishish mumkin:
select table_name
, ...
from information_schema.tables
where schema = 'HR'
Ma'lumotlar bazasidan ma'lumotlar bazasiga, bunday ma'lumot jadvallarining mazmuni har bir ma'lumotlar bazasining imkoniyatlariga qarab farqlanadi. Va, masalan, MySQL uchun, xuddi shu ma'lumotnomadan ushbu DBMSga xos jadval parametrlarini olishingiz mumkin:
select table_name
, storage_engine -- ΠΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌΡΠΉ "Π΄Π²ΠΈΠΆΠΎΠΊ" ("MyISAM", "InnoDB" etc)
, row_format -- Π€ΠΎΡΠΌΠ°Ρ ΡΡΡΠΎΠΊΠΈ ("Fixed", "Dynamic" etc)
, ...
from information_schema.tables
where schema = 'HR'
Oracle information_schema-ni bilmaydi, lekin unda bor
select table_name
, pct_free -- ΠΠΈΠ½ΠΈΠΌΡΠΌ ΡΠ²ΠΎΠ±ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΌΠ΅ΡΡΠ° Π² Π±Π»ΠΎΠΊΠ΅ Π΄Π°Π½Π½ΡΡ
(%)
, pct_used -- ΠΠΈΠ½ΠΈΠΌΡΠΌ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌΠΎΠ³ΠΎ ΠΌΠ΅ΡΡΠ° Π² Π±Π»ΠΎΠΊΠ΅ Π΄Π°Π½Π½ΡΡ
(%)
, last_analyzed -- ΠΠ°ΡΠ° ΠΏΠΎΡΠ»Π΅Π΄Π½Π΅Π³ΠΎ ΡΠ±ΠΎΡΠ° ΡΡΠ°ΡΠΈΡΡΠΈΠΊΠΈ
, ...
from all_tables
where owner = 'HR'
ClickHouse ham bundan mustasno emas:
select name
, engine -- ΠΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌΡΠΉ "Π΄Π²ΠΈΠΆΠΎΠΊ" ("MergeTree", "Dictionary" etc)
, ...
from system.tables
where database = 'HR'
Kassandrada (jadvallar o'rniga ustunlar oilalari va sxemalar o'rniga kalit bo'shliqlari mavjud) shunga o'xshash narsani qilish mumkin:
select columnfamily_name
, compaction_strategy_class -- Π‘ΡΡΠ°ΡΠ΅Π³ΠΈΡ ΡΠ±ΠΎΡΠΊΠΈ ΠΌΡΡΠΎΡΠ°
, gc_grace_seconds -- ΠΡΠ΅ΠΌΡ ΠΆΠΈΠ·Π½ΠΈ ΠΌΡΡΠΎΡΠ°
, ...
from system.schema_columnfamilies
where keyspace_name = 'HR'
Ko'pgina boshqa ma'lumotlar bazalari uchun siz shunga o'xshash so'rovlarni topishingiz mumkin (hatto Mongoda ham mavjud
Albatta, bu bilan siz nafaqat jadvallar, balki umuman har qanday ob'ekt haqida ma'lumot olishingiz mumkin. Vaqti-vaqti bilan mehribon odamlar turli xil ma'lumotlar bazalari uchun bunday kodni baham ko'rishadi, masalan, "PostgreSQL ma'lumotlar bazalarini hujjatlashtirish funktsiyalari" habra maqolalarida (
Natijada, ob'ektlarni navigatsiya qilish va qidirishning ushbu usuli ancha moslashuvchan bo'lib, ko'p vaqtni tejaydi va kerakli ma'lumotni hozirda zarur bo'lgan shaklda olish imkonini beradi (masalan, postda tasvirlanganidek).
Ob'ektlar bilan operatsiyalar
Biz kerakli narsalarni topib, o'rganib chiqqanimizdan so'ng, ular bilan foydali narsalarni qilish vaqti keldi. Tabiiyki, barmoqlaringizni klaviaturadan uzmasdan ham.
Hech kimga sir emaski, jadvalni shunchaki o'chirish deyarli barcha ma'lumotlar bazalarida bir xil ko'rinadi:
drop table hr.persons
Ammo stolni yaratish bilan u yanada qiziqarli bo'ladi. Deyarli har qanday DBMS (shu jumladan, ko'p NoSQL) u yoki bu shaklda "jadval yaratishi" mumkin va uning asosiy qismi biroz farq qilishi mumkin (nomi, ustunlar ro'yxati, ma'lumotlar turlari), ammo boshqa tafsilotlar keskin farq qilishi va ma'lumotlarga bog'liq bo'lishi mumkin. ichki qurilma va ma'lum bir ma'lumotlar bazasining imkoniyatlari. Mening sevimli misolim, Oracle hujjatlarida "jadval yaratish" sintaksisi uchun faqat "yalang'och" BNFlar mavjud.
Bundan tashqari, ko'pgina ma'lumotlar bazalari boshqa ma'lumotlar bazalarida mavjud bo'lmagan o'ziga xos turdagi ob'ektlarga ega. Bundan tashqari, biz nafaqat ma'lumotlar bazasi ob'ektlarida, balki DBMSning o'zida ham operatsiyalarni bajarishimiz mumkin, masalan, jarayonni "o'ldirish", xotira maydonini bo'shatish, kuzatishni yoqish, "faqat o'qish" rejimiga o'tish va boshqalar.
Endi biroz chizamiz
Eng keng tarqalgan vazifalardan biri - ma'lumotlar bazasi ob'ektlari bilan diagramma qurish va ular orasidagi ob'ektlar va aloqalarni chiroyli rasmda ko'rishdir. Deyarli har qanday grafik IDE, alohida "buyruqlar qatori" yordam dasturlari, maxsus grafik vositalar va modelerlar buni amalga oshirishi mumkin. Ular siz uchun "iloji boricha" nimanidir chizishadi va siz konfiguratsiya faylidagi bir nechta parametrlar yoki interfeysdagi tasdiqlash qutilari yordamida bu jarayonga ozgina ta'sir qilishingiz mumkin.
Ammo bu muammoni ancha sodda, moslashuvchan va oqlangan va, albatta, kod yordamida hal qilish mumkin. Har qanday murakkablikdagi diagrammalarni yaratish uchun bizda bir nechta maxsus belgilash tillari (DOT, GraphML va boshqalar) mavjud va ular uchun bunday ko'rsatmalarni o'qiy oladigan va ularni turli formatlarda tasvirlashi mumkin bo'lgan to'liq tarqoq ilovalar (GraphViz, PlantUML, Mermaid) mavjud. . Xo'sh, biz allaqachon ob'ektlar va ular orasidagi aloqalar haqida ma'lumot olishni bilamiz.
Mana bu qanday ko'rinishi mumkinligiga kichik misol, PlantUML va
select '@startuml'||chr(10)||'hide methods'||chr(10)||'hide stereotypes' union all
select distinct ccu.table_name || ' --|> ' ||
tc.table_name as val
from table_constraints as tc
join key_column_usage as kcu
on tc.constraint_name = kcu.constraint_name
join constraint_column_usage as ccu
on ccu.constraint_name = tc.constraint_name
where tc.constraint_type = 'FOREIGN KEY'
and tc.table_name ~ '.*' union all
select '@enduml'
Va agar siz biroz harakat qilsangiz, unda asoslanadi
SQL so'rovi biroz murakkabroq
-- Π¨Π°ΠΏΠΊΠ°
select '@startuml
!define Table(name,desc) class name as "desc" << (T,#FFAAAA) >>
!define primary_key(x) <b>x</b>
!define unique(x) <color:green>x</color>
!define not_null(x) <u>x</u>
hide methods
hide stereotypes'
union all
-- Π’Π°Π±Π»ΠΈΡΡ
select format('Table(%s, "%s n information about %s") {'||chr(10), table_name, table_name, table_name) ||
(select string_agg(column_name || ' ' || upper(udt_name), chr(10))
from information_schema.columns
where table_schema = 'public'
and table_name = t.table_name) || chr(10) || '}'
from information_schema.tables t
where table_schema = 'public'
union all
-- Π‘Π²ΡΠ·ΠΈ ΠΌΠ΅ΠΆΠ΄Ρ ΡΠ°Π±Π»ΠΈΡΠ°ΠΌΠΈ
select distinct ccu.table_name || ' "1" --> "0..N" ' || tc.table_name || format(' : "A %s may haven many %s"', ccu.table_name, tc.table_name)
from information_schema.table_constraints as tc
join information_schema.key_column_usage as kcu on tc.constraint_name = kcu.constraint_name
join information_schema.constraint_column_usage as ccu on ccu.constraint_name = tc.constraint_name
where tc.constraint_type = 'FOREIGN KEY'
and ccu.constraint_schema = 'public'
and tc.table_name ~ '.*'
union all
-- ΠΠΎΠ΄Π²Π°Π»
select '@enduml'
Agar diqqat bilan qarasangiz, kaput ostida ko'plab vizualizatsiya vositalari ham shunga o'xshash so'rovlardan foydalanadi. To'g'ri, bu so'rovlar odatda chuqurdir
Ko'rsatkichlar va monitoring
Keling, an'anaviy murakkab mavzuga o'tamiz - ma'lumotlar bazasining ishlashi monitoringi. Menga "do'stlarimdan biri" aytgan kichik haqiqiy voqeani eslayman. Boshqa bir loyihada ma'lum bir kuchli DBA yashagan va ishlab chiquvchilarning bir nechtasi uni shaxsan bilishgan yoki uni shaxsan ko'rishgan (mish-mishlarga ko'ra, u keyingi binoda ishlagan bo'lsa ham). "X" soatida yirik chakana sotuvchining poduction tizimi yana "o'zini yomon his qila" boshlaganida, u jimgina Oracle Enterprise Manager-dan grafiklarning skrinshotlarini yubordi, unda u "tushunish" uchun qizil marker bilan muhim joylarni diqqat bilan ajratib ko'rsatdi ( Bu, yumshoq qilib aytganda, unchalik yordam bermadi). Va bu "foto karta" asosida men davolanishim kerak edi. Shu bilan birga, hech kim qimmatbaho (so'zning ikkala ma'nosida) korxona menejeriga kira olmadi, chunki tizim murakkab va qimmat, to'satdan "ishlab chiquvchilar biror narsaga qoqilib, hamma narsani buzadilar". Shuning uchun, ishlab chiquvchilar "empirik" tormozlarning joylashuvi va sababini topdilar va yamoqni chiqardilar. Agar DBAdan qoβrqinchli xat yaqin orada yana kelmasa, hamma yengil nafas olib, hozirgi vazifalariga qaytadi (yangi Xatgacha).
Ammo monitoring jarayoni yanada qiziqarli va do'stona, eng muhimi, hamma uchun ochiq va shaffof ko'rinishi mumkin. Hech bo'lmaganda uning asosiy qismi, asosiy monitoring tizimlariga qo'shimcha sifatida (ular, albatta, foydali va ko'p hollarda almashtirib bo'lmaydigan). Har qanday DBMS o'zining joriy holati va ishlashi haqida ma'lumot almashish uchun bepul va mutlaqo bepul. Xuddi shu "qonli" Oracle DB da ishlash haqida deyarli har qanday ma'lumotni tizim ko'rinishidan, jarayonlar va seanslardan tortib bufer kesh holatigacha olish mumkin (masalan,
Shunday qilib, maxsus sql so'rovlarini bajara oladigan qandaydir ko'rsatkichlar yig'uvchisi (Telegraf, Metricbeat, Collectd), ushbu ko'rsatkichlarni saqlash (InfluxDB, Elasticsearch, Timescaledb) va vizualizator (Grafana, Kibana) bilan qurollangan holda, siz juda oson bo'lishingiz mumkin. va boshqa tizim miqyosidagi ko'rsatkichlar bilan chambarchas integratsiyalangan moslashuvchan monitoring tizimi (masalan, dastur serveridan, OTdan va boshqalardan olinadi). Masalan, bu pgwatch2 da amalga oshiriladi, u InfluxDB + Grafana kombinatsiyasidan va tizim ko'rinishlari uchun so'rovlar to'plamidan foydalanadi, ularga ham kirish mumkin
jami
Va bu oddiy SQL kodidan foydalangan holda bizning ma'lumotlar bazasi bilan nima qilish mumkinligining taxminiy ro'yxati. Ishonchim komilki, siz yana ko'p foydalanishni topishingiz mumkin, sharhlarda yozing. Va biz bularning barchasini qanday avtomatlashtirish (va eng muhimi, nima uchun) haqida gaplashamiz va keyingi safar CI/CD quvuriga qo'shamiz.
Manba: www.habr.com