Ezmûna "Daneyên wekî Kodê".

Ezmûna "Daneyên wekî Kodê".

SQL, çi dikare hêsantir be? Her yek ji me dikare daxwazek hêsan binivîse - em binivîsin neqandin, stûnên pêwîst navnîş bikin, paşê ji, navê tabloyê, hin şert û merc tê de ko û ew hemî ye - daneyên bikêr di berîka me de ne, û (hema hema) bêyî ku di wê demê de kîjan DBMS di bin kavilê de ye (an dibe ku qet ne DBMS e). Wekî encamek, xebata bi hema hema her çavkaniyek daneyê (têkilî û ne wusa) dikare ji hêla koda asayî ve were hesibandin (bi her tiştê ku tê wê wateyê - kontrolkirina guhertoyê, vekolîna kodê, analîzên statîk, ceribandinên otomatîkî, û ew hemî). Û ev ne tenê ji bo daneyan bixwe, nexşe û koçberan, lê bi gelemperî ji bo tevahiya jiyana hilanînê derbas dibe. Di vê gotarê de em ê li ser kar û pirsgirêkên rojane yên xebatê bi databasên cihêreng di bin lensên "danûstandin wekî kod" de biaxivin.

Û em rast ji dest pê bikin ORM. Şerên yekem ên celebê "SQL vs ORM" paşde hatin dîtin pêş-Petrine Rus'.

Nexşeya objekt-têkilî

Alîgirên ORM bi kevneşopî leza û hêsaniya pêşkeftinê, serxwebûna ji DBMS û koda paqij nirx dikin. Ji bo gelek ji me, koda xebata bi databasê re (û pir caran databas bixwe)

bi gelemperî tiştek wusa xuya dike ...

@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 bi annotasyonên biaqil ve hatî daliqandin, û li cîhek li pişt perdê ORMek wêrek bi tonan hin kodên SQL çêdike û dimeşîne. Bi awayê, pêşdebiran bi çi awayî hewl didin ku xwe ji databasa xwe bi kîlometran abstractions veqetînin, ku hin nîşan dide "SQL nefret".

Li aliyê din ê barîkatan, alîgirên SQL-ya safî ya "destçêkirî" balê dikişînin ser kapasîteya ku hemî ava DBMS-ya xwe bêyî qat û abstraksyonên zêde derxînin. Wekî encamek, projeyên "dane-navendî" xuya dibin, ku mirovên bi taybetî perwerdekirî beşdarî databasê dibin (ew jî "bingehparêz in", ew jî "bingehparêz" in, ew jî "bingehparêz in", hwd.), û pêşdebiran tenê pêdivî ye ku meriv nerînên amade û prosedurên hilanîn "bikişîne", bêyî ku bikeve nav hûrguliyan.

Ger em ji her du cîhanan çêtirîn hebin? Çawa ev di nav amûrek ecêb de bi navek jiyanê-erêker tê kirin Yesql. Ez ê di wergera xweya belaş de çend rêzan ji têgeha giştî bidim, û hûn dikarin bi hûrgulî pê re nas bikin vir.

Clojure ji bo afirandina DSL-yan zimanek xweş e, lê SQL bi xwe DSLyek xweş e, û hewcedariya me bi yek din tune. Daxuyanên S-ê mezin in, lê ew li vir tiştek nû zêde nakin. Di encamê de, em ji bo xatirê kelûpelan kelek digirin. Naxwazin? Dûv re li benda wê gavê bisekinin ku abstraction li ser databasê dest pê dike û hûn bi fonksiyonê re şer dikin (raw-sql)

Îcar divê ez çi bikim? Ka em SQL wekî SQL-ya birêkûpêk bihêlin - her daxwazek pelek:

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

... û paşê vê pelê bixwînin, wê veguherînin fonksiyonek Clojure ya birêkûpêk:

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

