Таҷрибаи "Махзани маълумот ҳамчун код"

Таҷрибаи "Махзани маълумот ҳамчун код"

SQL, чӣ метавонад соддатар бошад? Ҳар яки мо метавонем дархости оддӣ нависед - мо менависем интихоб кунед, сутунҳои лозимиро номбар кунед, пас аз, номи ҷадвал, баъзе шартҳо дар ки дар ва ҳамааш ин аст - маълумоти муфид дар ҷайби мо ва (қариб) новобаста аз он ки дар он вақт кадом DBMS зери сарпӯш аст (ё шояд). умуман DBMS нест). Дар натиҷа, кор бо ҳама гуна манбаи додаҳо (релятсионӣ ва на он қадар) метавонад аз нуқтаи назари рамзи оддӣ баррасӣ карда шавад (бо ҳама чизҳое, ки он дар назар дорад - назорати версия, баррасии код, таҳлили статикӣ, автотестҳо ва ҳамааш). Ва ин на танҳо ба худи маълумот, схемаҳо ва муҳоҷират, балки дар маҷмӯъ ба тамоми мӯҳлати нигоҳдорӣ дахл дорад. Дар ин мақола мо дар бораи вазифаҳои ҳаррӯза ва мушкилоти кор бо пойгоҳи додаҳои гуногун дар зери линзаи "базанаи додаҳо ҳамчун код" сӯҳбат хоҳем кард.

Ва биёед рост аз он оғоз кунем ORM. Аввалин набардҳои навъи "SQL vs ORM" дар бозгашт мушоҳида карда шуданд пеш аз Петрин Рус.

Харитасозии релятсионӣ ба объект

Тарафдорони ORM ба таври анъанавӣ суръат ва осонии рушд, мустақилият аз DBMS ва рамзи тозаро қадр мекунанд. Барои бисёре аз мо, рамзи кор бо пойгоҳи додаҳо (ва аксар вақт худи пойгоҳи додаҳо)

одатан чунин ба назар мерасад ...

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

Модел бо эзоҳҳои оқилона овезон карда шудааст ва дар ҷое паси парда як ORM далерона тоннаҳо коди SQL-ро тавлид ва иҷро мекунад. Дар омади гап, таҳиягарон кӯшиш мекунанд, ки худро аз пойгоҳи додаҳои худ бо километрҳои абстраксия ҷудо кунанд, ки ин нишон медиҳад, ки баъзе "Нафрат SQL".

Дар тарафи дигари баррикадаҳо, ҷонибдорони SQL-и холиси "дастсохт" қобилияти фишурдани тамоми шарбатро аз DBMS бидуни қабатҳои иловагӣ ва абстраксияҳо қайд мекунанд. Дар натиља лоињањои «дата-марказї» пайдо мешаванд, ки дар онњо ба базаи маълумот одамони махсус омўзонидашуда љалб карда мешаванд (онњо њам «асосист», онњо њам «базисист», њам «басденер» ва ѓайра) ва тањиягарон. бе тафсилот танҳо бояд намудҳои тайёр ва расмиёти ҳифзшударо “кашад”.

Чӣ мешавад, агар мо беҳтарини ҳарду ҷаҳонро дошта бошем? Чӣ тавр ин дар як асбоби аҷиб бо номи тасдиқкунандаи ҳаёт анҷом дода мешавад Yesql. Ман дар тарҷумаи ройгони худ аз мафҳуми умумӣ чанд сатр меорам ва шумо метавонед бо он муфассалтар шинос шавед дар ин ҷо.

Clojure як забони олӣ барои эҷоди DSLҳо аст, аммо худи SQL як DSL-и олӣ аст ва ба мо забони дигаре лозим нест. Ифодаи S бузург аст, аммо онҳо дар ин ҷо чизи нав илова намекунанд. Дар натиҷа, мо ба хотири қавс қавс ба даст меорем. розӣ нестед? Пас лаҳзаеро интизор шавед, ки абстраксия аз пойгоҳи додаҳо ба ихроҷ шурӯъ мекунад ва шумо бо функсия мубориза мебаред (raw-sql)

