SQL, hvað gæti verið einfaldara? Hvert okkar getur skrifað einfalda beiðni - við skrifum velja, skráðu þá dálka sem þarf, síðan frá, nafn töflu, nokkur skilyrði í þar sem og það er allt - gagnleg gögn eru í vasa okkar og (næstum) óháð því hvaða DBMS er undir hettunni á þeim tíma (eða kannski
Og við skulum byrja strax frá
Hlutatengslakortlagning
Stuðningsmenn ORM meta jafnan hraða og auðvelda þróun, sjálfstæði frá DBMS og hreinum kóða. Fyrir mörg okkar er kóðinn til að vinna með gagnagrunninn (og oft gagnagrunninn sjálfan)
þetta lítur yfirleitt eitthvað svona út...
@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;
}
...
Líkanið er hengt með snjöllum athugasemdum og einhvers staðar á bak við tjöldin býr hraustur ORM til og framkvæmir tonn af SQL kóða. Við the vegur, verktaki reyna sitt besta til að einangra sig frá gagnagrunni sínum með kílómetra af útdrætti, sem bendir til nokkurra
Hinum megin við hindrunina taka fylgismenn hreins „handgerðra“ SQL eftir hæfileikanum til að kreista allan safann úr DBMS þeirra án viðbótarlaga og útdráttar. Fyrir vikið birtast „gagnamiðuð“ verkefni þar sem sérþjálfað fólk tekur þátt í gagnagrunninum (þeir eru líka „basicists“, þeir eru líka „basicists“, þeir eru líka „basdeners“ o.s.frv.), og þróunaraðilarnir þarf aðeins að „draga“ tilbúnum skoðunum og geymdum verklagsreglum, án þess að fara í smáatriði.
Hvað ef við hefðum það besta af báðum heimum? Hvernig þetta er gert í dásamlegu tóli með nafni sem gefur líf
Clojure er flott tungumál til að búa til DSL, en SQL sjálft er flott DSL og við þurfum ekki annað. S-tjáningar eru frábærar, en þær bæta engu nýju við hér. Fyrir vikið fáum við sviga vegna sviga. Ekki sammála? Bíddu svo eftir augnablikinu þegar útdrátturinn yfir gagnagrunninn byrjar að leka og þú byrjar að berjast við aðgerðina (raw-sql)
Svo hvað ætti ég að gera? Við skulum skilja SQL eftir sem venjulegan SQL - ein skrá fyrir hverja beiðni:
-- name: users-by-country
select *
from users
where country_code = :country_code
... og lestu síðan þessa skrá og breyttu henni í venjulega Clojure aðgerð:
(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" ...} ...)
Með því að fylgja "SQL út af fyrir sig, Clojure af sjálfu sér" meginreglunni færðu:
- Ekkert setningafræðilegt á óvart. Gagnagrunnurinn þinn (eins og hver annar) er ekki 100% í samræmi við SQL staðalinn - en þetta skiptir ekki máli fyrir Yesql. Þú munt aldrei eyða tíma í að leita að aðgerðum með samsvarandi SQL setningafræði. Þú þarft aldrei að fara aftur í aðgerð (raw-sql "sum('funky'::SYNTAX)")).
- Besti ritstjóri stuðningur. Ritstjórinn þinn hefur nú þegar framúrskarandi SQL stuðning. Með því að vista SQL sem SQL geturðu einfaldlega notað það.
- Team eindrægni. DBAs þínir geta lesið og skrifað SQL sem þú notar í Clojure verkefninu þínu.
- Auðveldari frammistöðustilling. Þarftu að búa til áætlun fyrir erfiða fyrirspurn? Þetta er ekki vandamál þegar fyrirspurnin þín er venjuleg SQL.
- Endurnota fyrirspurnir. Dragðu og slepptu sömu SQL skrám í önnur verkefni vegna þess að það er bara venjulegt gamalt SQL - deildu því bara.
Hugmyndin er að mínu mati mjög flott og á sama tíma mjög einföld, því verkefnið hefur fengið marga
IDE & DB stjórnendur
Byrjum á einföldu hversdagsverki. Oft þurfum við að leita að einhverjum hlutum í gagnagrunninum, til dæmis finna töflu í skemanu og rannsaka uppbyggingu þess (hvaða dálkar, lyklar, vísitölur, skorður o.s.frv. eru notaðir). Og frá hvaða grafísku IDE eða litlum DB-stjóra, fyrst og fremst, búumst við við nákvæmlega þessum hæfileikum. Svo að það sé hratt og ekki þurfi að bíða í hálftíma þar til gluggi með nauðsynlegum upplýsingum er dreginn upp (sérstaklega með hægri tengingu við fjarlægan gagnagrunn) og á sama tíma eru upplýsingarnar sem berast ferskar og viðeigandi, og ekki rusl í skyndiminni. Þar að auki, því flóknari og stærri sem gagnagrunnurinn er og því fleiri sem þeir eru, því erfiðara er að gera þetta.
En yfirleitt hendi ég músinni og skrifa bara kóða. Segjum að þú þurfir að finna út hvaða töflur (og með hvaða eiginleikum) eru í "HR" skemanu. Í flestum DBMS er hægt að ná tilætluðum árangri með þessari einföldu fyrirspurn frá information_schema:
select table_name
, ...
from information_schema.tables
where schema = 'HR'
Frá gagnagrunni til gagnagrunns er innihald slíkra viðmiðunartafla mismunandi eftir getu hvers DBMS. Og, til dæmis, fyrir MySQL, úr sömu uppflettibók er hægt að fá töflubreytur sem eru sértækar fyrir þetta DBMS:
select table_name
, storage_engine -- Используемый "движок" ("MyISAM", "InnoDB" etc)
, row_format -- Формат строки ("Fixed", "Dynamic" etc)
, ...
from information_schema.tables
where schema = 'HR'
Oracle þekkir ekki information_schema, en það hefur það
select table_name
, pct_free -- Минимум свободного места в блоке данных (%)
, pct_used -- Минимум используемого места в блоке данных (%)
, last_analyzed -- Дата последнего сбора статистики
, ...
from all_tables
where owner = 'HR'
ClickHouse er engin undantekning:
select name
, engine -- Используемый "движок" ("MergeTree", "Dictionary" etc)
, ...
from system.tables
where database = 'HR'
Eitthvað svipað er hægt að gera í Cassandra (sem hefur dálkafjölskyldur í staðinn fyrir töflur og lyklarými í stað skemas):
select columnfamily_name
, compaction_strategy_class -- Стратегия сборки мусора
, gc_grace_seconds -- Время жизни мусора
, ...
from system.schema_columnfamilies
where keyspace_name = 'HR'
Fyrir flesta aðra gagnagrunna geturðu líka komið með svipaðar fyrirspurnir (jafnvel Mongo hefur
Auðvitað, á þennan hátt geturðu fengið upplýsingar ekki aðeins um töflur, heldur um hvaða hlut sem er almennt. Af og til deilir vingjarnlegt fólk slíkum kóða fyrir mismunandi gagnagrunna, eins og til dæmis í röð habra greina „Functions for documenting PostgreSQL gagnagrunna“ (
Þess vegna er þessi aðferð við að fletta og leita að hlutum mun sveigjanlegri, sparar mikinn tíma og gerir þér kleift að fá nákvæmlega upplýsingarnar á því formi sem þær eru nauðsynlegar (eins og til dæmis lýst í færslunni
Aðgerðir með hluti
Eftir að við höfum fundið og rannsakað nauðsynlega hluti er kominn tími til að gera eitthvað gagnlegt við þá. Auðvitað, líka án þess að taka fingurna af lyklaborðinu.
Það er ekkert leyndarmál að einfaldlega að eyða töflu mun líta eins út í næstum öllum gagnagrunnum:
drop table hr.persons
En með stofnun borðsins verður það áhugaverðara. Næstum hvaða DBMS sem er (þar á meðal mörg NoSQL) getur „búið til töflu“ á einu eða öðru formi, og meginhluti hennar mun jafnvel vera örlítið frábrugðinn (nafn, listi yfir dálka, gagnategundir), en aðrar upplýsingar geta verið verulega mismunandi og fer eftir innra tæki og getu tiltekins DBMS. Uppáhalds dæmið mitt er að í Oracle skjölunum eru aðeins „naktir“ BNF fyrir setningafræði „búa til töflu“
Einnig hafa margar DBMS sínar eigin sérstakar gerðir af hlutum sem eru ekki tiltækar í öðrum DBMS. Þar að auki getum við framkvæmt aðgerðir ekki aðeins á gagnagrunnshlutum, heldur einnig á DBMS sjálfu, til dæmis, „drepið“ ferli, losað um minnissvæði, virkjað rakningu, skipt yfir í „read only“ ham og margt fleira.
Nú skulum við teikna aðeins
Eitt algengasta verkefnið er að smíða skýringarmynd með gagnagrunnshlutum og sjá hlutina og tengslin á milli þeirra í fallegri mynd. Næstum hvaða grafísku IDE, aðskilin „skipanalínu“ tól, sérhæfð grafísk verkfæri og módelmenn geta gert þetta. Þeir munu teikna eitthvað fyrir þig „eins og þeir geta“ og þú getur aðeins haft áhrif á þetta ferli með hjálp nokkurra breytu í stillingarskránni eða gátreitum í viðmótinu.
En þetta vandamál er hægt að leysa mun einfaldara, sveigjanlegra og glæsilegra, og auðvitað með hjálp kóða. Til að búa til skýringarmyndir af hvaða flóknu sem er, höfum við nokkur sérhæfð álagningarmál (DOT, GraphML o.s.frv.), og fyrir þau fjöldann allan af forritum (GraphViz, PlantUML, Mermaid) sem geta lesið slíkar leiðbeiningar og séð þær fyrir sér á ýmsum sniðum . Jæja, við vitum nú þegar hvernig á að fá upplýsingar um hluti og tengingar á milli þeirra.
Hér er lítið dæmi um hvernig þetta gæti litið út, með því að nota PlantUML og
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'
Og ef þú reynir aðeins, þá byggt á
SQL fyrirspurnin er aðeins flóknari
-- Шапка
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'
Ef þú lítur vel, undir hettunni nota mörg sjónræn verkfæri líka svipaðar fyrirspurnir. Að vísu eru þessar beiðnir yfirleitt djúpar
Mælingar og eftirlit
Við skulum halda áfram að hefðbundnu flóknu efni - eftirlit með frammistöðu gagnagrunns. Ég man eftir lítilli sannri sögu sem „einn af vinum mínum“ sagði mér. Í öðru verkefni bjó ákveðinn öflugur DBA og fáir verktaki þekktu hann persónulega, eða höfðu nokkurn tíma séð hann í eigin persónu (þrátt fyrir að, samkvæmt sögusögnum, hafi hann unnið einhvers staðar í næstu byggingu). Á klukkutímanum „X“, þegar framleiðslukerfi stórs smásala fór að „líða illa“ enn og aftur, sendi hann hljóðlaust skjáskot af línuritum frá Oracle Enterprise Manager, þar sem hann auðkenndi vandlega mikilvæga staði með rauðu merki fyrir „skiljanleika“ ( þetta hjálpaði vægast sagt ekki mikið). Og miðað við þetta „myndakort“ þurfti ég að meðhöndla. Á sama tíma hafði enginn aðgang að hinum dýrmæta (í báðum merkingum orðsins) Enterprise Manager, vegna þess Kerfið er flókið og dýrt, skyndilega „rekasta verktaki á einhverju og brjóta allt“. Þess vegna fundu verktaki "reynslufræðilega" staðsetningu og orsök bremsanna og gáfu út plástur. Ef ógnarbréfið frá DBA kæmi ekki aftur á næstunni, þá myndu allir anda léttar og snúa aftur til núverandi verkefna (þar til nýja bréfsins).
En eftirlitsferlið getur litið skemmtilegra og vingjarnlegra út og síðast en ekki síst aðgengilegt og gagnsætt fyrir alla. Að minnsta kosti grunnhluti þess, sem viðbót við helstu vöktunarkerfi (sem eru vissulega gagnleg og í mörgum tilfellum óbætanleg). Sérhvert DBMS er frjálst og algerlega ókeypis til að deila upplýsingum um núverandi ástand og frammistöðu. Í sömu „blóðugu“ Oracle DB er hægt að nálgast næstum allar upplýsingar um frammistöðu úr kerfissýnum, allt frá ferlum og lotum til stöðu biðminni skyndiminni (td,
Þannig, vopnaður einhvers konar mæligildasafnara (Telegraf, Metricbeat, Collectd) sem getur framkvæmt sérsniðnar sql fyrirspurnir, geymslu á þessum mæligildum (InfluxDB, Elasticsearch, Timescaledb) og visualizer (Grafana, Kibana), geturðu fengið nokkuð auðvelt og sveigjanlegt eftirlitskerfi sem verður náið samþætt öðrum kerfisbundnum mæligildum (sem fæst td frá forritaþjóninum, frá stýrikerfinu osfrv.). Eins og til dæmis er þetta gert í pgwatch2, sem notar InfluxDB + Grafana samsetninguna og mengi fyrirspurna til kerfissýna, sem einnig er hægt að nálgast
Alls
Og þetta er aðeins áætlaður listi yfir það sem hægt er að gera með gagnagrunninum okkar með því að nota venjulegan SQL kóða. Ég er viss um að þú getur fundið miklu fleiri notkun, skrifaðu í athugasemdum. Og við munum tala um hvernig (og síðast en ekki síst hvers vegna) á að gera allt þetta sjálfvirkt og hafa það með í CI/CD leiðslunni þinni næst.
Heimild: www.habr.com