Bi pabendbûna bi prensîba "SQL bi xwe, Clojure bi xwe" re, hûn distînin:

  • No surprîzên syntaktîk. Databasa we (wek din) 100% bi standarda SQL re ne lihevhatî ye - lê ev ji bo Yesql ne girîng e. Hûn ê çu carî wextê xwe winda nekin nêçîra fonksiyonên bi hevoksaziya hevwateya SQL. Hûn ê çu carî ne hewce ne ku vegerin fonksiyonek (raw-sql "hinek ('funky':: SYNTAX)")).
  • Piştgiriya edîtorê çêtirîn. Edîtorê we jixwe piştgiriyek hêja ya SQL heye. Bi tomarkirina SQL wekî SQL hûn dikarin bi hêsanî wê bikar bînin.
  • Lihevhatina Tîm. DBA-yên we dikarin SQL-ya ku hûn di projeya xweya Clojure de bikar tînin bixwînin û binivîsin.
  • Sazkirina performansa hêsantir. Pêdivî ye ku ji bo pirsek pirsgirêkek plansaziyek çêbikin? Dema ku pirsa we SQL birêkûpêk be ev ne pirsgirêk e.
  • Ji nû ve bikaranîna pirsan. Heman pelên SQL kaş bikin û bavêjin nav projeyên din ji ber ku ew tenê SQL-ya kevnar e - tenê wê parve bikin.

Bi dîtina min, raman pir xweş û di heman demê de pir sade ye, bi saya vê projeyê gelek bi dest xistiye şopînerên bi gelek zimanan. Û em ê paşê hewl bidin ku felsefeyek wekhev a veqetandina koda SQL ji her tiştê ku ji ORM-ê wêdetir bicîh bikin.

Rêveberên IDE & DB

Ka em bi karekî rojane ya hêsan dest pê bikin. Pir caran divê em li hin tiştan di databasê de bigerin, mînakî, di şemayê de tabloyek bibînin û strukturê wê bikolin (çi stûn, kilît, index, asteng, hwd. têne bikar anîn). Û ji her IDE-ya grafîkî an rêveberek DB-ya piçûk, berî her tiştî, em tam van hêzan hêvî dikin. Ji bo ku ew bilez be û hûn ne hewce ne ku nîv saetê li bendê bimînin heya ku pencereyek bi agahdariya pêwîst were kişandin (nemaze bi girêdanek hêdî bi databasek dûr re), û di heman demê de agahdariya ku hatî wergirtin nû û têkildar e, û nexwarinên cached. Wekî din, databas çiqas tevlihev û mezin û hejmara wan mezintir be, kirina vê yekê ew qas dijwartir e.

Lê bi gelemperî ez mişkê diavêjim û tenê kodê dinivîsim. Ka em bibêjin ku hûn hewce ne ku fêr bibin ka kîjan tablo (û bi kîjan taybetmendiyan) di şemaya "HR" de hene. Di piraniya DBMS-an de, encama xwestinê dikare bi vê pirsê hêsan a ji information_schema were bidestxistin:

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

Ji databasê heya databasê, naveroka van tabloyên referansê li gorî kapasîteyên her DBMS-ê diguhere. Mînakî, ji bo MySQL, ji heman pirtûka referansê hûn dikarin pîvanên tabloyê yên taybetî yên vê DBMS-ê bistînin:

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

Oracle agahdariya_schema nizane, lê ew heye metadata Oracle, û pirsgirêkên mezin dernakeve:

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

ClickHouse ne îstîsna ye:

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

Tiştek wusa dikare li Cassandra were kirin (ku li şûna tabloyan malbatên stûnan û li şûna şemayan cîhên keys hene):

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

Ji bo piraniya databasên din, hûn dikarin pirsên weha jî derxînin (tewra Mongo jî heye berhevkirina pergala taybetî, ku di derheqê hemî berhevokên pergalê de agahdarî vedihewîne).

Bê guman, bi vî rengî hûn dikarin ne tenê li ser tabloyan, lê bi gelemperî li ser her tiştî agahdarî bistînin. Dem bi dem, mirovên dilovan kodên weha ji bo databasên cihêreng parve dikin, wek nimûne, di rêze gotarên habra de "Fonksiyon ji bo belgekirina databasên PostgreSQL" (Ayb, Ben, gym). Bê guman, girtina vî çiyayê pirsan di serê min de û bi domdarî nivîsandina wan pir kêfek e, ji ber vê yekê di IDE/edîtorê min ê bijare de ji bo pirsên ku pir caran têne bikar anîn komek hûrguliyên pêş-amadekirî hene, û ya ku dimîne ev e ku ez binivîsim. navên tiştan di nav şablonê de.

Wekî encamek, ev rêbaza gerîdok û lêgerîna li tiştan pir maqûltir e, pir dem xilas dike, û dihêle hûn tam agahdariya di forma ku nuha hewce ye (wek mînak, di postê de hatî diyar kirin) bistînin. "Daneyên ji databasê bi her formê hinardekirin: IDE dikarin li ser platforma IntelliJ çi bikin").

Operasyonên bi tiştên