Пас, ман бояд чӣ кор кунам? Биёед SQL-ро ҳамчун SQL муқаррарӣ гузорем - як файл барои як дархост:

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

... ва он гоҳ ин файлро хонед ва онро ба функсияи муқаррарии Clojure табдил диҳед:

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

Бо риояи принсипи "SQL худ аз худ, Clojure худ аз худ", шумо ба даст меоред:

  • Ҳеҷ гуна тааҷҷубовар нест. Пойгоҳи шумо (мисли ҳама гуна дигар) 100% бо стандарти SQL мувофиқ нест - аммо ин барои Yesql муҳим нест. Шумо ҳеҷ гоҳ вақтро барои шикори функсияҳо бо синтаксиси муодили SQL сарф намекунед. Шумо ҳеҷ гоҳ набояд ба функсия баргардед (raw-sql "баъзе('funky'::SYNTAX)")).
  • Дастгирии беҳтарин муҳаррир. Муҳаррири шумо аллакай дастгирии аълои SQL дорад. Бо захира кардани SQL ҳамчун SQL шумо метавонед онро танҳо истифода баред.
  • Мутобиқати даста. DBA-ҳои шумо метавонанд SQL-ро, ки шумо дар лоиҳаи Clojure истифода мебаред, хонда ва нависад.
  • Танзими иҷрои осонтар. Оё шумо бояд нақшаи як дархости мушкилро таҳия кунед? Вақте ки дархости шумо SQL муқаррарӣ аст, ин мушкилот нест.
  • Истифодаи такрории дархостҳо. Он файлҳои SQL-ро ба лоиҳаҳои дигар кашед ва партоед, зеро он танҳо SQL-и оддии кӯҳна аст - танҳо онро мубодила кунед.

Ба андешаи ман, идея хеле аҷиб ва дар айни замон хеле содда аст, ки ба шарофати он лоиҳа бисёр чизҳоро ба даст овард пайравон бо забонҳои гуногун. Ва мо минбаъд кӯшиш хоҳем кард, ки фалсафаи шабеҳи ҷудо кардани коди SQL-ро аз ҳама чизҳои берун аз ORM истифода барем.

Менеҷерони IDE ва DB

Биёед бо як вазифаи оддии ҳаррӯза оғоз кунем. Аксар вақт ба мо лозим меояд, ки баъзе объектҳоро дар базаи маълумот ҷустуҷӯ кунем, масалан, ҷадвалро дар схема пайдо кунем ва сохтори онро омӯзем (кадом сутунҳо, калидҳо, индексҳо, маҳдудиятҳо ва ғайра истифода мешаванд). Ва аз ҳама гуна IDE графикӣ ё каме мудири DB, пеш аз ҳама, мо маҳз ин қобилиятҳоро интизорем. Барои он ки он зуд бошад ва ба шумо лозим нест, ки ним соат интизор шавед, то равзанаи дорои маълумоти зарурӣ (хусусан бо пайвасти суст ба пойгоҳи додаҳои дурдаст) ва ҳамзамон, маълумоти гирифташуда тоза ва мувофиқ бошад, ва партовҳои кэш нашудаанд. Гузашта аз ин, базаи маълумот ҳар қадар мураккабтар ва калонтар бошад ва шумораи онҳо зиёд бошад, иҷрои ин кор ҳамон қадар мушкилтар мешавад.

Аммо одатан ман мушро мепартоям ва танҳо код менависам. Фарз мекунем, ки шумо бояд бифаҳмед, ки кадом ҷадвалҳо (ва бо кадом хосиятҳо) дар схемаи "HR" мавҷуданд. Дар аксари DBMS, натиҷаи дилхоҳро бо ин дархости оддӣ аз information_schema ба даст овардан мумкин аст:

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

Аз махзани маълумот то махзани маълумот, мундариҷаи чунин ҷадвалҳои истинод вобаста ба имкониятҳои ҳар як DBMS фарқ мекунанд. Ва, масалан, барои MySQL, аз ҳамон як маълумотнома шумо метавонед параметрҳои ҷадвалро, ки ба ин DBMS хос аст, гиред:

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

