"Database bi koodu" Iriri

"Database bi koodu" Iriri

SQL, kini o le rọrun? Olukuluku wa le kọ ibeere ti o rọrun - a tẹ yan, ṣe atokọ awọn ọwọn ti a beere, lẹhinna lati, tabili orukọ, diẹ ninu awọn ipo ni ibi ti ati pe iyẹn ni gbogbo rẹ - data to wulo wa ninu apo wa, ati (fere) laibikita eyiti DBMS wa labẹ iho ni akoko yẹn (tabi boya kii ṣe DBMS rara). Bi abajade, ṣiṣẹ pẹlu fere eyikeyi orisun data (ibasepo ati kii ṣe bẹ) ni a le gbero lati oju wiwo ti koodu lasan (pẹlu gbogbo eyiti o tumọ si - iṣakoso ẹya, atunyẹwo koodu, itupalẹ aimi, awọn adaṣe, ati pe gbogbo rẹ ni). Ati pe eyi kii ṣe nikan si data funrararẹ, awọn eto ati awọn iṣipopada, ṣugbọn ni gbogbogbo si gbogbo igbesi aye ibi ipamọ naa. Ninu nkan yii a yoo sọrọ nipa awọn iṣẹ ṣiṣe lojoojumọ ati awọn iṣoro ti ṣiṣẹ pẹlu ọpọlọpọ awọn apoti isura infomesonu labẹ lẹnsi ti “database bi koodu”.

Ki o si jẹ ki ká bẹrẹ ọtun lati ORM. Awọn ogun akọkọ ti iru “SQL vs ORM” ni a ṣe akiyesi pada sinu Pre-Petrine Rus.

Nkan-ibaraṣe aworan agbaye

Awọn alatilẹyin ORM ni aṣa ṣe idiyele iyara ati irọrun ti idagbasoke, ominira lati DBMS ati koodu mimọ. Fun ọpọlọpọ wa, koodu fun ṣiṣẹ pẹlu ibi ipamọ data (ati nigbagbogbo data data funrararẹ)

Nigbagbogbo o dabi iru eyi ...

@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;
    }
  ...

Awoṣe naa ti kọkọ pẹlu awọn asọye onilàkaye, ati ni ibikan lẹhin awọn iṣẹlẹ ti ORM akikanju kan n ṣe ipilẹṣẹ ati ṣiṣe awọn toonu ti diẹ ninu koodu SQL. Nipa ọna, awọn olupilẹṣẹ n gbiyanju gbogbo wọn lati ya ara wọn sọtọ kuro ni ibi ipamọ data wọn pẹlu awọn ibuso ti awọn abstractions, eyiti o tọka diẹ ninu "SQL ikorira".

Ni apa keji ti awọn idena, awọn alamọ ti SQL mimọ “ti a fi ọwọ ṣe” ṣe akiyesi agbara lati fun pọ gbogbo oje kuro ninu DBMS wọn laisi awọn ipele afikun ati awọn abstractions. Bi abajade, awọn iṣẹ akanṣe “centric data” han, nibiti awọn eniyan ti o ni ikẹkọ pataki ti kopa ninu ibi ipamọ data (wọn tun jẹ “awọn ipilẹ”, wọn tun jẹ “awọn ipilẹ”, wọn tun jẹ “basdeners”, ati bẹbẹ lọ), ati awọn olupilẹṣẹ. nikan ni lati "fa" awọn wiwo ti a ti ṣetan ati awọn ilana ti a fipamọ, laisi lilọ sinu awọn alaye.

Kini ti a ba ni ohun ti o dara julọ ti awọn agbaye mejeeji? Bawo ni a ṣe ṣe eyi ni irinṣẹ iyanu pẹlu orukọ ti o ni idaniloju aye Bẹẹniql. Emi yoo fun awọn laini meji lati imọran gbogbogbo ni itumọ ọfẹ mi, ati pe o le ni oye pẹlu rẹ ni awọn alaye diẹ sii nibi.

Clojure jẹ ede ti o tutu fun ṣiṣẹda DSL, ṣugbọn SQL funrararẹ jẹ DSL tutu, ati pe a ko nilo ọkan miiran. S-ikosile jẹ nla, sugbon ti won ko fi ohunkohun titun nibi. Bi abajade, a gba awọn biraketi nitori awọn biraketi. Ko gba? Lẹhinna duro fun akoko ti abstraction lori data data bẹrẹ lati jo ati pe o bẹrẹ ija pẹlu iṣẹ naa (aise-sql)