Piştî ku me tiştên pêwîst dîtin û lêkolîn kirin, dem e ku em bi wan re tiştek kêrhatî bikin. Bi xwezayî, di heman demê de bêyî ku tiliyên xwe ji klavyeyê bavêjin.

Ne veşartî ye ku bi tenê jêbirina tabloyek hema hema di hemî databasan de heman xuya dike:

drop table hr.persons

Lê bi çêkirina tabloyê re balkêştir dibe. Hema hema her DBMS (tevî gelek NoSQL) dikare bi rengekî an yekî din "tabloyê biafirîne", û beşa wê ya sereke jî dê hinekî cûda bibe (nav, navnîşa stûnan, celebên daneyê), lê hûrguliyên din dikarin bi rengek berbiçav cûda bibin û bi ve girêdayî be. cîhaza navxweyî û kapasîteyên DBMS-ya taybetî. Mînaka min a bijare ev e ku di belgeya Oracle de tenê BNF-yên "tazî" ji bo hevoksaziya "tabloya çêbikin" hene. 31 rûpel digire. DBMS-yên din xwedan kapasîteyên nermtir in, lê her yek ji wan ji bo çêkirina tabloyan jî gelek taybetmendiyên balkêş û bêhempa hene (postgres, mysql, sisirk, cassandra). Ne mimkûn e ku "sêrbaz"ek grafîkî ji IDE-ya din (nemaze yekî gerdûnî) karibe van hemî hêzan bi tevahî veşêre, û heke bikaribe jî, ew ê ji dilpak re nebe dîmenek. Di heman demê de, daxuyaniyeke nivîskî ya rast û di cih de tablo çêbikin dê bihêle ku hûn hemî wan bi hêsanî bikar bînin, hilanîn û gihîştina daneyên xwe pêbawer, çêtirîn û bi qasî ku pêkan rehet bikin.

Di heman demê de, gelek DBMS celebên xwe yên taybetî hene ku di DBMS-yên din de tune ne. Wekî din, em dikarin ne tenê li ser tiştên databasê, lê di heman demê de li ser DBMS bixwe jî operasyonan bikin, mînakî, pêvajoyek "bikujin", hin devera bîranînê azad bikin, şopandinê çalak bikin, veguherînin moda "tenê xwendinê", û hêj bêtir.

Niha em hinekî xêz bikin

Yek ji peywirên herî gelemperî ev e ku meriv bi hêmanên databasê re diagramek ava bike û di wêneyek xweşik de tiştan û girêdanên di navbera wan de bibîne. Hema hema her IDE-ya grafîkî, karûbarên "xêza fermanê" yên veqetandî, amûrên grafîkî yên pispor û modelker dikarin vê bikin. Ew ê tiştek ji we re "çawa ku ew dikarin çêtirîn" xêz bikin, û hûn dikarin tenê bi alîkariya çend parametreyên di pelê veavakirinê de an qutiyên kontrolê yên di navberê de hinekî bandorê li vê pêvajoyê bikin.

Lê ev pirsgirêk pir sadetir, maqûltir û xweştir û bê guman bi alîkariya kodê dikare were çareser kirin. Ji bo afirandina diagramên her tevlihevî, me çend zimanên nîşankirinê yên pispor hene (DOT, GraphML, hwd.), û ji bo wan tevaya serîlêdanan (GraphViz, PlantUML, Mermaid) hene ku dikarin rêwerzên weha bixwînin û wan di cûrbecûr formatan de xuyang bikin. . Welê, em jixwe dizanin ka meriv çawa di derheqê tiştan û girêdanên di navbera wan de agahdarî digire.

Li vir mînakek piçûk e ku ev dikare çawa xuya bike, bi karanîna PlantUML û databasa demo ji bo PostgreSQL (li milê çepê pirsek SQL heye ku dê ji bo PlantUML talîmata pêwîst çêbike, û li milê rastê jî encam heye):

Ezmûna "Daneyên wekî Kodê".

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'

Û heke hûn hinekî biceribînin, wê hingê li ser bingeha şablonê ER ji bo PlantUML hûn dikarin tiştek pir dişibin diagramek ER ya rastîn bistînin:

Pirsa SQL hinekî tevlihevtir e

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

Ezmûna "Daneyên wekî Kodê".

Ger hûn ji nêz ve lê mêze bikin, di binê kapê de gelek amûrên dîtbariyê jî pirsên wekhev bikar tînin. Rast e, ev daxwaz bi gelemperî kûr in "Hardwire" di koda serîlêdanê bixwe de ye û têgihîştina dijwar e, ne ku behsa ti guhertina wan bikin.