Oracle information_schema-ро намедонад, аммо дорад Метамаълумоти Oracle, ва ҳеҷ мушкилоти калон ба миён намеояд:

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

ClickHouse истисно нест:

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

Чизи ба ин монандро дар Кассандра анҷом додан мумкин аст (ки дорои оилаҳои сутунҳо ба ҷои ҷадвалҳо ва фазои калидҳо ба ҷои схемаҳо):

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

Барои аксари дигар пойгоҳи додаҳо, шумо инчунин метавонед саволҳои шабеҳро пешниҳод кунед (ҳатто Mongo дорои ҷамъоварии системаи махсус, ки дорои маълумот дар бораи ҳамаи коллексияҳои система).

Албатта, бо ин рох на танхо дар бораи чадвалхо, балки умуман дар бораи ягон объект маълумот гирифтан мумкин аст. Баъзан одамони меҳрубон чунин кодро барои пойгоҳи додаҳои гуногун мубодила мекунанд, масалан, дар силсилаи мақолаҳои хабра "Функсияҳо барои ҳуҷҷатгузории пойгоҳи додаҳои PostgreSQL" (Айб, ман, Варзишгоҳ). Албатта, дар сари ман нигоҳ доштани ин кӯҳи пурсишҳо ва пайваста чоп кардани онҳо як лаззат аст, аз ин рӯ дар IDE/муҳаррири дӯстдоштаи худ ман маҷмӯи порчаҳои қаблан омодашуда барои дархостҳои зуд-зуд истифодашаванда дорам ва танҳо чоп кардани он аст. номҳои объектро ба қолаб ворид кунед.

Дар натиҷа, ин усули паймоиш ва ҷустуҷӯи объектҳо хеле чандиртар аст, вақти зиёдро сарфа мекунад ва ба шумо имкон медиҳад, ки маълумотро дар шакле, ки ҳоло зарур аст, гиред (чунон ки, масалан, дар мақола тасвир шудааст) "Содироти маълумот аз пойгоҳи додаҳо дар ҳама гуна формат: IDE-ҳо дар платформаи IntelliJ чӣ кор карда метавонанд").

Амалиёт бо объектҳо

Пас аз он ки мо объектҳои заруриро ёфтем ва омӯзем, вақти он расидааст, ки бо онҳо ягон кори муфид анҷом диҳем. Табиист, ки инчунин бидуни гирифтани ангуштони худ аз клавиатура.

Ба касе пӯшида нест, ки танҳо нест кардани ҷадвал тақрибан дар ҳама базаҳои маълумот якхела хоҳад буд:

drop table hr.persons

Аммо бо ташкили ҷадвал он ҷолибтар мешавад. Қариб ҳама DBMS (аз ҷумла бисёр NoSQL) метавонанд дар ин ё он шакл "ҷадвал эҷод кунанд" ва қисми асосии он ҳатто каме фарқ мекунад (ном, рӯйхати сутунҳо, намудҳои маълумот), аммо тафсилоти дигар метавонанд ба таври назаррас фарқ кунанд ва аз он вобаста бошанд. дастгоҳи дохилӣ ва имкониятҳои DBMS мушаххас. Намунаи дӯстдоштаи ман ин аст, ки дар ҳуҷҷатҳои Oracle танҳо BNF-ҳои "бараҳна" барои синтаксиси "сохтани ҷадвал" мавҷуданд. 31 саҳифаро ишғол мекунад. Дигар DBMS дорои қобилиятҳои хоксортар мебошанд, аммо ҳар яки онҳо инчунин дорои бисёр хусусиятҳои ҷолиб ва беназир барои сохтани ҷадвалҳо (постгресс, MySQL, таракан, кассандра). Гумон аст, ки ягон «ҷодугар»-и графикӣ аз IDE-и дигар (хусусан универсалӣ) тавонад ҳамаи ин қобилиятҳоро пурра фаро гирад ва ҳатто агар тавониста бошад ҳам, барои одамони сустдил тамошобоб нахоҳад буд. Дар баробари ин баёнияи дуруст ва сари вакт навишта шудааст ҷадвал эҷод кунед ба шумо имкон медиҳад, ки ҳамаи онҳоро ба осонӣ истифода баред, нигоҳдорӣ ва дастрасиро ба маълумоти шумо боэътимод, оптималӣ ва то ҳадди имкон бароҳат созед.

