SQL, ni nini kinachoweza kuwa rahisi zaidi? Kila mmoja wetu anaweza kuandika ombi rahisi - tunaandika teua, orodhesha safu wima zinazohitajika, basi kutoka, jina la jedwali, hali fulani ndani ambapo na hiyo ndiyo yote - data muhimu iko kwenye mfuko wetu, na (karibu) bila kujali ni DBMS gani iko chini ya kofia wakati huo (au labda
Na wacha tuanze kutoka
Ramani ya kitu na uhusiano
Wafuasi wa ORM kawaida huthamini kasi na urahisi wa maendeleo, uhuru kutoka kwa DBMS na nambari safi. Kwa wengi wetu, nambari ya kufanya kazi na hifadhidata (na mara nyingi hifadhidata yenyewe)
kawaida inaonekana kama hii ...
@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;
}
...
Muundo huo umewekwa kwa maelezo mahiri, na mahali fulani nyuma ya pazia ORM shujaa hutengeneza na kutekeleza tani za msimbo fulani wa SQL. Kwa njia, watengenezaji wanajaribu bora yao kujitenga na hifadhidata yao na kilomita za vifupisho, ambayo inaonyesha baadhi.
Kwa upande mwingine wa vizuizi, wafuasi wa SQL safi "iliyotengenezwa kwa mikono" wanaona uwezo wa kufinya juisi yote kutoka kwa DBMS yao bila tabaka za ziada na vifupisho. Kama matokeo, miradi ya "data-centric" inaonekana, ambapo watu waliofunzwa maalum wanahusika katika hifadhidata (pia ni "basicist", pia ni "basicist", pia ni "basdeners", nk), na watengenezaji. lazima tu "kuvuta" maoni yaliyotengenezwa tayari na taratibu zilizohifadhiwa, bila kuingia katika maelezo.
Je, ikiwa tungekuwa na ulimwengu bora zaidi wa wote wawili? Jinsi hii inafanywa katika chombo cha ajabu kilicho na jina la kuthibitisha maisha
Clojure ni lugha nzuri ya kuunda DSL, lakini SQL yenyewe ni DSL nzuri, na hatuhitaji nyingine. Maneno ya S ni mazuri, lakini hayaongezi chochote kipya hapa. Matokeo yake, tunapata mabano kwa ajili ya mabano. Je, hukubaliani? Kisha subiri wakati ambapo uondoaji juu ya hifadhidata huanza kuvuja na uanze kupigana na kazi (sql ghafi)
Kwa hiyo nifanye nini? Wacha tuache SQL kama SQL ya kawaida - faili moja kwa ombi:
-- name: users-by-country
select *
from users
where country_code = :country_code
... kisha usome faili hii, na kuibadilisha kuwa kazi ya kawaida ya Clojure:
(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" ...} ...)
Kwa kuambatana na kanuni ya "SQL peke yake, Clojure peke yake", unapata:
- Hakuna mshangao wa kisintaksia. Hifadhidata yako (kama nyingine yoyote) hailingani 100% na kiwango cha SQL - lakini hii haijalishi kwa Yesql. Kamwe hautapoteza wakati kutafuta vitendaji na syntax sawa ya SQL. Hutawahi kurudi kwenye kipengele cha kukokotoa (raw-sql "baadhi ('funky'::SYNTAX)")).
- Usaidizi bora wa mhariri. Mhariri wako tayari ana usaidizi bora wa SQL. Kwa kuhifadhi SQL kama SQL unaweza kuitumia tu.
- Utangamano wa timu. DBA zako zinaweza kusoma na kuandika SQL unayotumia katika mradi wako wa Clojure.
- Urekebishaji rahisi wa utendaji. Je! unahitaji kuunda mpango wa swali lenye shida? Hili sio tatizo wakati hoja yako ni SQL ya kawaida.
- Kutumia maswali tena. Buruta na uangushe faili hizo hizo za SQL kwenye miradi mingine kwa sababu ni SQL ya zamani tu - ishiriki tu.
Kwa maoni yangu, wazo ni baridi sana na wakati huo huo ni rahisi sana, shukrani ambayo mradi umepata wengi
Wasimamizi wa IDE na DB
Wacha tuanze na kazi rahisi ya kila siku. Mara nyingi tunapaswa kutafuta vitu vingine kwenye hifadhidata, kwa mfano, kupata jedwali kwenye schema na kusoma muundo wake (ni nguzo gani, funguo, faharisi, vikwazo, nk hutumiwa). Na kutoka kwa IDE yoyote ya picha au meneja mdogo wa DB, kwanza kabisa, tunatarajia uwezo huu haswa. Ili kwamba ni haraka na huna kusubiri nusu saa hadi dirisha na taarifa muhimu inatolewa (hasa kwa uunganisho wa polepole kwenye hifadhidata ya mbali), na wakati huo huo, habari iliyopokelewa ni safi na inafaa, na sio takataka iliyohifadhiwa. Kwa kuongezea, kadiri hifadhidata inavyozidi kuwa ngumu na kubwa na idadi yao kubwa, ndivyo ilivyo ngumu zaidi kufanya hivi.
Lakini kawaida mimi hutupa panya na kuandika nambari tu. Wacha tuseme unahitaji kujua ni meza gani (na ni mali gani) zilizomo kwenye schema ya "HR". Katika DBMS nyingi, matokeo unayotaka yanaweza kupatikana kwa swali hili rahisi kutoka kwa information_schema:
select table_name
, ...
from information_schema.tables
where schema = 'HR'
Kutoka hifadhidata hadi hifadhidata, yaliyomo kwenye jedwali kama hizo za kumbukumbu hutofautiana kulingana na uwezo wa kila DBMS. Na, kwa mfano, kwa MySQL, kutoka kwa kitabu hicho cha kumbukumbu unaweza kupata vigezo vya jedwali maalum kwa DBMS hii:
select table_name
, storage_engine -- ΠΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌΡΠΉ "Π΄Π²ΠΈΠΆΠΎΠΊ" ("MyISAM", "InnoDB" etc)
, row_format -- Π€ΠΎΡΠΌΠ°Ρ ΡΡΡΠΎΠΊΠΈ ("Fixed", "Dynamic" etc)
, ...
from information_schema.tables
where schema = 'HR'
Oracle hajui information_schema, lakini ina
select table_name
, pct_free -- ΠΠΈΠ½ΠΈΠΌΡΠΌ ΡΠ²ΠΎΠ±ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΌΠ΅ΡΡΠ° Π² Π±Π»ΠΎΠΊΠ΅ Π΄Π°Π½Π½ΡΡ
(%)
, pct_used -- ΠΠΈΠ½ΠΈΠΌΡΠΌ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌΠΎΠ³ΠΎ ΠΌΠ΅ΡΡΠ° Π² Π±Π»ΠΎΠΊΠ΅ Π΄Π°Π½Π½ΡΡ
(%)
, last_analyzed -- ΠΠ°ΡΠ° ΠΏΠΎΡΠ»Π΅Π΄Π½Π΅Π³ΠΎ ΡΠ±ΠΎΡΠ° ΡΡΠ°ΡΠΈΡΡΠΈΠΊΠΈ
, ...
from all_tables
where owner = 'HR'
ClickHouse sio ubaguzi:
select name
, engine -- ΠΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌΡΠΉ "Π΄Π²ΠΈΠΆΠΎΠΊ" ("MergeTree", "Dictionary" etc)
, ...
from system.tables
where database = 'HR'
Kitu kama hicho kinaweza kufanywa katika Cassandra (ambayo ina safu familia badala ya meza na nafasi muhimu badala ya schemas):
select columnfamily_name
, compaction_strategy_class -- Π‘ΡΡΠ°ΡΠ΅Π³ΠΈΡ ΡΠ±ΠΎΡΠΊΠΈ ΠΌΡΡΠΎΡΠ°
, gc_grace_seconds -- ΠΡΠ΅ΠΌΡ ΠΆΠΈΠ·Π½ΠΈ ΠΌΡΡΠΎΡΠ°
, ...
from system.schema_columnfamilies
where keyspace_name = 'HR'
Kwa hifadhidata zingine nyingi, unaweza pia kuja na maswali sawa (hata Mongo anayo
Bila shaka, kwa njia hii unaweza kupata taarifa si tu kuhusu meza, lakini kuhusu kitu chochote kwa ujumla. Mara kwa mara, watu wema hushiriki msimbo kama huo kwa hifadhidata tofauti, kama, kwa mfano, katika safu ya vifungu vya habra "Kazi za kuweka kumbukumbu za hifadhidata za PostgreSQL" (
Kama matokeo, njia hii ya kuvinjari na kutafuta vitu ni rahisi zaidi, huokoa muda mwingi, na hukuruhusu kupata habari haswa katika fomu ambayo inahitajika sasa (kama, kwa mfano, ilivyoelezewa kwenye chapisho.
Operesheni na vitu
Baada ya kupata na kusoma vitu muhimu, ni wakati wa kufanya kitu muhimu nao. Kwa kawaida, pia bila kuchukua vidole vyako kwenye kibodi.
Sio siri kuwa kufuta tu jedwali kutaonekana sawa katika hifadhidata zote:
drop table hr.persons
Lakini kwa kuundwa kwa meza inakuwa ya kuvutia zaidi. Takriban DBMS yoyote (pamoja na NoSQL nyingi) inaweza "kuunda meza" kwa namna moja au nyingine, na sehemu yake kuu itatofautiana kidogo (jina, orodha ya safu, aina za data), lakini maelezo mengine yanaweza kutofautiana kwa kiasi kikubwa na hutegemea. kifaa cha ndani na uwezo wa DBMS maalum. Mfano wangu ninaoupenda zaidi ni kwamba katika hati za Oracle kuna BNF "uchi" tu za syntax ya "unda jedwali".
Pia, DBMS nyingi zina aina zao maalum za vitu ambazo hazipatikani katika DBMS zingine. Kwa kuongezea, tunaweza kufanya shughuli sio tu kwenye vitu vya hifadhidata, lakini pia kwenye DBMS yenyewe, kwa mfano, "kuua" mchakato, fungua eneo fulani la kumbukumbu, wezesha ufuatiliaji, ubadilishe kwa hali ya "kusoma tu", na mengi zaidi.
Sasa hebu tuchore kidogo
Moja ya kazi za kawaida ni kujenga mchoro na vitu vya database na kuona vitu na uhusiano kati yao katika picha nzuri. Takriban IDE yoyote ya picha, huduma tofauti za "mstari wa amri", zana maalum za picha na viundaji vinaweza kufanya hivi. Watakuchorea kitu "kadiri wawezavyo," na unaweza kuathiri mchakato huu kidogo tu kwa usaidizi wa vigezo vichache kwenye faili ya usanidi au visanduku vya kuteua kwenye kiolesura.
Lakini tatizo hili linaweza kutatuliwa rahisi zaidi, rahisi zaidi na kifahari, na bila shaka kwa msaada wa kanuni. Ili kuunda michoro ya ugumu wowote, tunayo lugha kadhaa maalum za alama (DOT, GraphML n.k), ββna kwao utawanyiko mzima wa programu (GraphViz, PlantUML, Mermaid) ambazo zinaweza kusoma maagizo kama haya na kuibua katika muundo tofauti. . Kweli, tayari tunajua jinsi ya kupata habari juu ya vitu na viunganisho kati yao.
Hapa kuna mfano mdogo wa jinsi hii inaweza kuonekana, kwa kutumia PlantUML na
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'
Na ukijaribu kidogo, basi kulingana na
Swala la SQL ni gumu zaidi
-- Π¨Π°ΠΏΠΊΠ°
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'
Ukiangalia kwa karibu, chini ya kofia zana nyingi za taswira pia hutumia maswali sawa. Kweli, maombi haya kwa kawaida ni ya kina
Vipimo na ufuatiliaji
Wacha tuendelee kwenye mada changamano ya jadi - ufuatiliaji wa utendaji wa hifadhidata. Nakumbuka hadithi ndogo ya kweli iliyosimuliwa kwangu na "mmoja wa marafiki zangu." Katika mradi mwingine kulikuwa na DBA fulani yenye nguvu, na wachache wa watengenezaji walimjua kibinafsi, au wamewahi kumuona ana kwa ana (licha ya ukweli kwamba, kulingana na uvumi, alifanya kazi mahali fulani katika jengo linalofuata). Saa ya "X", wakati mfumo wa utaftaji wa muuzaji mkubwa ulianza "kujisikia vibaya" tena, alituma kimya picha za skrini kutoka kwa Oracle Enterprise Manager, ambayo alionyesha kwa uangalifu maeneo muhimu na alama nyekundu ya "kueleweka" ( hii, kuiweka kwa upole, haikusaidia sana). Na kulingana na "kadi ya picha" hii nilipaswa kutibu. Wakati huo huo, hakuna mtu aliyekuwa na upatikanaji wa thamani (kwa maana zote mbili za neno) Meneja wa Biashara, kwa sababu mfumo ni mgumu na wa gharama kubwa, ghafla "watengenezaji hujikwaa juu ya kitu na kuvunja kila kitu." Kwa hivyo, watengenezaji "kwa nguvu" walipata eneo na sababu ya breki na wakatoa kiraka. Ikiwa barua ya kutisha kutoka kwa DBA haikufika tena katika siku za usoni, basi kila mtu angepumua na kurudi kwenye kazi zao za sasa (mpaka Barua mpya).
Lakini mchakato wa ufuatiliaji unaweza kuonekana kuwa wa kufurahisha zaidi na wa kirafiki, na muhimu zaidi, kupatikana na kwa uwazi kwa kila mtu. Angalau sehemu yake ya msingi, kama nyongeza ya mifumo kuu ya ufuatiliaji (ambayo kwa hakika ni muhimu na katika hali nyingi haiwezi kurejeshwa). DBMS yoyote ni bure na bila malipo kabisa kushiriki habari kuhusu hali na utendaji wake wa sasa. Katika Oracle DB ile ile ya βdamuβ, karibu taarifa yoyote kuhusu utendakazi inaweza kupatikana kutoka kwa mitazamo ya mfumo, kuanzia michakato na vipindi hadi hali ya akiba ya akiba (kwa mfano,
Kwa hivyo, ikiwa na aina fulani ya mkusanyaji wa vipimo (Telegraf, Metricbeat, Collectd) ambayo inaweza kutekeleza maswali maalum ya sql, uhifadhi wa metriki hizi (InfluxDB, Elasticsearch, Timescaledb) na taswira (Grafana, Kibana), unaweza kupata rahisi sana. na mfumo wa ufuatiliaji unaonyumbulika ambao utaunganishwa kwa karibu na vipimo vingine vya mfumo mzima (zinazopatikana, kwa mfano, kutoka kwa seva ya programu, kutoka kwa OS, nk). Kama, kwa mfano, hii inafanywa katika pgwatch2, ambayo hutumia mchanganyiko wa InfluxDB + Grafana na seti ya maswali kwa maoni ya mfumo, ambayo yanaweza pia kupatikana.
Katika jumla ya
Na hii ni orodha ya takriban ya kile kinachoweza kufanywa na hifadhidata yetu kwa kutumia msimbo wa kawaida wa SQL. Nina hakika unaweza kupata matumizi mengi zaidi, andika kwenye maoni. Na tutazungumza juu ya jinsi (na muhimu zaidi kwa nini) kubinafsisha haya yote na kuyajumuisha kwenye bomba lako la CI/CD wakati ujao.
Chanzo: mapenzi.com