Nitorina kini o yẹ ki n ṣe? Jẹ ki a fi SQL silẹ bi SQL deede - faili kan fun ibeere:

-- name: users-by-country
select *
  from users
 where country_code = :country_code

ati lẹhinna ka faili yii, yiyi pada si iṣẹ Clojure deede:

(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" ...} ...)

Nipa titẹmọ si “SQL funrararẹ, Clojure funrararẹ” ilana, o gba:

  • Ko si awọn iyanilẹnu syntactic. Ipamọ data rẹ (bii eyikeyi miiran) ko ni ibamu 100% pẹlu boṣewa SQL - ṣugbọn eyi ko ṣe pataki fun Yesql. Iwọ kii yoo padanu akoko ṣiṣe ode fun awọn iṣẹ pẹlu sintasi deede SQL. Iwọ kii yoo ni lati pada si iṣẹ kan (aise-sql "diẹ ninu awọn ('funky':: SYNTAX)")).
  • Atilẹyin olootu ti o dara julọ. Olootu rẹ ti ni atilẹyin SQL ti o dara julọ tẹlẹ. Nipa fifipamọ SQL bi SQL o le jiroro lo.
  • Ibamu ẹgbẹ. Awọn DBA rẹ le ka ati kọ SQL ti o lo ninu iṣẹ akanṣe Clojure rẹ.
  • Atunse iṣẹ ti o rọrun. Ṣe o nilo lati kọ ero kan fun ibeere iṣoro kan? Eyi kii ṣe iṣoro nigbati ibeere rẹ jẹ SQL deede.
  • Atunlo awọn ibeere. Fa ati ju silẹ awọn faili SQL kanna sinu awọn iṣẹ akanṣe nitori pe o kan SQL atijọ ti o rọrun - kan pin.

Ni ero mi, ero naa jẹ itura pupọ ati ni akoko kanna rọrun pupọ, o ṣeun si eyi ti iṣẹ naa ti ni ọpọlọpọ omoleyin ni orisirisi awọn ede. Ati pe a yoo gbiyanju nigbamii lati lo iru imoye ti o jọra ti yiya sọtọ koodu SQL lati ohun gbogbo miiran ti o jinna ju ORM lọ.

IDE & DB alakoso

Jẹ ká bẹrẹ pẹlu kan ti o rọrun lojojumo-ṣiṣe. Nigbagbogbo a ni lati wa diẹ ninu awọn ohun kan ninu ibi ipamọ data, fun apẹẹrẹ, wa tabili kan ninu eto naa ki o ṣe iwadi eto rẹ (kini awọn ọwọn, awọn bọtini, awọn atọka, awọn ihamọ, ati bẹbẹ lọ ti a lo). Ati lati eyikeyi ayaworan IDE tabi kekere kan DB-faili, akọkọ ti gbogbo, a reti gangan wọnyi agbara. Ki o yara ati pe o ko ni lati duro fun idaji wakati kan titi ti window pẹlu alaye pataki yoo fa (paapaa pẹlu asopọ ti o lọra si ibi ipamọ data latọna jijin), ati ni akoko kanna, alaye ti o gba jẹ alabapade ati ti o yẹ, ati ki o ko cached ijekuje. Jubẹlọ, awọn diẹ eka ati ki o tobi awọn database ati awọn ti o tobi awọn nọmba ti wọn, awọn diẹ soro o ni lati ṣe eyi.

Sugbon maa Mo jabọ awọn Asin kuro ati ki o kan kọ koodu. Jẹ ki a sọ pe o nilo lati wa iru awọn tabili (ati pẹlu awọn ohun-ini) ti o wa ninu ero “HR”. Ni ọpọlọpọ awọn DBMS, abajade ti o fẹ le ṣee ṣe pẹlu ibeere ti o rọrun yii lati alaye_schema:

select table_name
     , ...
  from information_schema.tables
 where schema = 'HR'

Lati ibi ipamọ data si ibi ipamọ data, awọn akoonu ti iru awọn tabili itọkasi yatọ da lori awọn agbara ti DBMS kọọkan. Ati, fun apẹẹrẹ, fun MySQL, lati iwe itọkasi kanna o le gba awọn paramita tabili ni pato si DBMS yii:

select table_name
     , storage_engine -- Используемый "движок" ("MyISAM", "InnoDB" etc)
     , row_format     -- Формат строки ("Fixed", "Dynamic" etc)
     , ...
  from information_schema.tables
 where schema = 'HR'

