
SQL, apa sing luwih gampang? Saben kita bisa nulis pitakon prasaja - kita ngetik pilih, kita dhaptar kolom perlu, banjur saka, jeneng tabel, sawetara kahanan ing ngendi lan iku - data migunani ing kanthong kita, lan (meh) preduli saka apa DBMS ing hood ing wektu (utawa Mungkin ). Akibaté, nggarap meh kabeh sumber data (relasional lan ora) bisa dianggep saka sudut pandang kode reguler (karo kabeh sing sabanjure - kontrol versi, review kode, analisis statis, autotes lan kabeh). Lan iki ora mung data dhewe, rencana lan migrasi, nanging umume kabeh urip panyimpenan. Ing artikel iki, kita bakal ngomong babagan tugas saben dina lan masalah nggarap macem-macem DB miturut gun "database minangka kode".
Lan ayo miwiti langsung saka . Perang pisanan saka jinis "SQL vs ORM" ditemokake maneh .
Pemetaan obyek-relasional
Panyengkuyung ORM sacara tradisional ngurmati kacepetan lan kesederhanaan pangembangan, kamardikan saka DBMS, lan kode sing resik. Kanggo akeh kita, kode kanggo nggarap DB (lan asring DB dhewe)
biasane katon kaya iki ...
@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 kasebut ditutupi anotasi sing cerdas, lan ing endi wae ing mburi, ORM sing gagah nggawe lan nglakokake pirang-pirang kode SQL. Miturut cara, pangembang nyoba sing paling apik kanggo pager saka DB kanthi kilometer abstraksi, sing ngomong babagan sawetara .
Ing sisih liya saka barricades, penganut murni "gawean tangan" SQL nyathet kemampuan kanggo remet kabeh jus metu saka DBMS sing tanpa lapisan tambahan lan abstraksi. Akibaté, proyèk "data-sentris" katon, ing ngendi basis data ditangani dening wong sing dilatih khusus (alias "basist", alias "basoviki", alias "basemenshchiki", lan liya-liyane), lan para pangembang mung kudu "narik" tampilan sing wis siap lan tata cara sing disimpen, tanpa nerangake rincian.
Apa yen sampeyan njupuk sing paling apik saka loro donya? Kaya sing ditindakake ing instrumen sing apik banget kanthi jeneng sing nguatake urip . Aku bakal menehi sawetara baris saka konsep umum ing terjemahan gratis, lan sampeyan bisa ngerti kanthi luwih rinci. .
Clojure minangka basa sing apik kanggo nggawe DSL, nanging SQL wis dadi DSL sing apik, lan kita ora butuh liyane. S-ekspresi gedhe, nanging ora nambah apa-apa anyar ing kene. We mungkasi karo kurung kanggo marga saka kurung. ora setuju? Banjur ngenteni nganti abstraksi database wiwit bocor lan sampeyan miwiti nglawan fungsi kasebut (raw-sql)
Dadi apa sing kudu ditindakake? Ayo ninggalake SQL minangka SQL biasa - siji file saben pitakon:
-- name: users-by-country
select *
from users
where country_code = :country_code...banjur waca file kasebut, ngowahi dadi fungsi Clojure biasa:
(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" ...} ...)Kanthi tetep ing prinsip "SQL apart, Clojure apart", sampeyan entuk:
- Ora ana kejutan sintaksis. Database sampeyan (kaya liyane) ora 100% tundhuk karo SQL - nanging Yesql ora peduli. Sampeyan ora bakal mbuwang wektu mburu fungsi kanthi sintaks sing padha karo SQL. Sampeyan ora bakal kudu bali menyang fungsi (raw-sql "sawetara ('funky'::SYNTAX)")).
- Dhukungan editor sing luwih apik. Editor sampeyan wis duwe dhukungan SQL sing apik. Kanthi nyimpen SQL minangka SQL, sampeyan mung bisa nggunakake.
- Kompatibilitas printah: DBA sampeyan bisa maca lan nulis SQL sing digunakake ing proyek Clojure.
- Tuning kinerja luwih gampang. Apa sampeyan kudu nggawe rencana kanggo pitakon masalah? Ora masalah yen pitakon sampeyan yaiku SQL biasa.
- Gunakake maneh Pitakonan: Seret lan selehake file SQL sing padha menyang proyek liyane amarga mung SQL lawas - mung nuduhake.
Ing mratelakake panemume, idea iki banget kelangan lan ing wektu sing padha banget prasaja, thanks kanggo kang project wis entuk akèh popularitas. ing macem-macem basa. Lan kita bakal nyoba ngetrapake filosofi sing padha kanggo misahake kode SQL saka kabeh liya sing ngluwihi ORM.
Manajer IDE & DB
Ayo dadi miwiti karo tugas saben dinten prasaja. Kita kerep kudu nggoleki sawetara obyek ing DB, contone, golek tabel ing skema lan sinau strukture (kolom, tombol, indeks, kendala, lan liya-liyane). Lan saka IDE grafis utawa manajer DB, pisanane, kita ngarepake kemampuan kasebut. Supaya cepet lan sampeyan ora kudu ngenteni setengah jam nganti jendhela karo informasi sing dibutuhake digambar (utamane karo sambungan alon menyang DB remot), lan ing wektu sing padha, supaya informasi sing ditampa seger lan cocog, lan ora cached barang lawas. Kajaba iku, luwih rumit lan luwih gedhe DB lan luwih akeh, luwih angel nindakake iki.
Nanging biasane aku mbuwang mouse adoh lan mung nulis kode. Ayo dadi ngomong sampeyan kudu ngerteni tabel (lan karo sifat apa) sing ana ing skema "HR". Ing umume DBMS, asil sing dikarepake bisa digayuh kanthi pitakon prasaja saka information_schema:
select table_name
, ...
from information_schema.tables
where schema = 'HR'Saka basis data menyang basis data, isi tabel referensi kasebut beda-beda gumantung saka kapabilitas saben DBMS. Lan, contone, kanggo MySQL, saka referensi sing padha sampeyan bisa entuk parameter tabel khusus kanggo DBMS iki:
select table_name
, storage_engine -- Используемый "движок" ("MyISAM", "InnoDB" etc)
, row_format -- Формат строки ("Fixed", "Dynamic" etc)
, ...
from information_schema.tables
where schema = 'HR'Oracle ora ngerti information_schema, nanging duwe , lan ora ana masalah gedhe:
select table_name
, pct_free -- Минимум свободного места в блоке данных (%)
, pct_used -- Минимум используемого места в блоке данных (%)
, last_analyzed -- Дата последнего сбора статистики
, ...
from all_tables
where owner = 'HR'ClickHouse ora kajaba:
select name
, engine -- Используемый "движок" ("MergeTree", "Dictionary" etc)
, ...
from system.tables
where database = 'HR'Bab sing padha bisa ditindakake ing Cassandra (ing ngendi ana kolom kulawarga tinimbang tabel lan spasi tombol tinimbang skema):
select columnfamily_name
, compaction_strategy_class -- Стратегия сборки мусора
, gc_grace_seconds -- Время жизни мусора
, ...
from system.schema_columnfamilies
where keyspace_name = 'HR'Kanggo umume database liyane, sampeyan uga bisa nggawe pitakon sing padha (malah Mongo duwe , sing ngemot informasi babagan kabeh koleksi ing sistem).
Mesthi, cara iki bisa digunakake kanggo njupuk informasi ora mung bab tabel, nanging bab sembarang obyek ing umum. Secara periodik, wong sing apikan nuduhake kode kasebut kanggo macem-macem DB, kayata ing seri artikel Habr "Fungsi kanggo ndokumentasi database PostgreSQL" (, , ). Mesthi, tetep kabeh gunung pitakonan iki ing sirah lan terus-terusan ngetik mau "ora dadi luwih" fun, supaya ing IDE favorit / editor aku duwe set sing wis disiapake saka snippets kanggo pitakonan sing kerep digunakake, lan kabeh sing isih kanggo ngetik jeneng obyek menyang cithakan.
Akibaté, cara pandhu arah lan telusuran obyek iki luwih fleksibel, ngirit wektu, ngidini sampeyan entuk persis informasi lan ing wangun sing sampeyan butuhake saiki (kayata, contone, diterangake ing kiriman kasebut. ).
Operasi karo obyek
Sawise kita nemokake lan sinau obyek sing dibutuhake, wektune kanggo nindakake perkara sing migunani. Alami, uga tanpa ngangkat driji saka keyboard.
Ora ana rahasia manawa mung mbusak tabel bakal katon padha ing meh kabeh database:
drop table hr.personsNanging kanthi nggawe meja wis luwih menarik. Meh kabeh DBMS (kalebu akeh NoSQL) ing salah siji wangun utawa liyane bisa "nggawe tabel", lan bagean utama ora malah beda-beda (jeneng, dhaftar kolom, jinis data), nanging rincian liyane bisa beda-beda dramatically lan gumantung ing struktur internal lan kapabilitas DBMS tartamtu. Conto favoritku - ing dokumentasi Oracle mung ana BNF "gundhul" kanggo sintaks "gawe tabel" . DBMS liyane nduweni kemampuan sing luwih andhap, nanging saben DBMS uga nduweni fitur sing menarik lan unik kanggo nggawe tabel (, , , ). Ora mungkin "Tuntunan" grafis saka IDE liyane (utamane sing universal) bakal bisa nutupi kabeh kemampuan kasebut, lan yen bisa, mula ora bakal katon kanggo wong sing semaput. Ing wektu sing padha, operator ditulis kanthi bener lan pas wektune nggawe tabel bakal ngidini sampeyan nggunakake kabeh kanthi gampang, nggawe panyimpenan lan akses menyang data bisa dipercaya, optimal lan nyaman.
Uga, akeh DBMS duwe jinis obyek tartamtu dhewe sing ora kasedhiya ing DBMS liyane. Menapa malih, kita bisa nindakake operasi ora mung ing obyek DB, nanging uga ing DBMS dhewe, contone, "mateni" proses, mbebasake sawetara area memori, ngaktifake nelusuri, ngalih menyang mode "mung maca", lan akeh liyane.
Saiki ayo nggambar sethithik
Salah sawijining tugas sing paling umum yaiku nggawe diagram karo obyek DB, kanggo ndeleng obyek lan sambungan ing antarane gambar sing apik. Meh kabeh IDE grafis, utilitas "baris perintah" sing kapisah, alat grafis khusus lan modeler bisa nindakake iki. Kang bakal tarik soko kanggo sampeyan "sing paling apik padha bisa", lan sampeyan mung bisa rada pengaruhe proses iki kanthi bantuan saka sawetara paramèter ing file konfigurasi utawa kothak ing antarmuka.
Nanging masalah iki bisa ditanggulangi luwih gampang, fleksibel lan elegan, lan mesthi kanthi bantuan kode. Kanggo nggawe diagram saka kerumitan apa wae, kita duwe sawetara basa markup khusus (DOT, GraphML, lsp.), lan kanggo wong-wong mau - kabeh panyebaran aplikasi (GraphViz, PlantUML, Mermaid), sing bisa maca instruksi kasebut lan nggambarake ing macem-macem format. Inggih, lan kita wis ngerti carane njaluk informasi bab obyek lan sambungan antarane wong-wong mau.
Iki minangka conto cepet babagan apa sing bisa ditindakake nggunakake PlantUML lan (ing sisih kiwa ana query SQL sing bakal ngasilake instruksi sing dibutuhake kanggo PlantUML, lan ing sisih tengen ana asil):

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'Lan yen sampeyan nyoba sethitik, banjur ing basis saka sampeyan bisa entuk sing meh padha karo diagram ER nyata:
Pitakonan SQL rada rumit
-- Шапка
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' 
Yen sampeyan ndeleng kanthi teliti, akeh alat visualisasi nggunakake pitakon sing padha ing sangisore hood. Nanging, pitakon kasebut biasane jero , ora kanggo sebutno modifikasi saka wong-wong mau.
Metrik lan ngawasi
Ayo pindhah menyang topik tradisional sing angel - DB performance monitoring . Ayo kula kelingan crita nyata cekak sing dicritakake "salah sawijining kancaku". Ing project liyane urip DBA kuat tartamtu, lan sawetara pangembang sumurup wong, utawa malah weruh ing mripat (senadyan kasunyatan sing makarya, miturut gosip, nang endi wae ing bangunan tetanggan). Ing jam "X", nalika sistem produksi saka pengecer gedhe maneh wiwit "rasa ala", meneng ngirim gambar saka Oracle Enterprise Manager, kang kasebut kanthi teliti, nyorot panggonan kritis karo tandha abang kanggo "pangerten" (iki, kanggo sijine iku mildly, ora bantuan akeh). Lan miturut "kertu foto" iki sing kudu diobati. Ing wektu sing padha, ora ana sing bisa ngakses Manajer Perusahaan sing larang regane (ing tembung loro), amarga sistem kasebut rumit lan larang, dumadakan "pangembang bakal kesandhung lan ngrusak kabeh". Mulane, para pangembang "secara empiris" nemokake panggonan lan alasan kanggo slowdowns lan ngeculake tembelan. Yen layang ancaman saka DBA ora teka maneh ing mangsa ngarep, kabeh wong ambegan lega lan bali menyang tugas saiki (nganti Surat sabanjure).
Nanging proses ngawasi bisa katon luwih nyenengake lan ramah, lan sing paling penting - bisa diakses lan transparan kanggo kabeh wong. Paling ora bagean dhasar, minangka tambahan kanggo sistem ngawasi utama (sing mesthi migunani lan ing akeh kasus irreplaceable). Sembarang DBMS gratis lan pancen gratis siap nuduhake informasi babagan kahanan lan kinerja saiki. Ing Oracle DB "getih" sing padha, meh kabeh informasi babagan kinerja bisa dipikolehi saka tampilan sistem, saka proses lan sesi menyang status cache buffer (contone, , bagean "Monitoring"). Postgresql uga duwe akeh tampilan sistem kanggo , ing tartamtu sing indispensable ing urip saben dina saka sembarang DBA, kayata , , . MySQL malah duwe skema kapisah kanggo tujuan iki. . Lan ing Mongo wis dibangun ing nglumpukake data kinerja menyang koleksi sistem .
Mangkono, bersenjata karo sawetara kolektor metrik (Telegraf, Metricbeat, Collectd), sing bisa nglakokake pitakon SQL khusus, panyimpenan metrik kasebut (InfluxDB, Elasticsearch, Timescaledb) lan visualizer (Grafana, Kibana), sampeyan bisa entuk sistem ngawasi sing cukup entheng lan fleksibel sing bakal diintegrasi kanthi rapet karo metrik aplikasi ing saindenging sistem (contone, saka metrik aplikasi sistem liyane, etc). Contone, iki ditindakake ing pgwatch2, sing nggunakake paket InfluxDB + Grafana lan sakumpulan pitakon menyang tampilan sistem, sing uga bisa .
Total
Lan iki mung dhaptar kira-kira apa sing bisa ditindakake karo DB nggunakake kode SQL biasa. Aku yakin sampeyan bisa nemokake luwih akeh aplikasi, tulis ing komentar. Lan kita bakal pirembagan bab carane (lan sing paling Jahwéh kok) kanggo ngotomatisasi kabeh iki lan kalebu ing CI / pipo CD sabanjuré.
Source: www.habr.com