Metrics û çavdêrîkirina

Ka em biçin ser mijarek kevneşopî ya tevlihev - çavdêriya performansa databasê. Çîrokek rastîn a piçûk tê bîra min ku "yek ji hevalên min" ji min re got. Li ser projeyek din DBA-ya hin hêzdar dijiya, û hindik ji pêşdebiran ew bi xwe nas dikirin, an jî qet ew bi xwe dîtibûn (tevî ku, li gorî gotegotan, ew li cîhek li avahiya din dixebitî). Di demjimêra "X" de, dema ku pergala hilberandinê ya firoşgehek mezin careke din dest bi "xirabbûnê" kir, wî bi bêdengî dîmenên grafîkan ji Rêvebirê Oracle Enterprise re şand, ku li ser wan bi baldarî cîhên krîtîk bi nîşanek sor ji bo "fêmkirinê" ronî kir ( ev, bi hûrgulî, pir alîkarî nekir). Û li ser bingeha vê "karta wêneyê" ez neçar bûm ku derman bikim. Di heman demê de, tu kesî xwe negihand Gerînendeyê Karsaziya hêja (di her du wateyên peyvê de), ji ber ku pergal tevlihev û biha ye, ji nişka ve "pêşdebir li tiştekî diqelişe û her tiştî dişkîne." Ji ber vê yekê, pêşdebiran bi "empirîkî" cîh û sedema şikestinan dîtin û pişkek berdan. Ger nameya metirsîdar a DBA di demek nêzîk de careke din nehatiba, wê demê dê her kes bêhna xwe hilde û vegere ser karên xwe yên niha (heta Nameya nû).

Lê pêvajoya çavdêriyê dikare ji bo her kesî xweştir û dostanetir xuya bike, û ya herî girîng, gihîştî û zelal. Bi kêmanî beşa wê ya bingehîn, wekî pêvekek pergalên çavdêriyê yên sereke (yên ku bê guman bikêr in û di pir rewşan de neguhezbar in). Her DBMS bi serbestî û bêkêmasî belaş e ku agahdariya li ser rewş û performansa xwe ya heyî parve bike. Di heman Oracle DB-ya "xwîndar" de, hema hema her agahdarî di derbarê performansê de dikare ji dîtinên pergalê, ji pêvajo û danişînan bigire heya rewşa cacheya tampon (mînak, Skrîptên DBA, beşa "Şopandin"). Postgresql di heman demê de komek nêrînên pergalê jî heye çavdêriya databasê, bi taybetî yên ku di jiyana rojane ya her DBA-ê de neçar in, wek mînak pg_stat_activity, pg_stat_base, pg_stat_bgwriter. MySQL tewra ji bo vê yekê şemayek veqetandî heye. performance_schema. A In Mongo ava-li profiler daneyên performansê di berhevokek pergalê de berhev dike system.profile.

Bi vî rengî, çekdar bi cûreyek berhevkarê metrîkan (Telegraf, Metricbeat, Collectd) ku dikare pirsên sql yên xwerû, hilanîna van metrikan (InfluxDB, Elasticsearch, Timescaledb) û dîmenderek (Grafana, Kibana) pêk bîne, hûn dikarin pir hêsan peyda bikin. û pergalek çavdêriya maqûl a ku dê ji nêz ve bi metrîkên din ên berfireh ên pergalê re were yek kirin (mînak, ji servera serîlêdanê, ji OS-ê, hwd. tête wergirtin). Mînakî, ev di pgwatch2 de tê kirin, ku têkeliya InfluxDB + Grafana û komek pirsiyar ji bo dîtinên pergalê bikar tîne, ku ew jî dikarin werin gihîştin. pirsên xwerû lê zêde bike.

Tevahî

Û ev tenê navnîşek texmînî ya tiştê ku dikare bi databasa me re bi karanîna koda SQL-ya birêkûpêk were kirin e. Ez bawer im ku hûn dikarin gelek karanîna din bibînin, di şîroveyan de binivîsin. Û em ê li ser çawa biaxivin (û ya herî girîng çima) ku hûn van hemîyan otomatîk bikin û carek din wê di lûleya CI/CD-ya xwe de bicîh bikin.

Source: www.habr.com

Ji bo malperên bi parastina DDoS, serverên VPS VDS mêvandariya pêbawer bikirin 🔥 Hostinga malperê ya pêbawer bi parastina DDoS, serverên VPS VDS bikirin | ProHoster