Eksperyans "Baz done kòm Kòd".

Eksperyans "Baz done kòm Kòd".

SQL, ki sa ki ka pi senp? Chak nan nou ka ekri yon demann senp - nou tape chwazi, lis kolòn obligatwa yo, lè sa a soti nan, non tab, kèk kondisyon nan ki kote ak sa a tout - done itil nan pòch nou an, ak (prèske) kèlkeswa sa DBMS ki anba kapo a nan moman sa a (oswa petèt pa yon DBMS ditou). Kòm yon rezilta, travay ak prèske nenpòt sous done (relasyonèl ak pa konsa) ka konsidere nan pwen de vi nan kòd òdinè (ak tout sa li implique - kontwòl vèsyon, revizyon kòd, analiz estatik, tès oto, ak sa a tout). Ak sa a aplike pa sèlman nan done yo tèt li, chema ak migrasyon, men an jeneral nan tout lavi a nan depo a. Nan atik sa a nou pral pale sou travay chak jou ak pwoblèm nan travay ak baz done divès kalite anba lantiy la nan "baz done kòm kòd".

Epi ann kòmanse dwat nan ORM. Premye batay yo nan kalite "SQL vs ORM" yo te remake tounen nan pre-Petrine Rus'.

Kat objè-relasyonèl

Sipòtè ORM yo tradisyonèlman apresye vitès ak fasilite devlopman, endepandans nan DBMS ak kòd pwòp. Pou anpil nan nou, kòd pou travay ak baz done a (e souvan baz done a li menm)

anjeneral li sanble yon bagay tankou sa a ...

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

Modèl la pandye ak anotasyon entelijan, ak yon kote dèyè sèn nan yon ORM vanyan jenere ak egzekite tòn kèk kòd SQL. By wout la, devlopè yo ap eseye pi byen yo izole tèt yo nan baz done yo ak kilomèt nan abstraksyon, ki endike kèk "SQL rayi".

Sou lòt bò a nan barikad yo, aderan pi bon kalite "handmade" SQL note kapasite nan peze tout ji a soti nan DBMS yo san yo pa kouch adisyonèl ak abstraksyon. Kòm yon rezilta, pwojè "data-centric" parèt, kote moun ki resevwa fòmasyon espesyal yo patisipe nan baz done a (yo se tou "bazisist", yo tou "bazisist", yo tou "basdeners", elatriye), ak devlopè yo. sèlman gen nan "rale" yo pare-fè opinyon yo ak pwosedi ki estoke, san yo pa antre nan detay.

E si nou te gen pi bon nan tou de mond yo? Ki jan sa fèt nan yon zouti bèl bagay ak yon non ki afime lavi Yesql. Mwen pral bay yon koup nan liy ki soti nan konsèp jeneral la nan tradiksyon gratis mwen an, epi ou ka fè konesans ak li an plis detay. isit la.

Clojure se yon lang fre pou kreye DSL, men SQL li menm se yon DSL fre, epi nou pa bezwen yon lòt. Ekspresyon S yo gwo, men yo pa ajoute anyen nouvo isit la. Kòm yon rezilta, nou jwenn parantèz pou dedomajman pou parantèz. pa dakò? Lè sa a, tann pou moman sa a lè abstraksyon sou baz done a kòmanse koule epi ou kòmanse goumen ak fonksyon an (kri-sql)

Se konsa, kisa mwen ta dwe fè? Ann kite SQL kòm SQL regilye - yon dosye pou chak demann:

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

... ak Lè sa a, li dosye sa a, vire l 'nan yon fonksyon Clojure regilye:

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