Инчунин, бисёре аз DBMS-ҳо намудҳои махсуси объектҳои худро доранд, ки дар дигар МДМ мавҷуд нестанд. Гузашта аз ин, мо метавонем амалиётҳоро на танҳо дар объектҳои пойгоҳи додаҳо, балки дар худи DBMS иҷро кунем, масалан, равандро «кушед», як қисми хотираро озод кунед, пайгирӣро фаъол созед, ба режими «танҳо барои хондан» гузаред ва ғайра.

Акнун биёед каме тасвир кунем

Яке аз вазифаҳои маъмултарин ин сохтани диаграмма бо объектҳои пойгоҳи додаҳо ва дидани объектҳо ва робитаҳои байни онҳо дар тасвири зебо мебошад. Қариб ҳама гуна IDE графикӣ, утилитаҳои алоҳидаи "хати фармон", асбобҳои махсуси графикӣ ва моделсозон метавонанд ин корро кунанд. Онҳо барои шумо чизеро "то ҳадди имкон метавонанд" ҷалб кунанд ва шумо метавонед ба ин раванд танҳо бо ёрии чанд параметр дар файли конфигуратсия ё қуттиҳои қайд дар интерфейс каме таъсир расонед.

Аммо ин масъаларо хеле соддатар, чандиртар ва шево ва албатта бо ёрии код хал кардан мумкин аст. Барои сохтани диаграммаҳои ҳама гуна мураккабӣ, мо якчанд забонҳои махсуси аломатгузорӣ дорем (DOT, GraphML ва ғайра) ва барои онҳо як пароканиши пурраи барномаҳо (GraphViz, PlantUML, Mermaid), ки метавонанд ин гуна дастурҳоро хонанд ва онҳоро дар форматҳои гуногун тасаввур кунанд. . Хуб, мо аллакай медонем, ки чӣ тавр дар бораи объектҳо ва робитаҳои байни онҳо маълумот гирифтан мумкин аст.

Ин як мисоли хурди он аст, ки ин метавонад бо истифода аз PlantUML ва пойгоҳи додаҳои намоишӣ барои PostgreSQL (дар тарафи чап дархости SQL аст, ки дастури заруриро барои PlantUML тавлид мекунад ва дар тарафи рост натиҷа аст):

Таҷрибаи "Махзани маълумот ҳамчун код"

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'

Ва агар шумо каме кӯшиш кунед, пас дар асоси Шаблон ER барои PlantUML шумо метавонед чизеро ба диаграммаи воқеии ER монанд гиред:

Дархости SQL каме мураккабтар аст

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

Таҷрибаи "Махзани маълумот ҳамчун код"

Агар шумо бодиққат назар кунед, дар зери сарпӯш бисёр асбобҳои визуализатсия низ дархостҳои шабеҳро истифода мебаранд. Дуруст аст, ки ин дархостҳо одатан амиқанд Ба коди худи барнома "муқаррар карда шудааст" ва фаҳмидан душвор аст, ба ҳеҷ гуна тағйирот дар бораи онҳо ёдовар нест.

Метрикҳо ва мониторинг