Oracle ko mọ alaye_schema, ṣugbọn o ni Oracle metadataKo si awọn iṣoro nla ti o dide:

select table_name
     , pct_free       -- Минимум свободного места в блоке данных (%)
     , pct_used       -- Минимум используемого места в блоке данных (%)
     , last_analyzed  -- Дата последнего сбора статистики
     , ...
  from all_tables
 where owner = 'HR'

ClickHouse kii ṣe iyatọ:

select name
     , engine -- Используемый "движок" ("MergeTree", "Dictionary" etc)
     , ...
  from system.tables
 where database = 'HR'

Nkankan ti o jọra le ṣee ṣe ni Cassandra (eyiti o ni awọn idile ọwọn dipo awọn tabili ati awọn aaye bọtini dipo awọn eto):

select columnfamily_name
     , compaction_strategy_class  -- Стратегия сборки мусора
     , gc_grace_seconds           -- Время жизни мусора
     , ...
  from system.schema_columnfamilies
 where keyspace_name = 'HR'

Fun ọpọlọpọ awọn data data miiran, o tun le wa pẹlu awọn ibeere ti o jọra (paapaa Mongo ni pataki gbigba eto, eyi ti o ni alaye nipa gbogbo awọn akojọpọ ninu eto).

Nitoribẹẹ, ni ọna yii o le gba alaye kii ṣe nipa awọn tabili nikan, ṣugbọn nipa eyikeyi nkan ni gbogbogbo. Lati igba de igba, awọn eniyan oninuure pin iru koodu fun oriṣiriṣi awọn apoti isura infomesonu, gẹgẹbi, fun apẹẹrẹ, ninu jara ti awọn nkan habra “Awọn iṣẹ ṣiṣe fun kikọ awọn apoti isura data PostgreSQL” (Ayb, Ben, idaraya). Nitoribẹẹ, fifi gbogbo oke ibeere yii si ori mi ati titẹ nigbagbogbo jẹ iru igbadun bẹ, nitorinaa ninu IDE / olootu ayanfẹ mi Mo ni awọn snippets ti a ti pese tẹlẹ fun awọn ibeere ti a lo nigbagbogbo, ati pe gbogbo ohun ti o ku ni lati tẹ ohun awọn orukọ sinu awọn awoṣe.

Bi abajade, ọna yii ti lilọ kiri ati wiwa awọn nkan jẹ irọrun diẹ sii, fi akoko pupọ pamọ, ati gba ọ laaye lati gba alaye gangan ni fọọmu eyiti o jẹ dandan (bii, fun apẹẹrẹ, ti ṣalaye ninu ifiweranṣẹ. "Firanṣẹ okeere data lati ibi ipamọ data ni eyikeyi ọna kika: kini awọn IDE le ṣe lori ipilẹ IntelliJ").

Awọn iṣẹ pẹlu awọn nkan

Lẹhin ti a ti rii ati iwadi awọn nkan pataki, o to akoko lati ṣe nkan ti o wulo pẹlu wọn. Nipa ti, paapaa laisi gbigbe awọn ika ọwọ rẹ kuro ni keyboard.

Kii ṣe aṣiri pe piparẹ tabili kan nirọrun yoo dabi kanna ni gbogbo awọn apoti isura data:

drop table hr.persons

Ṣugbọn pẹlu awọn ẹda ti tabili o di diẹ awon. Fere eyikeyi DBMS (pẹlu ọpọlọpọ NoSQL) le “ṣẹda tabili” ni fọọmu kan tabi omiiran, ati apakan akọkọ rẹ yoo paapaa yatọ si diẹ (orukọ, atokọ ti awọn ọwọn, awọn oriṣi data), ṣugbọn awọn alaye miiran le yatọ ni iyalẹnu ati dale lori ti abẹnu ẹrọ ati awọn agbara ti kan pato DBMS. Apẹẹrẹ ayanfẹ mi ni pe ninu iwe Oracle awọn BNF “ihoho” nikan wa fun sintasi “ṣẹda tabili” gba 31 ojúewé. Awọn DBMS miiran ni awọn agbara iwọntunwọnsi diẹ sii, ṣugbọn ọkọọkan wọn tun ni ọpọlọpọ awọn ẹya ti o nifẹ ati alailẹgbẹ fun ṣiṣẹda awọn tabili (awọn ifiweranṣẹ, MySQL, àkùkọ, cassandra). Ko ṣee ṣe pe “oluṣeto” ayaworan eyikeyi lati IDE miiran (paapaa gbogbo agbaye) yoo ni anfani lati bo gbogbo awọn agbara wọnyi ni kikun, ati paapaa ti o ba le, kii yoo jẹ iwoye fun alãrẹ ọkan. Ni akoko kanna, alaye kikọ ti o tọ ati akoko ṣẹda tabili yoo gba ọ laaye lati lo gbogbo wọn ni irọrun, ṣe ibi ipamọ ati iraye si data rẹ ni igbẹkẹle, ti aipe ati itunu bi o ti ṣee.

