SQL, kio povus esti pli simpla? Ĉiu el ni povas skribi simplan peton - ni tajpas elektu, listigu la postulatajn kolumnojn, do el, tabelnomo, kelkaj kondiĉoj en kie kaj jen ĉio - utilaj datumoj estas en nia poŝo, kaj (preskaŭ) sendepende de kiu DBMS estas sub la kapuĉo tiutempe (aŭ eble
Kaj ni komencu ĝuste de
Objekt-rilata mapado
Subtenantoj de ORM tradicie taksas rapidecon kaj facilecon de evoluo, sendependecon de la DBMS kaj puran kodon. Por multaj el ni, la kodo por labori kun la datumbazo (kaj ofte la datumbazo mem)
ĝi kutime aspektas kiel ĉi tio...
@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;
}
...
La modelo estas pendigita kun saĝaj komentarioj, kaj ie malantaŭ la scenoj kuraĝa ORM generas kaj efektivigas tunojn da iu SQL-kodo. Cetere, programistoj klopodas por izoli sin de sia datumbazo per kilometroj da abstraktaĵoj, kio indikas iujn
Aliflanke de la barikadoj, adeptoj de pura "manfarita" SQL rimarkas la kapablon elpremi la tutan sukon el siaj DBMS sen pliaj tavoloj kaj abstraktaĵoj. Rezulte aperas projektoj "datumcentraj", kie en la datumbazo partoprenas speciale trejnitaj homoj (ili estas ankaŭ "bazikistoj", ili estas ankaŭ "bazistoj", ili ankaŭ estas "basdenistoj", ktp.), kaj la programistoj. nur devas "tiri" la pretajn vidojn kaj konservitajn procedurojn, sen eniri detalojn.
Kio se ni havus la plej bonan el ambaŭ mondoj? Kiel ĉi tio estas farita en mirinda ilo kun viv-aserta nomo
Clojure estas bonega lingvo por krei DSL-ojn, sed SQL mem estas bonega DSL, kaj ni ne bezonas alian. S-esprimoj estas bonegaj, sed ili aldonas nenion novan ĉi tie. Kiel rezulto, ni ricevas krampojn pro krampoj. Ĉu ne konsentas? Tiam atendu la momenton, kiam la abstraktado super la datumbazo komencas liki kaj vi komencas batali kun la funkcio (kruda-sql)
Kion do mi faru? Ni lasu SQL kiel ordinara SQL - unu dosieron per peto:
-- name: users-by-country
select *
from users
where country_code = :country_code
... kaj poste legu ĉi tiun dosieron, igante ĝin regula Clojure-funkcio:
(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" ...} ...)
Aliĝante al la principo "SQL per si mem, Clojure per si mem", vi ricevas:
- Neniuj sintaksaj surprizoj. Via datumbazo (kiel ĉiu alia) ne 100% konformas al la SQL-normo - sed tio ne gravas por Yesql. Vi neniam malŝparos tempon por ĉasi funkciojn kun SQL-ekvivalenta sintakso. Vi neniam devos reveni al funkcio (raw-sql "kelkaj('funky'::SINTAKSO)")).
- Plej bona redaktoro subteno. Via redaktilo jam havas bonegan SQL-subtenon. Konservante SQL kiel SQL vi povas simple uzi ĝin.
- Teama kongruo. Viaj DBA-oj povas legi kaj skribi la SQL kiun vi uzas en via Clojure-projekto.
- Pli facila agordado de rendimento. Ĉu vi bezonas konstrui planon por problema demando? Ĉi tio ne estas problemo kiam via demando estas regula SQL.
- Reuzado de demandoj. Trenu kaj faligi tiujn samajn SQL-dosierojn en aliajn projektojn ĉar ĝi estas simple malnova SQL - simple dividu ĝin.
Laŭ mi, la ideo estas tre mojosa kaj samtempe tre simpla, danke al kiu la projekto gajnis multajn
Administrantoj de IDE & DB
Ni komencu per simpla ĉiutaga tasko. Ofte ni devas serĉi kelkajn objektojn en la datumbazo, ekzemple, trovi tabelon en la skemo kaj studi ĝian strukturon (kiaj kolumnoj, ŝlosiloj, indeksoj, limoj ktp. estas uzataj). Kaj de iu ajn grafika IDE aŭ iom DB-administranto, antaŭ ĉio, ni atendas ĝuste ĉi tiujn kapablojn. Por ke ĝi estu rapida kaj vi ne devas atendi duonhoron ĝis desegnita fenestro kun la necesaj informoj (precipe kun malrapida konekto al fora datumbazo), kaj samtempe, la ricevita informo estas freŝa kaj trafa, kaj ne kaŝmemoritaj rubaĵoj. Krome, ju pli kompleksa kaj pli granda la datumbazo kaj ju pli granda estas la nombro da ili, des pli malfacilas fari ĉi tion.
Sed kutime mi forĵetas la muson kaj nur skribas kodon. Ni diru, ke vi devas ekscii, kiuj tabeloj (kaj kun kiuj propraĵoj) estas enhavitaj en la skemo "HR". En la plej multaj DBMSoj, la dezirata rezulto povas esti atingita per ĉi tiu simpla demando de information_schema:
select table_name
, ...
from information_schema.tables
where schema = 'HR'
De datumbazo al datumbazo, la enhavo de tiaj referencaj tabeloj varias depende de la kapabloj de ĉiu DBMS. Kaj, ekzemple, por MySQL, el la sama konsultlibro vi povas akiri tabelajn parametrojn specifajn por ĉi tiu DBMS:
select table_name
, storage_engine -- Используемый "движок" ("MyISAM", "InnoDB" etc)
, row_format -- Формат строки ("Fixed", "Dynamic" etc)
, ...
from information_schema.tables
where schema = 'HR'
Oracle ne konas informa_skemon, sed ĝi havas
select table_name
, pct_free -- Минимум свободного места в блоке данных (%)
, pct_used -- Минимум используемого места в блоке данных (%)
, last_analyzed -- Дата последнего сбора статистики
, ...
from all_tables
where owner = 'HR'
ClickHouse ne estas escepto:
select name
, engine -- Используемый "движок" ("MergeTree", "Dictionary" etc)
, ...
from system.tables
where database = 'HR'
Io simila povas esti farita en Kasandra (kiu havas kolonfamiliojn anstataŭ tabelojn kaj ŝlosilspacojn anstataŭ skemojn):
select columnfamily_name
, compaction_strategy_class -- Стратегия сборки мусора
, gc_grace_seconds -- Время жизни мусора
, ...
from system.schema_columnfamilies
where keyspace_name = 'HR'
Por plej multaj aliaj datumbazoj, vi ankaŭ povas elpensi similajn demandojn (eĉ Mongo havas
Kompreneble, tiamaniere oni povas ricevi informojn ne nur pri tabeloj, sed pri iu ajn objekto ĝenerale. De tempo al tempo, afablaj homoj dividas tian kodon por malsamaj datumbazoj, kiel, ekzemple, en la serio de habra artikoloj "Funkcioj por dokumentado de PostgreSQL-datumbazoj" (
Kiel rezulto, ĉi tiu metodo por navigi kaj serĉi objektojn estas multe pli fleksebla, ŝparas multan tempon kaj ebligas al vi akiri precize la informojn en la formo en kiu ĝi nun estas necesa (kiel, ekzemple, priskribite en la afiŝo).
Operacioj kun objektoj
Post kiam ni trovis kaj studis la necesajn objektojn, estas tempo fari ion utilan kun ili. Kompreneble, ankaŭ sen depreni viajn fingrojn de la klavaro.
Ne estas sekreto, ke simple forigo de tabelo aspektos same en preskaŭ ĉiuj datumbazoj:
drop table hr.persons
Sed kun la kreado de la tablo ĝi fariĝas pli interesa. Preskaŭ ajna DBMS (inkluzive de multaj NoSQL) povas "krei tabelon" en unu formo aŭ alia, kaj la ĉefa parto de ĝi eĉ iomete malsamas (nomo, listo de kolumnoj, datumtipoj), sed aliaj detaloj povas diferenci draste kaj dependi de la interna aparato kaj kapabloj de specifa DBMS. Mia plej ŝatata ekzemplo estas, ke en la Oracle-dokumentado estas nur "nudaj" BNF-oj por la sintakso "krei tabelon".
Ankaŭ, multaj DBMSoj havas siajn proprajn specifajn specojn de objektoj kiuj ne estas haveblaj en aliaj DBMSoj. Plie, ni povas fari operaciojn ne nur sur datumbazaj objektoj, sed ankaŭ sur la DBMS mem, ekzemple, "mortigi" procezon, liberigi iun memorareon, ebligi spuradon, ŝanĝi al "nurlega" reĝimo, kaj multe pli.
Nun ni desegnu iomete
Unu el la plej oftaj taskoj estas konstrui diagramon kun datumbazaj objektoj kaj vidi la objektojn kaj ligojn inter ili en bela bildo. Preskaŭ ajna grafika IDE, apartaj "komandliniaj" utilecoj, specialigitaj grafikaj iloj kaj modelistoj povas fari tion. Ili desegnos ion por vi "kiel eble plej bone", kaj vi povas iomete influi ĉi tiun procezon nur helpe de kelkaj parametroj en la agorda dosiero aŭ markobutonoj en la interfaco.
Sed ĉi tiu problemo povas esti solvita multe pli simple, pli fleksebla kaj eleganta, kaj kompreneble helpe de kodo. Por krei diagramojn de ajna komplekseco, ni havas plurajn specialajn marklingvojn (DOT, GraphML ktp), kaj por ili tutan disvastigon da aplikaĵoj (GraphViz, PlantUML, Mermaid), kiuj povas legi tiajn instrukciojn kaj bildigi ilin en diversaj formatoj. . Nu, ni jam scias kiel akiri informojn pri objektoj kaj ligoj inter ili.
Jen malgranda ekzemplo de kiel tio povus aspekti, uzante PlantUML kaj
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'
Kaj se vi provas iomete, tiam bazita sur
La SQL-demando estas iom pli komplika
-- Шапка
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'
Se vi rigardas atente, sub la kapuĉo multaj bildigaj iloj ankaŭ uzas similajn demandojn. Vere, ĉi tiuj petoj estas kutime profunde
Metriko kaj monitorado
Ni transiru al tradicie kompleksa temo - datumbaza agado-monitorado. Mi memoras malgrandan veran historion rakontitan al mi de "unu el miaj amikoj". En alia projekto vivis certa potenca DBA, kaj malmultaj el la programistoj konis lin persone, aŭ iam vidis lin persone (malgraŭ ke, laŭ onidiroj, li laboris ie en la sekva konstruaĵo). Je la horo "X", kiam la sistemo de produktado de granda komercisto komencis "senti malbone" denove, li silente sendis ekrankopiojn de grafikaĵoj de Oracle Enterprise Manager, sur kiuj li zorge reliefigis kritikajn lokojn per ruĝa signo por "komprenebleco" ( ĉi tio, por paroli milde, ne multe helpis). Kaj surbaze de ĉi tiu "fotokarto" mi devis trakti. Samtempe neniu havis aliron al la altvalora (en ambaŭ sencoj de la vorto) Enterprise Manager, ĉar la sistemo estas kompleksa kaj multekosta, subite "la programistoj stumblas pri io kaj rompas ĉion." Tial, la programistoj "empirie" trovis la lokon kaj kaŭzon de la bremsoj kaj liberigis diakilon. Se la minaca letero de la DBA ne alvenus denove en proksima estonteco, tiam ĉiuj spirus trankvile kaj revenus al siaj nunaj taskoj (ĝis la nova Letero).
Sed la kontrola procezo povas aspekti pli amuza kaj amika, kaj plej grave, alirebla kaj travidebla por ĉiuj. Almenaŭ ĝia baza parto, kiel aldono al la ĉefaj monitoraj sistemoj (kiuj certe estas utilaj kaj en multaj kazoj neanstataŭeblaj). Ajna DBMS estas libere kaj absolute senpaga por kunhavi informojn pri sia nuna stato kaj agado. En la sama "sanga" Oracle DB, preskaŭ ajna informo pri rendimento povas esti akirita de sistemaj vidoj, intervalante de procezoj kaj sesioj ĝis la stato de la bufrokaŝmemoro (ekzemple,
Tiel, armita per ia mezurikolektilo (Telegraf, Metricbeat, Collectd), kiu povas plenumi kutimajn sql-demandojn, stokadon de ĉi tiuj metrikoj (InfluxDB, Elasticsearch, Timescaledb) kaj vidigilon (Grafana, Kibana), vi povas akiri sufiĉe facilan. kaj fleksebla monitoradsistemo kiu estos proksime integrita kun aliaj tutsistemaj metrikoj (akirita, ekzemple, de la aplikaĵoservilo, de la OS, ktp.). Kiel, ekzemple, tio estas farita en pgwatch2, kiu uzas la kombinaĵon InfluxDB + Grafana kaj aron da demandoj al sistemaj vidoj, kiuj ankaŭ alireblas.
Tuta
Kaj ĉi tio estas nur proksimuma listo de tio, kion oni povas fari per nia datumbazo per regula SQL-kodo. Mi certas, ke vi povas trovi multajn pliajn uzojn, skribu en la komentoj. Kaj ni parolos pri kiel (kaj plej grave kial) aŭtomatigi ĉion ĉi kaj inkluzivi ĝin en vian CI/KD-dukton venontfoje.
fonto: www.habr.com