Lè w respekte prensip "SQL pou kont li, Clojure poukont li", ou jwenn:

  • Pa gen sipriz sentaktik. Baz done ou a (tankou nenpòt lòt) pa 100% konfòme ak estanda SQL - men sa a pa enpòtan pou Yesql. Ou p'ap janm pèdi tan lachas pou fonksyon ak sentaks ekivalan SQL. Ou pap janm oblije retounen nan yon fonksyon (raw-sql "kèk('funky'::SENTAKS)")).
  • Pi bon sipò editè. Editè ou a deja gen ekselan sipò SQL. Lè w sove SQL kòm SQL ou ka tou senpleman itilize li.
  • Ekip konpatibilite. DBA ou yo ka li ak ekri SQL ou itilize nan pwojè Clojure ou a.
  • Akor pèfòmans pi fasil. Bezwen bati yon plan pou yon rechèch pwoblèm? Sa a se pa yon pwoblèm lè rechèch ou an se SQL regilye.
  • Réutilisation requêtes. Trennen epi lage menm fichye SQL sa yo nan lòt pwojè paske se jis SQL fin vye granmoun - jis pataje li.

Dapre mwen, lide a trè fre ak an menm tan trè senp, gras a ki pwojè a te genyen anpil disip yo nan yon varyete lang. Epi nou pral pwochen eseye aplike yon filozofi ki sanble nan separe kòd SQL soti nan tout lòt bagay byen lwen pi lwen pase ORM la.

Manadjè IDE & DB

Ann kòmanse ak yon senp travay chak jou. Souvan nou gen pou chèche kèk objè nan baz done a, pou egzanp, jwenn yon tab nan chema a epi etidye estrikti li (ki kolòn, kle, endèks, kontrent, elatriye yo itilize). Ak nan nenpòt ki IDE grafik oswa yon ti kras DB-manadjè, premye a tout moun, nou espere egzakteman kapasite sa yo. Se konsa, ke li rapid epi ou pa bezwen tann yon demi èdtan jiskaske yon fenèt ki gen enfòmasyon ki nesesè yo trase (sitou ak yon koneksyon dousman nan yon baz done aleka), epi an menm tan an, enfòmasyon yo resevwa se fre ak enpòtan, epi yo pa kachèt tenten. Anplis, pi konplèks ak pi gwo baz done a ak pi gwo kantite yo, pi difisil la li se fè sa.

Men, anjeneral mwen jete sourit la epi jis ekri kòd. Ann di ou bezwen chèche konnen ki tab (ak ki pwopriyete) yo genyen nan chema "HR" la. Nan pifò DBMS yo, rezilta yo vle a ka reyalize ak rechèch senp sa a soti nan information_schema:

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

Soti nan baz done a baz done, sa ki nan tab referans sa yo varye selon kapasite yo nan chak DBMS. Epi, pou egzanp, pou MySQL, nan menm liv referans ou ka jwenn paramèt tab espesifik pou DBMS sa a:

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

Oracle pa konnen information_schema, men li genyen Metadata Oracle, epi pa gen gwo pwoblèm leve:

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

ClickHouse pa gen okenn eksepsyon:

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

Yon bagay ki sanble ka fè nan Cassandra (ki gen columnfamilies olye pou yo tab ak espas kle olye pou yo chema):

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

Pou pifò lòt baz done, ou kapab tou vini ak demann menm jan an (menm Mongo genyen koleksyon sistèm espesyal, ki gen enfòmasyon sou tout koleksyon nan sistèm nan).

Natirèlman, nan fason sa a ou ka jwenn enfòmasyon pa sèlman sou tab, men sou nenpòt objè an jeneral. De tan zan tan, moun ki janti pataje kòd sa yo pou baz done diferan, tankou, pou egzanp, nan seri atik habra "Fonksyon pou dokimante baz done PostgreSQL" (Ayb, Ben, jimnastik). Natirèlman, kenbe tout mòn sa a nan demann nan tèt mwen ak toujou ap tape yo se yon plezi konsa, kidonk nan IDE / editè pi renmen mwen an mwen gen yon seri fragments prepare pou demann yo itilize souvan, ak tout sa ki rete se tape a. non objè nan modèl la.

Kòm yon rezilta, metòd sa a pou navige ak chèche objè se pi fleksib, ekonomize anpil tan, epi li pèmèt ou jwenn egzakteman enfòmasyon an nan fòm ki kounye a li nesesè (tankou, pou egzanp, ki dekri nan pòs la. "Ekspòtasyon done ki sòti nan yon baz done nan nenpòt fòma: kisa IDE yo ka fè sou platfòm IntelliJ la").

Operasyon ak objè yo