Paapaa, ọpọlọpọ awọn DBMS ni awọn iru ohun kan pato tiwọn ti ko si ni awọn DBMS miiran. Pẹlupẹlu, a le ṣe awọn iṣẹ kii ṣe lori awọn nkan data nikan, ṣugbọn tun lori DBMS funrararẹ, fun apẹẹrẹ, “pa” ilana kan, laaye diẹ ninu agbegbe iranti, mu wiwa kakiri, yipada si ipo “ka nikan” ati pupọ diẹ sii.

Bayi jẹ ki a ya kekere kan

Ọkan ninu awọn iṣẹ-ṣiṣe ti o wọpọ julọ ni lati kọ aworan kan pẹlu awọn ohun elo data ati ki o wo awọn nkan ati awọn asopọ laarin wọn ni aworan ti o dara. Fere eyikeyi IDE ayaworan, awọn ohun elo “laini aṣẹ” lọtọ, awọn irinṣẹ ayaworan amọja ati awọn apẹẹrẹ le ṣe eyi. Wọn yoo fa ohun kan fun ọ “bi o ṣe dara julọ ti wọn le,” ati pe o le ni ipa lori ilana yii diẹ nikan pẹlu iranlọwọ ti awọn paramita diẹ ninu faili iṣeto tabi awọn apoti ayẹwo ni wiwo.

Ṣugbọn iṣoro yii ni a le yanju ni irọrun pupọ, irọrun diẹ sii ati yangan, ati dajudaju pẹlu iranlọwọ ti koodu. Lati ṣẹda awọn aworan atọka ti eyikeyi idiju, a ni ọpọlọpọ awọn ede isamisi amọja (DOT, GraphML ati bẹbẹ lọ), ati fun wọn gbogbo tuka awọn ohun elo (GraphViz, PlantUML, Mermaid) ti o le ka iru awọn itọnisọna ati wo wọn ni ọpọlọpọ awọn ọna kika. . O dara, a ti mọ tẹlẹ bi a ṣe le gba alaye nipa awọn nkan ati awọn asopọ laarin wọn.

Eyi ni apẹẹrẹ kekere ti kini eyi le dabi, lilo PlantUML ati demo database fun PostgreSQL (ni apa osi jẹ ibeere SQL kan ti yoo ṣe agbekalẹ itọnisọna ti a beere fun PlantUML, ati ni apa ọtun ni abajade):

"Database bi koodu" Iriri

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'

Ati pe ti o ba gbiyanju diẹ, lẹhinna da lori ER awoṣe fun PlantUML o le gba nkan ti o jọra si aworan ER gidi kan:

Ibeere SQL jẹ idiju diẹ diẹ sii

-- Шапка
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'

"Database bi koodu" Iriri

Ti o ba wo ni pẹkipẹki, labẹ iho ọpọlọpọ awọn irinṣẹ iworan tun lo awọn ibeere ti o jọra. Lootọ, awọn ibeere wọnyi jẹ igbagbogbo jinna “hardwired” sinu koodu ohun elo funrararẹ ati pe o nira lati ni oye, ko si darukọ eyikeyi iyipada ti wọn.

Metiriki ati monitoring