Биёед ба мавзӯи анъанавии мураккаб - мониторинги иҷрои пойгоҳи додаҳо гузарем. Ман як ҳикояи ҳақиқии хурдеро ба ёд меорам, ки "яке аз дӯстонам" ба ман гуфта буд. Дар лоиҳаи дигар як DBA-и пурқудрат зиндагӣ мекард ва каме аз таҳиягарон ӯро шахсан мешинохтанд ё боре ӯро шахсан дидаанд (бо вуҷуди он, ки тибқи овозаҳо, ӯ дар ягон бинои дигар кор мекард). Дар соати "X", вақте ки системаи подукционии як фурӯшандаи калон бори дигар "бад ҳис" кард, вай хомӯшона скриншотҳои графикҳоро аз Менеҷери Enterprise Oracle фиристод, ки дар онҳо ҷойҳои муҳимро бо аломати сурх барои "фаҳмо будан" бодиққат қайд кард ( ин, нарм карда гуем, чандон ёрй нарасонд). Ва дар асоси ин «фотокарта» ман бояд табобат кунам. Дар айни замон, ҳеҷ кас ба мудири корхонаи қиматбаҳо (ба ҳар ду маънои калима) дастрасӣ надошт, зеро система мураккаб ва гарон аст, ногаҳон «таҳиягарон ба чизе пешпо мехӯранд ва ҳама чизро мешикананд». Аз ин рӯ, таҳиягарон "ба таври таҷрибавӣ" макон ва сабаби тормозҳоро пайдо карданд ва ямоқи онро бароварданд. Агар дар ояндаи наздик мактуби тахдидкунандаи ДБА нарасид, пас хама нафаси сабук кашида, ба кори имрузаи худ бармегарданд (то мактуби нав).

Аммо раванди мониторинг метавонад шавқовартар ва дӯстона ва муҳимтар аз ҳама, барои ҳама дастрас ва шаффоф ба назар расад. Ҳадди ақал қисми асосии он, ҳамчун илова ба системаҳои асосии мониторинг (ки албатта муфид ва дар бисёр ҳолатҳо ивазнашавандаанд). Ҳама гуна DBMS ройгон ва комилан ройгон аст, то маълумотро дар бораи ҳолати кунунӣ ва иҷрои он мубодила кунад. Дар ҳамон Oracle DB "хундор" тақрибан ҳама гуна маълумотро дар бораи иҷроиш аз намуди система, аз равандҳо ва сеансҳо то ҳолати кэши буферӣ гирифтан мумкин аст (масалан, Скриптҳои DBA, фасли «Мониторинг»). Postgresql инчунин дорои як қатор назари система барои мониторинги пойгоҳи додаҳо, махсусан онҳое, ки дар ҳаёти ҳаррӯзаи ҳама DBA ҳатмӣ мебошанд, ба монанди pg_stat_activity, pg_stat_base, pg_stat_bgwriter. MySQL ҳатто барои ин схемаи алоҳида дорад. иҷрои_схема. A Дар Mongo дарунсохт профилактик маълумоти иҷроишро ба маҷмӯи система ҷамъ мекунад system.profile.

Ҳамин тариқ, бо як намуди коллекторҳои метрикӣ (Telegraf, Metricbeat, Collectd), ки метавонад дархостҳои фармоишии sql-ро иҷро кунад, нигоҳдории ин метрикҳо (InfluxDB, Elasticsearch, Timescaledb) ва визуализатор (Grafana, Kibana), шумо метавонед хеле осон ба даст оред. ва системаи мониторинги чандир, ки бо дигар ченакҳои системавӣ зич муттаҳид карда мешавад (масалан, аз сервери барномаҳо, аз ОС ва ғ. гирифта мешавад). Масалан, ин дар pgwatch2 анҷом дода мешавад, ки омезиши InfluxDB + Grafana ва маҷмӯи дархостҳоро барои намоишҳои система истифода мебарад, ки ба онҳо низ дастрас шудан мумкин аст. дархостҳои фармоиширо илова кунед.

Ҳамагӣ

Ва ин танҳо як рӯйхати тахминии он чизест, ки бо пойгоҳи додаи мо бо истифода аз рамзи муқаррарии SQL чӣ кор кардан мумкин аст. Ман боварӣ дорам, ки шумо метавонед бисёр истифодаҳоро пайдо кунед, дар шарҳҳо нависед. Ва мо дар бораи он сӯҳбат хоҳем кард, ки чӣ гуна (ва муҳимтар аз ҳама, чаро) ин ҳамаро автоматӣ кунем ва дафъаи оянда онро ба лӯлаи CI/CD дохил кунем.

Манбаъ: will.com

Илова Эзоҳ