Apre nou te jwenn ak etidye objè ki nesesè yo, li lè yo fè yon bagay itil ak yo. Natirèlman, tou san yo pa retire dwèt ou sou klavye a.

Li pa sekrè ke tou senpleman efase yon tab pral sanble menm bagay la nan prèske tout baz done:

drop table hr.persons

Men, ak kreyasyon tab la li vin pi enteresan. Prèske nenpòt DBMS (ki gen ladan anpil NoSQL) ka "kreye tab" nan yon fòm oswa yon lòt, ak pati prensipal la nan li pral menm diferan yon ti kras (non, lis kolòn, kalite done), men lòt detay yo ka diferan dramatikman epi depann de la. aparèy entèn ak kapasite yon DBMS espesifik. Egzanp pi renmen mwen an se ke nan dokiman Oracle la gen sèlman BNF "toutouni" pou sentaks "kreye tab". okipe 31 paj. Lòt DBMS yo gen plis kapasite modès, men chak nan yo tou gen anpil karakteristik enteresan ak inik pou kreye tab (postgres, miskl, ravèt, kasandra). Li fasil pou nenpòt ki "sòsye" grafik ki soti nan yon lòt IDE (espesyalman yon sèl inivèsèl) yo pral kapab konplètman kouvri tout kapasite sa yo, e menm si li kapab, li pa pral yon spektak pou moun ki endispoze nan kè. An menm tan an, yon deklarasyon ekri kòrèkteman ak alè kreye tab la pral pèmèt ou fasilman sèvi ak tout nan yo, fè depo ak aksè a done ou serye, optimal ak konfòtab ke posib.

Epitou, anpil DBMS yo gen pwòp kalite objè espesifik yo ki pa disponib nan lòt DBMS yo. Anplis, nou ka fè operasyon pa sèlman sou objè baz done, men tou sou DBMS nan tèt li, pou egzanp, "touye" yon pwosesis, libere kèk zòn memwa, pèmèt trase, chanje nan "li sèlman" mòd, ak plis ankò.

Koulye a, ann desine yon ti kras

Youn nan travay ki pi komen yo se bati yon dyagram ak objè baz done epi wè objè yo ak koneksyon ant yo nan yon foto bèl. Prèske nenpòt IDE grafik, sèvis piblik separe "liy kòmand", zouti grafik espesyalize ak modèl ka fè sa. Yo pral trase yon bagay pou ou "tankou pi bon yo kapab," epi ou ka enfliyanse pwosesis sa a yon ti kras sèlman avèk èd nan kèk paramèt nan dosye a konfigirasyon oswa kaz nan koòdone nan.

Men, pwoblèm sa a ka rezoud pi senp, pi fleksib ak elegant, ak nan kou avèk èd nan kòd. Pou kreye dyagram nan nenpòt ki konpleksite, nou gen plizyè lang espesyalize maketing (DOT, GraphML elatriye), ak pou yo yon gaye tout aplikasyon (GraphViz, PlantUML, Mermaid) ki ka li enstriksyon sa yo ak vizyalize yo nan yon varyete fòma. . Oke, nou deja konnen ki jan yo jwenn enfòmasyon sou objè ak koneksyon ant yo.

Isit la nan yon ti egzanp sou sa sa a ta ka sanble, lè l sèvi avèk PlantUML ak baz done Demo pou PostgreSQL (sou bò gòch la se yon rechèch SQL ki pral jenere enstriksyon ki nesesè pou PlantUML, ak sou bò dwat la se rezilta a):

Eksperyans "Baz done kòm Kòd".

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'

Men, si ou eseye yon ti kras, Lè sa a, ki baze sou Modèl ER pou PlantUML ou ka jwenn yon bagay ki sanble anpil ak yon dyagram ER reyèl:

Rekèt la SQL se yon ti kras pi konplike

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

Eksperyans "Baz done kòm Kòd".

Si ou gade ak anpil atansyon, anba kapo a anpil zouti vizyalizasyon tou itilize demann menm jan an. Se vre, demann sa yo anjeneral pwofondman "Fire" nan kòd aplikasyon an li menm epi yo difisil pou konprann, nou pa mansyone nenpòt modifikasyon nan yo.