Jẹ ki a lọ si koko-ọrọ eka ti aṣa - data iṣẹ ibojuwo . Mo ranti itan otitọ kekere kan ti “ọkan ninu awọn ọrẹ mi” sọ fun mi. Lori iṣẹ akanṣe miiran ti o ngbe DBA ti o lagbara kan, ati pe diẹ ninu awọn olupilẹṣẹ ti mọ ọ tikalararẹ, tabi ti ri i ni eniyan (biotilẹjẹpe otitọ pe, ni ibamu si awọn agbasọ ọrọ, o ṣiṣẹ ni ibikan ni ile atẹle). Ni wakati “X”, nigbati eto agbejade ti alagbata nla kan bẹrẹ si “rilara buburu” lẹẹkan si, o fi ipalọlọ ranṣẹ awọn sikirinisoti ti awọn aworan lati ọdọ Oluṣakoso Idawọlẹ Oracle, lori eyiti o farabalẹ ṣe afihan awọn aaye to ṣe pataki pẹlu ami ami pupa fun “oye” ( eyi, lati fi sii ni irẹlẹ, ko ṣe iranlọwọ pupọ). Ati pe o da lori “kaadi fọto” yii Mo ni lati tọju. Ni akoko kanna, ko si ẹnikan ti o ni iwọle si iyebiye (ninu awọn ọna mejeeji ti ọrọ naa) Oluṣakoso Idawọlẹ, nitori Eto naa jẹ eka ati gbowolori, lojiji “awọn olupilẹṣẹ kọsẹ lori nkan kan wọn fọ ohun gbogbo.” Nitorinaa, awọn olupilẹṣẹ “ti o ni agbara” rii ipo ati idi ti awọn idaduro ati tu alemo kan silẹ. Ti lẹta ikọlu lati ọdọ DBA ko ba tun de ni ọjọ iwaju to sunmọ, lẹhinna gbogbo eniyan yoo simi kan ti iderun ati pada si awọn iṣẹ ṣiṣe lọwọlọwọ wọn (titi di Lẹta tuntun).

Ṣugbọn ilana ibojuwo le wo igbadun diẹ sii ati ore, ati pataki julọ, wiwọle ati sihin fun gbogbo eniyan. O kere ju apakan ipilẹ rẹ, bi afikun si awọn eto ibojuwo akọkọ (eyiti o wulo dajudaju ati ni ọpọlọpọ awọn ọran ko ṣee ṣe). Eyikeyi DBMS jẹ ọfẹ ati ọfẹ ọfẹ lati pin alaye nipa ipo lọwọlọwọ ati iṣẹ rẹ. Ninu Oracle DB “ẹjẹ” kanna, o fẹrẹ to eyikeyi alaye nipa iṣẹ ṣiṣe ni a le gba lati awọn iwo eto, ti o wa lati awọn ilana ati awọn akoko si ipo ti kaṣe ifipamọ (fun apẹẹrẹ, Awọn iwe afọwọkọ DBA, apakan "Abojuto"). Postgresql tun ni gbogbo opo ti awọn iwo eto fun database monitoring, ni pato awọn ti o ṣe pataki ni igbesi aye ojoojumọ ti eyikeyi DBA, gẹgẹbi pg_stat_akitiyan, pg_stat_database, pg_stat_bgwriter. MySQL paapaa ni ero lọtọ fun eyi. išẹ_schema. A Ni Mongo ti a ṣe sinu profaili ṣajọpọ data iṣẹ ṣiṣe sinu gbigba eto kan eto.profaili.

Nitorinaa, ni ihamọra pẹlu diẹ ninu awọn agbowọpọ awọn metiriki (Telegraf, Metricbeat, Ti a gba) ti o le ṣe awọn ibeere sql aṣa, ibi ipamọ ti awọn metiriki wọnyi (InfluxDB, Elasticsearch, Timescaledb) ati wiwo wiwo (Grafana, Kibana), o le gba irọrun ti o rọrun. ati eto ibojuwo to rọ ti yoo ṣepọ ni pẹkipẹki pẹlu awọn metiriki jakejado eto (ti o gba, fun apẹẹrẹ, lati olupin ohun elo, lati OS, ati bẹbẹ lọ). Bi, fun apẹẹrẹ, eyi ni a ṣe ni pgwatch2, eyiti o nlo InfluxDB + Grafana apapo ati ṣeto awọn ibeere si awọn iwo eto, eyiti o tun le wọle si fi aṣa ibeere.

Lapapọ

Ati pe eyi jẹ atokọ isunmọ ti ohun ti o le ṣee ṣe pẹlu data data wa nipa lilo koodu SQL deede. Mo ni idaniloju pe o le rii ọpọlọpọ awọn lilo diẹ sii, kọ sinu awọn asọye. Ati pe a yoo sọrọ nipa bii (ati pataki julọ idi) lati ṣe adaṣe gbogbo eyi ki o fi sii ninu opo gigun ti epo CI/CD rẹ ni akoko atẹle.

orisun: www.habr.com

Fi ọrọìwòye kun