SQL, kas var bÅ«t vienkÄrÅ”Äks? Katrs no mums var uzrakstÄ«t vienkÄrÅ”u pieprasÄ«jumu ā mÄs ierakstÄm atlasÄ«t, uzskaitiet vajadzÄ«gÄs kolonnas un pÄc tam no, tabulas nosaukums, daži nosacÄ«jumi kur un tas arÄ« viss ā noderÄ«gi dati ir mÅ«su kabatÄ un (gandrÄ«z) neatkarÄ«gi no tÄ, kura DBVS tajÄ laikÄ atrodas zem pÄrsega (vai varbÅ«t
Un sÄksim tieÅ”i no
Objektu relÄciju kartÄÅ”ana
ORM atbalstÄ«tÄji tradicionÄli novÄrtÄ Ätrumu un attÄ«stÄ«bas vieglumu, neatkarÄ«bu no DBVS un tÄ«ru kodu. Daudziem no mums kods darbam ar datu bÄzi (un bieži arÄ« paÅ”u datu bÄzi)
tas parasti izskatÄs apmÄram Å”Ädi...
@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;
}
...
Modelis ir piekÄrts ar gudrÄm anotÄcijÄm, un kaut kur aizkulisÄs drosmÄ«gs ORM Ä£enerÄ un izpilda daudz SQL koda. Starp citu, izstrÄdÄtÄji cenÅ”as visu iespÄjamo, lai izolÄtu sevi no savas datu bÄzes ar abstrakciju kilometriem, kas norÄda uz dažiem
OtrÄ barikÄžu pusÄ tÄ«ra āroku darbsā SQL piekritÄji atzÄ«mÄ spÄju izspiest visu sulu no DBVS bez papildu slÄÅiem un abstrakcijÄm. RezultÄtÄ parÄdÄs ādatu centriskiā projekti, kur datu bÄzÄ tiek iesaistÄ«ti speciÄli apmÄcÄ«ti cilvÄki (viÅi arÄ« ir ābasicistsā, viÅi arÄ« ir ābasicistsā, viÅi arÄ« ir ābasdenersā utt.), un izstrÄdÄtÄji. atliek tikai āizvilktā jau gatavus skatus un saglabÄtÄs procedÅ«ras, neiedziļinoties.
KÄ bÅ«tu, ja mums bÅ«tu labÄkais no abÄm pasaulÄm? KÄ tas tiek darÄ«ts brÄ«niŔķīgÄ rÄ«kÄ ar dzÄ«vi apliecinoÅ”u nosaukumu
Clojure ir forÅ”a valoda DSL izveidei, bet pati SQL ir forÅ”a DSL, un mums nav vajadzÄ«ga cita. S-izteiksmes ir lieliskas, taÄu tÄs Å”eit neko jaunu nepievieno. RezultÄtÄ mÄs iegÅ«stam kronÅ”teinus kronÅ”teinu labad. Vai nepiekrÄ«tu? Tad pagaidiet brÄ«di, kad sÄks noplÅ«st abstrakcija pÄr datubÄzi, un jÅ«s sÄkat cÄ«nÄ«ties ar funkciju (raw-sql)
TÄtad, kas man jÄdara? AtstÄsim SQL kÄ parasto SQL ā viens fails katram pieprasÄ«jumam:
-- name: users-by-country
select *
from users
where country_code = :country_code
... un pÄc tam izlasiet Å”o failu, pÄrvÄrÅ”ot to par parastu Clojure funkciju:
(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" ...} ...)
IevÄrojot principu "SQL pats par sevi, Clojure pats par sevi", jÅ«s iegÅ«stat:
- Nav sintaktisku pÄrsteigumu. JÅ«su datu bÄze (tÄpat kÄ jebkura cita) nav 100% saderÄ«ga ar SQL standartu, taÄu tas nav svarÄ«gi attiecÄ«bÄ uz Yesql. JÅ«s nekad netÄrÄsit laiku, meklÄjot funkcijas ar SQL ekvivalentu sintaksi. Jums nekad nebÅ«s jÄatgriežas pie funkcijas (raw-sql "some('funky'::SYNTAX)")).
- LabÄkais redaktora atbalsts. JÅ«su redaktoram jau ir lielisks SQL atbalsts. SaglabÄjot SQL kÄ SQL, varat to vienkÄrÅ”i izmantot.
- Komandu saderÄ«ba. JÅ«su DBA var lasÄ«t un rakstÄ«t SQL, ko izmantojat savÄ Clojure projektÄ.
- VienkÄrÅ”Äka veiktspÄjas regulÄÅ”ana. NepiecieÅ”ams izveidot plÄnu problemÄtiskam vaicÄjumam? TÄ nav problÄma, ja jÅ«su vaicÄjums ir parasts SQL.
- VaicÄjumu atkÄrtota izmantoÅ”ana. Velciet un nometiet tos paÅ”us SQL failus citos projektos, jo tas ir vienkÄrÅ”i vecs SQL ā vienkÄrÅ”i kopÄ«gojiet to.
ManuprÄt, ideja ir ļoti forÅ”a un tajÄ paÅ”Ä laikÄ Ä¼oti vienkÄrÅ”a, pateicoties kam projekts ir ieguvis daudzus
IDE un DB vadÄ«tÄji
SÄksim ar vienkÄrÅ”u ikdienas uzdevumu. Bieži datu bÄzÄ ir jÄmeklÄ kÄdi objekti, piemÄram, shÄmÄ jÄatrod tabula un jÄizpÄta tÄs struktÅ«ra (kÄdas kolonnas, atslÄgas, indeksi, ierobežojumi utt. tiek lietoti). Un no jebkura grafiskÄ IDE vai neliela DB pÄrvaldnieka, pirmkÄrt, mÄs sagaidÄm tieÅ”i Ŕīs spÄjas. Lai tas ir Ätri un nav jÄgaida pusstunda, lÄ«dz tiek uzzÄ«mÄts logs ar nepiecieÅ”amo informÄciju (Ä«paÅ”i ar lÄnu savienojumu ar attÄlo datu bÄzi), un tajÄ paÅ”Ä laikÄ saÅemtÄ informÄcija ir svaiga un aktuÄla, un nav keÅ”atmiÅas junk. TurklÄt, jo sarežģītÄka un lielÄka datu bÄze un jo lielÄks to skaits, jo grÅ«tÄk to izdarÄ«t.
Bet parasti es izmetu peli un vienkÄrÅ”i uzrakstu kodu. PieÅemsim, ka jums ir jÄnoskaidro, kuras tabulas (un ar kurÄm Ä«paŔībÄm) ir ietvertas "HR" shÄmÄ. LielÄkajÄ daÄ¼Ä DBVS vÄlamo rezultÄtu var sasniegt ar Å”o vienkÄrÅ”o vaicÄjumu no information_schema:
select table_name
, ...
from information_schema.tables
where schema = 'HR'
DažÄdÄs datubÄzÄs Å”Ädu atsauces tabulu saturs atŔķiras atkarÄ«bÄ no katras DBVS iespÄjÄm. Un, piemÄram, MySQL no tÄs paÅ”as atsauces grÄmatas varat iegÅ«t tabulas parametrus, kas raksturÄ«gi Å”ai DBVS:
select table_name
, storage_engine -- ŠŃŠæŠ¾Š»ŃŠ·ŃŠµŠ¼ŃŠ¹ "Š“Š²ŠøŠ¶Š¾Šŗ" ("MyISAM", "InnoDB" etc)
, row_format -- Š¤Š¾ŃŠ¼Š°Ń ŃŃŃŠ¾ŠŗŠø ("Fixed", "Dynamic" etc)
, ...
from information_schema.tables
where schema = 'HR'
Oracle nezina information_schema, bet tÄ ir
select table_name
, pct_free -- ŠŠøŠ½ŠøŠ¼ŃŠ¼ ŃŠ²Š¾Š±Š¾Š“Š½Š¾Š³Š¾ Š¼ŠµŃŃŠ° Š² Š±Š»Š¾ŠŗŠµ Š“Š°Š½Š½ŃŃ
(%)
, pct_used -- ŠŠøŠ½ŠøŠ¼ŃŠ¼ ŠøŃŠæŠ¾Š»ŃŠ·ŃŠµŠ¼Š¾Š³Š¾ Š¼ŠµŃŃŠ° Š² Š±Š»Š¾ŠŗŠµ Š“Š°Š½Š½ŃŃ
(%)
, last_analyzed -- ŠŠ°ŃŠ° ŠæŠ¾ŃŠ»ŠµŠ“Š½ŠµŠ³Š¾ ŃŠ±Š¾ŃŠ° ŃŃŠ°ŃŠøŃŃŠøŠŗŠø
, ...
from all_tables
where owner = 'HR'
ClickHouse nav izÅÄmums:
select name
, engine -- ŠŃŠæŠ¾Š»ŃŠ·ŃŠµŠ¼ŃŠ¹ "Š“Š²ŠøŠ¶Š¾Šŗ" ("MergeTree", "Dictionary" etc)
, ...
from system.tables
where database = 'HR'
Kaut ko lÄ«dzÄ«gu var izdarÄ«t programmÄ Cassandra (kurÄ tabulu vietÄ ir kolonnu saimes, bet shÄmu vietÄ ir atslÄgas vietas):
select columnfamily_name
, compaction_strategy_class -- Š”ŃŃŠ°ŃŠµŠ³ŠøŃ ŃŠ±Š¾ŃŠŗŠø Š¼ŃŃŠ¾ŃŠ°
, gc_grace_seconds -- ŠŃŠµŠ¼Ń Š¶ŠøŠ·Š½Šø Š¼ŃŃŠ¾ŃŠ°
, ...
from system.schema_columnfamilies
where keyspace_name = 'HR'
LielÄkajai daļai citu datu bÄzu varat arÄ« piedÄvÄt lÄ«dzÄ«gus vaicÄjumus (pat Mongo ir
Protams, tÄdÄ veidÄ var iegÅ«t informÄciju ne tikai par tabulÄm, bet par jebkuru objektu kopumÄ. Laiku pa laikam laipni cilvÄki dalÄs ar tÄdu kodu dažÄdÄm datu bÄzÄm, kÄ, piemÄram, habra rakstu sÄrijÄ āPostgreSQL datu bÄzu dokumentÄÅ”anas funkcijasā (
LÄ«dz ar to Ŕī navigÄcijas un objektu meklÄÅ”anas metode ir daudz elastÄ«gÄka, ietaupa daudz laika un ļauj iegÅ«t tieÅ”i informÄciju tÄdÄ formÄ, kÄdÄ tÄ Å”obrÄ«d ir nepiecieÅ”ama (kÄ, piemÄram, aprakstÄ«ts ierakstÄ
Darbības ar objektiem
Kad esam atraduÅ”i un izpÄtÄ«juÅ”i nepiecieÅ”amos objektus, ir pienÄcis laiks ar tiem darÄ«t kaut ko noderÄ«gu. Protams, arÄ« neatraujot pirkstus no tastatÅ«ras.
Nav noslÄpums, ka, vienkÄrÅ”i dzÄÅ”ot tabulu, gandrÄ«z visÄs datu bÄzÄs izskatÄ«sies vienÄdi:
drop table hr.persons
Bet ar tabulas izveidi kļūst interesantÄk. GandrÄ«z jebkura DBVS (tostarp daudzas NoSQL) var āizveidot tabuluā vienÄ vai otrÄ veidÄ, un tÄs galvenÄ daļa pat nedaudz atŔķirsies (nosaukums, kolonnu saraksts, datu tipi), bet citas detaļas var krasi atŔķirties un ir atkarÄ«gas no iekÅ”ÄjÄ ierÄ«ce un konkrÄtas DBVS iespÄjas. Mans iecienÄ«tÄkais piemÄrs ir tÄds, ka Oracle dokumentÄcijÄ sintaksei āizveidot tabuluā ir tikai ākailiā BNF.
TurklÄt daudzÄm DBVS ir savi specifiski objektu veidi, kas nav pieejami citÄs DBVS. TurklÄt mÄs varam veikt darbÄ«bas ne tikai ar datu bÄzes objektiem, bet arÄ« ar paÅ”u DBVS, piemÄram, ānogalinÄtā procesu, atbrÄ«vot daļu atmiÅas, iespÄjot izsekoÅ”anu, pÄrslÄgties uz ātikai lasÄ«Å”anasā režīmu un daudz ko citu.
Tagad nedaudz zÄ«mÄsim
Viens no biežÄkajiem uzdevumiem ir izveidot diagrammu ar datu bÄzes objektiem un redzÄt objektus un savienojumus starp tiem skaistÄ attÄlÄ. To var izdarÄ«t gandrÄ«z jebkura grafiskÄ IDE, atseviŔķas "komandrindas" utilÄ«tas, specializÄti grafiskie rÄ«ki un modelÄtÄji. ViÅi jums kaut ko uzzÄ«mÄs, "cik labi vien varÄs", un jÅ«s varat nedaudz ietekmÄt Å”o procesu, tikai izmantojot dažus parametrus konfigurÄcijas failÄ vai interfeisa izvÄles rÅ«tiÅas.
Bet Å”o problÄmu var atrisinÄt daudz vienkÄrÅ”Äk, elastÄ«gÄk un elegantÄk, un, protams, ar koda palÄ«dzÄ«bu. Lai izveidotu jebkuras sarežģītÄ«bas diagrammas, mums ir vairÄkas specializÄtas iezÄ«mÄÅ”anas valodas (DOT, GraphML uc), un tÄm ir vesela lietojumprogrammu izkliede (GraphViz, PlantUML, Mermaid), kas var lasÄ«t Å”Ädas instrukcijas un vizualizÄt tÄs dažÄdos formÄtos. . Nu, mÄs jau zinÄm, kÄ iegÅ«t informÄciju par objektiem un savienojumiem starp tiem.
Å eit ir neliels piemÄrs tam, kÄ tas varÄtu izskatÄ«ties, izmantojot PlantUML un
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'
Un, ja jÅ«s mÄÄ£inÄt nedaudz, tad pamatojoties uz
SQL vaicÄjums ir nedaudz sarežģītÄks
-- ŠØŠ°ŠæŠŗŠ°
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'
Ja paskatÄs cieÅ”i, zem pÄrsega daudzi vizualizÄcijas rÄ«ki izmanto arÄ« lÄ«dzÄ«gus vaicÄjumus. Tiesa, Å”ie lÅ«gumi parasti ir dziļi
Metrika un uzraudzība
PÄrejam pie tradicionÄli sarežģītas tÄmas ā datu bÄzes veiktspÄjas monitoringa. Es atceros mazu patiesu stÄstu, ko man stÄstÄ«ja "viens no maniem draugiem". CitÄ projektÄ dzÄ«voja zinÄms spÄcÄ«gs DBA, un daži no izstrÄdÄtÄjiem viÅu pazina personÄ«gi vai kÄdreiz bija redzÄjuÅ”i viÅu klÄtienÄ (neskatoties uz to, ka saskaÅÄ ar baumÄm viÅÅ” strÄdÄja kaut kur blakus ÄkÄ). āXā stundÄ, kad liela mazumtirgotÄja poduction sistÄma atkal sÄka āsliktiā, viÅÅ” klusÄ«bÄ nosÅ«tÄ«ja Oracle Enterprise Manager grafiku ekrÄnuzÅÄmumus, kuros viÅÅ” rÅ«pÄ«gi iezÄ«mÄja kritiskÄs vietas ar sarkanu marÄ·ieri āsaprotamÄ«baiā ( tas, maigi izsakoties, neko daudz nepalÄ«dzÄja). Un, pamatojoties uz Å”o "fotokarti", man bija jÄÄrstÄ. TajÄ paÅ”Ä laikÄ nevienam nebija pieejams dÄrgais (Ŕī vÄrda abÄs nozÄ«mÄs) UzÅÄmuma vadÄ«tÄjs, jo sistÄma ir sarežģīta un dÄrga, pÄkÅ”Åi "izstrÄdÄtÄji uz kaut ko paklupa un visu sabojÄ." TÄpÄc izstrÄdÄtÄji āempÄ«riskiā atrada bremžu atraÅ”anÄs vietu un cÄloni un izlaida ielÄpu. Ja draudÄ«gÄ vÄstule no DBA tuvÄkajÄ laikÄ vairs nepienÄktu, tad visi atviegloti uzelpotu un atgrieztos pie saviem paÅ”reizÄjiem uzdevumiem (lÄ«dz jaunajai VÄstulei).
TaÄu uzraudzÄ«bas process var izskatÄ«ties jautrÄks un draudzÄ«gÄks, un pats galvenais ā pieejams un pÄrskatÄms ikvienam. Vismaz tÄ pamata daļa, kÄ papildinÄjums galvenajÄm uzraudzÄ«bas sistÄmÄm (kuras noteikti ir noderÄ«gas un daudzos gadÄ«jumos neaizvietojamas). Jebkura DBVS var brÄ«vi un pilnÄ«gi bez maksas dalÄ«ties ar informÄciju par tÄs paÅ”reizÄjo stÄvokli un veiktspÄju. TajÄ paÅ”Ä "asiÅainajÄ" Oracle DB gandrÄ«z jebkuru informÄciju par veiktspÄju var iegÅ«t no sistÄmas skatiem, sÄkot no procesiem un sesijÄm lÄ«dz bufera keÅ”atmiÅas stÄvoklim (piemÄram,
TÄdÄjÄdi, bruÅojoties ar sava veida metrikas savÄcÄju (Telegraf, Metricbeat, Collectd), kas var veikt pielÄgotus sql vaicÄjumus, Å”o rÄdÄ«tÄju krÄtuvi (InfluxDB, Elasticsearch, Timescaledb) un vizualizÄtÄju (Grafana, Kibana), jÅ«s varat iegÅ«t diezgan vienkÄrÅ”u un elastÄ«ga uzraudzÄ«bas sistÄma, kas tiks cieÅ”i integrÄta ar citiem sistÄmas mÄroga rÄdÄ«tÄjiem (iegÅ«ta, piemÄram, no lietojumprogrammu servera, no OS utt.). KÄ, piemÄram, tas tiek darÄ«ts pgwatch2, kas izmanto InfluxDB + Grafana kombinÄciju un vaicÄjumu kopu sistÄmas skatiem, kuriem var arÄ« piekļūt
KopÄ
Un tas ir tikai aptuvens saraksts ar to, ko var paveikt ar mÅ«su datubÄzi, izmantojot parasto SQL kodu. Esmu pÄrliecinÄts, ka jÅ«s varat atrast daudz vairÄk lietojumu, rakstiet komentÄros. Un mÄs runÄsim par to, kÄ (un vissvarÄ«gÄk, kÄpÄc) to visu automatizÄt un iekļaut savÄ CI/CD konveijerÄ nÄkamreiz.
Avots: www.habr.com