Metrik ak siveyans

Ann ale nan yon sijè tradisyonèlman konplèks - siveyans pèfòmans baz done. Mwen sonje yon ti istwa vrè “yonn nan zanmi m yo” te rakonte m. Sou yon lòt pwojè te viv yon sèten DBA pwisan, ak kèk nan devlopè yo te konnen l 'pèsonèlman, oswa te janm wè l' nan moun (malgre lefèt ke, dapre rimè, li te travay yon kote nan pwochen bilding lan). Nan èdtan "X", lè sistèm pwodiksyon an nan yon gwo revandè te kòmanse "santi move" yon lòt fwa ankò, li an silans voye Ekran nan graf ki soti nan Oracle Enterprise Manager, kote li ak anpil atansyon make kote kritik ak yon makè wouj pou "konpreyansib" ( sa a, pou mete l 'dous, pa t' ede anpil). E ki baze sou "kat foto" sa a mwen te oblije trete. An menm tan an, pesonn pa te gen aksè a presye (nan tou de sans mo a) Enterprise Manager, paske sistèm nan se konplèks ak chè, toudenkou "devlopè yo bite sou yon bagay epi kraze tout bagay." Se poutèt sa, devlopè yo "anpirikman" te jwenn kote ak kòz fren yo ak lage yon patch. Si lèt menasan DBA a pa t rive ankò nan fiti prè, lè sa a tout moun ta soufle yon souf epi retounen nan travay aktyèl yo (jiskaske nouvo Lèt la).

Men, pwosesis siveyans la ka gade pi amizan ak zanmitay, ak pi enpòtan, aksesib ak transparan pou tout moun. Omwen pati debaz li yo, kòm yon adisyon nan sistèm siveyans prensipal yo (ki se sètènman itil ak nan anpil ka iranplasabl). Nenpòt DBMS se gratis epi absoliman gratis pou pataje enfòmasyon sou eta aktyèl li ak pèfòmans. Nan menm "san" Oracle DB a, prèske nenpòt enfòmasyon sou pèfòmans yo ka jwenn nan opinyon sistèm, sòti nan pwosesis ak sesyon ak eta a nan kachèt tanpon (pa egzanp, Scripts DBA, seksyon "Siveyans"). Postgresql tou gen yon pakèt antye nan opinyon sistèm pou siveyans baz done, an patikilye sa yo ki endispansab nan lavi a chak jou nan nenpòt DBA, tankou pg_stat_aktivite, pg_stat_database, pg_stat_bgwriter. MySQL menm gen yon chema separe pou sa. pèfòmans_schema. A Nan Mongo bati-an profiler rasanble done pèfòmans nan yon koleksyon sistèm system.profile.

Kidonk, ame ak kèk kalite pèseptè metrik (Telegraf, Metricbeat, Collectd) ki ka fè demann sql koutim, yon depo nan metrik sa yo (InfluxDB, Elasticsearch, Timescaledb) ak yon visualizer (Grafana, Kibana), ou ka jwenn yon jistis fasil. ak yon sistèm siveyans fleksib ki pral byen entegre ak lòt mezi sistèm nan laj (jwenn, pou egzanp, nan sèvè aplikasyon an, nan OS la, elatriye). Kòm, pou egzanp, sa a se fè nan pgwatch2, ki itilize konbinezon InfluxDB + Grafana ak yon seri demann nan opinyon sistèm, ki ka jwenn aksè tou. ajoute demann koutim.

Nan total

Ak sa a se sèlman yon lis apwoksimatif nan sa ki ka fè ak baz done nou an lè l sèvi avèk regilye kòd SQL. Mwen sèten ou ka jwenn anpil lòt itilizasyon, ekri nan kòmantè yo. Epi nou pral pale sou ki jan (ak pi enpòtan an poukisa) otomatize tout bagay sa yo epi mete li nan tiyo CI/CD ou pwochen fwa.

Sous: www.habr.com

Achte hosting serye pou sit ki gen pwoteksyon DDoS, sèvè VPS VDS 🔥 Achte yon hébergement sit entènèt serye ak pwoteksyon DDoS, sèvè VPS VDS | ProHoster