SQL, beth allai fod yn haws? Gall pob un ohonom ysgrifennu cais syml - rydym yn teipio dewiswch, rhestrwch y colofnau gofynnol, yna o, enw tabl, ychydig o amodau yn lle a dyna i gyd - data defnyddiol yn ein poced, a (bron) waeth pa DBMS sydd o dan y cwfl bryd hynny (neu efallai
A gadewch i ni ddechrau yn iawn gyda
Mapio perthynol i wrthrychau
Yn draddodiadol, mae cynigwyr ORM yn gwerthfawrogi cyflymder a rhwyddineb datblygiad, annibyniaeth o'r DBMS a phurdeb y cod. I lawer ohonom, y cod ar gyfer gweithio gyda'r gronfa ddata (ac yn aml y gronfa ddata ei hun)
mae fel arfer yn edrych fel hyn...
@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;
}
...
Mae'r model wedi'i lapio mewn anodiadau clyfar, ac yn rhywle y tu ôl i'r llenni, mae ORM dewr yn cynhyrchu ac yn gweithredu tunnell o god SQL. Gyda llaw, mae datblygwyr yn ceisio gyda'u holl nerth i ynysu eu hunain o'u cronfa ddata gyda chilomedrau o dyniadau, sy'n dangos rhai
Ar ochr arall y barricades, mae ymlynwyr o "wneud â llaw" pur -SQL yn nodi'r gallu i wasgu'r holl sudd allan o'u DBMS heb haenau a thynnu ychwanegol. O ganlyniad, mae prosiectau "data-ganolog" yn ymddangos, lle mae pobl sydd wedi'u hyfforddi'n arbennig yn cymryd rhan yn y gronfa ddata (maent hefyd yn "sylfaenwyr", maent hefyd yn "sylfaenwyr", maent hefyd yn "bastardiaid", ac ati), a datblygwyr yn unig gorfod "tynnu" golygfeydd parod a gweithdrefnau wedi'u storio, heb fynd i fanylion.
A beth os cymerwch y gorau o'r ddau fyd? Sut mae'n cael ei wneud mewn teclyn gwych gydag enw sy'n cadarnhau bywyd
Mae Clojure yn iaith cŵl ar gyfer adeiladu DSLs, ond mae SQL ei hun yn DSL cŵl ac nid oes angen un arall arnom. Mae ymadroddion S yn wych, ond nid ydynt yn ychwanegu unrhyw beth newydd yma. O ganlyniad, rydym yn cael cromfachau er mwyn cromfachau. Ddim yn cytuno? Yna arhoswch am y foment pan fydd y tynnu dros y gronfa ddata yn gollwng, a byddwch yn dechrau ymladd â'r swyddogaeth (amrai-sql)
A beth i'w wneud? Gadewch i ni adael SQL fel SQL arferol - un ffeil fesul cais:
-- name: users-by-country
select *
from users
where country_code = :country_code
...ac yna darllenwch y ffeil honno, gan ei throi'n swyddogaeth Clojure arferol:
(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" ...} ...)
Trwy gadw at yr egwyddor "SQL ar wahân, Clojure ar wahân", rydych chi'n cael:
- Dim syndod syntactig. Nid yw eich cronfa ddata (fel unrhyw un arall) yn cydymffurfio 100% SQL - ond nid yw Yesql yn poeni. Ni fyddwch byth yn gwastraffu amser yn chwilio am swyddogaethau gyda chystrawen gyfatebol SQL. Nid oes yn rhaid i chi byth ddychwelyd i swyddogaeth (raw-sql "rhai ('ffynci'::SYNTAX)")).
- Gwell cefnogaeth golygydd. Mae gan eich golygydd gefnogaeth SQL ardderchog eisoes. Trwy storio SQL fel SQL gallwch chi ei ddefnyddio.
- Cydnawsedd Tîm. Gall eich DBAs ddarllen ac ysgrifennu'r SQL a ddefnyddiwch yn eich prosiect Clojure.
- Tiwnio perfformiad haws. Angen adeiladu cynllun ar gyfer ymholiad problemus? Nid yw hyn yn broblem pan fydd eich ymholiad yn SQL rheolaidd.
- Ailddefnyddio ymholiadau. Llusgwch yr un ffeiliau SQL hynny i brosiectau eraill oherwydd ei fod yn hen SQL da - dim ond ei rannu.
Yn fy marn i, mae'r syniad yn cŵl iawn ac ar yr un pryd yn syml iawn, diolch i'r hyn mae'r prosiect wedi ennill llawer
Rheolwyr DRhA a DB
Gadewch i ni ddechrau gyda thasg bob dydd syml. Yn aml mae'n rhaid i ni chwilio am rai gwrthrychau yn y gronfa ddata, er enghraifft, dod o hyd i dabl yn y sgema ac astudio ei strwythur (pa golofnau, allweddi, mynegeion, cyfyngiadau, ac ati sy'n cael eu defnyddio). Ac o unrhyw IDE graffigol neu reolwr DB bach, yn gyntaf oll, rydym yn aros am yr union alluoedd hyn. Fel ei fod yn gyflym ac nad oes rhaid iddo aros hanner awr nes bod ffenestr gyda'r wybodaeth angenrheidiol yn cael ei thynnu (yn enwedig gyda chysylltiad araf â chronfa ddata anghysbell), ac ar yr un pryd bod y wybodaeth a dderbynnir yn ffres ac yn berthnasol, a sothach heb ei storio. Ar ben hynny, po fwyaf cymhleth a mwyaf yw'r gronfa ddata a'r mwyaf yw eu nifer, y mwyaf anodd yw hi i'w wneud.
Ond fel arfer dwi'n taflu'r llygoden ymhell i ffwrdd a jest ysgrifennu'r côd. Gadewch i ni ddweud eich bod chi eisiau gwybod pa dablau (a pha briodweddau) sydd wedi'u cynnwys yn y sgema "AD". Yn y rhan fwyaf o DBMS, gellir cyflawni'r canlyniad a ddymunir gydag ymholiad mor syml o information_schema:
select table_name
, ...
from information_schema.tables
where schema = 'HR'
O gronfa ddata i gronfa ddata, mae cynnwys tablau chwilio o'r fath yn amrywio yn dibynnu ar allu pob DBMS. Ac, er enghraifft, ar gyfer MySQL, o'r un cyfeiriadur, gallwch gael paramedrau tabl sy'n benodol i'r DBMS hwn:
select table_name
, storage_engine -- Используемый "движок" ("MyISAM", "InnoDB" etc)
, row_format -- Формат строки ("Fixed", "Dynamic" etc)
, ...
from information_schema.tables
where schema = 'HR'
Nid yw Oracle yn gwybod information_schema, ond mae'n gwybod
select table_name
, pct_free -- Минимум свободного места в блоке данных (%)
, pct_used -- Минимум используемого места в блоке данных (%)
, last_analyzed -- Дата последнего сбора статистики
, ...
from all_tables
where owner = 'HR'
Nid yw ClickHouse yn eithriad:
select name
, engine -- Используемый "движок" ("MergeTree", "Dictionary" etc)
, ...
from system.tables
where database = 'HR'
Gellir gwneud rhywbeth tebyg yn Cassandra (sydd â theuluoedd colofn yn lle tablau a bylchau allweddol yn lle sgemâu):
select columnfamily_name
, compaction_strategy_class -- Стратегия сборки мусора
, gc_grace_seconds -- Время жизни мусора
, ...
from system.schema_columnfamilies
where keyspace_name = 'HR'
Ar gyfer y rhan fwyaf o gronfeydd data eraill, gallwch hefyd ddod o hyd i ymholiadau tebyg (mae gan Mongo hyd yn oed
Wrth gwrs, yn y modd hwn gallwch gael gwybodaeth nid yn unig am dablau, ond yn gyffredinol am unrhyw wrthrych. O bryd i'w gilydd, mae pobl garedig yn rhannu cod o'r fath ar gyfer gwahanol gronfeydd data, fel, er enghraifft, yn y gyfres o erthyglau habra "Swyddogaethau ar gyfer dogfennu cronfeydd data PostgreSQL" (
O ganlyniad, mae'r ffordd hon o lywio a chwilio am wrthrychau yn llawer mwy hyblyg, yn arbed llawer o amser, yn caniatáu ichi gael yr union wybodaeth ac yn y ffurf y mae ei hangen arnoch nawr (fel, er enghraifft, a ddisgrifir yn y post).
Gweithrediadau gyda gwrthrychau
Ar ôl i ni ddarganfod ac astudio'r gwrthrychau angenrheidiol, mae'n bryd gwneud rhywbeth defnyddiol gyda nhw. Yn naturiol, hefyd heb dynnu'ch bysedd oddi ar y bysellfwrdd.
Nid yw'n gyfrinach y bydd dileu tabl yn edrych yr un peth ym mron pob cronfa ddata:
drop table hr.persons
Ond gyda chreu'r tabl eisoes yn fwy diddorol. Gall bron unrhyw DBMS (gan gynnwys llawer o NoSQL) mewn rhyw ffurf neu'i gilydd "greu tabl", ac ni fydd ei brif ran hyd yn oed yn wahanol iawn (enw, rhestr o golofnau, mathau o ddata), ond gall manylion eraill amrywio'n ddramatig a dibynnu ar y ddyfais fewnol a galluoedd DBMS penodol. Fy hoff enghraifft yw mai dim ond un BNF "moel" sydd yn nogfennaeth Oracle ar gyfer y gystrawen "creu tabl"
Hefyd, mae gan lawer o DBMS eu mathau penodol eu hunain o wrthrychau nad ydynt ar gael mewn DBMSs eraill. Ar ben hynny, gallwn berfformio gweithrediadau nid yn unig ar wrthrychau cronfa ddata, ond hefyd ar y DBMS ei hun, er enghraifft, "lladd" y broses, am ddim rhywfaint o ardal cof, galluogi olrhain, newid i "darllen yn unig" modd, a llawer mwy.
Ac yn awr gadewch i ni dynnu ychydig
Un o'r tasgau mwyaf cyffredin yw adeiladu diagram gyda gwrthrychau cronfa ddata, i weld y gwrthrychau a'r berthynas rhyngddynt mewn llun hardd. Gall bron unrhyw DRhA graffig, cyfleustodau "llinell orchymyn" ar wahân, offer graffig arbenigol a modelwyr wneud hyn. A fydd yn tynnu rhywbeth i chi "y gorau y gallant", a dim ond gyda chymorth ychydig o baramedrau yn y ffeil ffurfweddu neu'r blychau gwirio yn y rhyngwyneb y gallwch chi ddylanwadu ychydig ar y broses hon.
Ond gellir datrys y broblem hon mewn ffordd llawer symlach, mwy hyblyg a chain, ac wrth gwrs gyda chymorth cod. I adeiladu diagramau o unrhyw gymhlethdod, mae gennym nifer o ieithoedd marcio arbenigol ar unwaith (DOT, GraphML ac ati), ac ar eu cyfer - criw cyfan o gymwysiadau (GraphViz, PlantUML, Mermaid) sy'n gallu darllen cyfarwyddiadau o'r fath a'u delweddu mewn a amrywiaeth o fformatau. Wel, rydym eisoes yn gwybod sut i gael gwybodaeth am wrthrychau a'r berthynas rhyngddynt.
Gadewch i ni roi enghraifft fach o sut y gallai edrych fel defnyddio PlantUML a
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'
Ac os ceisiwch ychydig, yna ar sail
Mae ymholiad SQL ychydig yn fwy cymhleth
-- Шапка
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'
Os edrychwch yn ofalus, o dan y cwfl, mae llawer o offer delweddu hefyd yn defnyddio ymholiadau tebyg. Yn wir, mae'r ceisiadau hyn fel arfer yn ddwfn
Metrigau a monitro
Gadewch i ni symud ymlaen at y pwnc anodd yn draddodiadol - monitro perfformiad cronfa ddata. Rwy'n cofio stori fach wir a adroddwyd wrthyf gan "un o fy ffrindiau". Ar y prosiect nesaf, roedd DBA pwerus yn byw yno, ac ychydig o'r datblygwyr oedd yn ei adnabod yn bersonol, ac yn wir erioed wedi ei weld yn y llygad (er gwaethaf y ffaith ei fod yn gweithio, yn ôl sibrydion, rhywle mewn adeilad cyfagos). Ar awr "X", pan ddechreuodd system poduction manwerthwr mawr "deimlo'n ddrwg" unwaith eto, anfonodd sgrinluniau o graffiau yn dawel oddi wrth y Rheolwr Menter Oracle, ac amlygodd yn ofalus leoedd hanfodol gyda marciwr coch ar gyfer "clirder" (ni wnaeth hyn, i'w roi'n ysgafn, helpu llawer). Ac roedd yn rhaid trin y "cerdyn llun" hwn. Ar yr un pryd, nid oedd gan neb fynediad at y Rheolwr Menter gwerthfawr (yn y ddau ystyr o'r gair), oherwydd mae'r system yn gymhleth ac yn ddrud, yn sydyn "bydd y datblygwyr yn baglu ar rywbeth ac yn torri popeth." Felly, mae'r datblygwyr "empirig" dod o hyd i'r lle ac achos y breciau a rhyddhau darn. Os na ddaeth y llythyr ofnadwy oddi wrth DBA eto yn y dyfodol agos, yna anadlodd pawb ochenaid o ryddhad a dychwelyd at eu tasgau presennol (tan y Llythyr newydd).
Ond gall y broses fonitro edrych yn fwy hwyliog a chyfeillgar, ac yn bwysicaf oll, yn hygyrch ac yn dryloyw i bawb. O leiaf ei ran sylfaenol, fel ychwanegiad at y prif systemau monitro (sy'n sicr yn ddefnyddiol ac mewn llawer o achosion na ellir eu hadnewyddu). Mae unrhyw DBMS yn rhydd ac yn rhad ac am ddim yn barod i rannu gwybodaeth am ei gyflwr a'i berfformiad presennol. Yn yr un Oracle DB "gwaedlyd", gellir cael bron unrhyw wybodaeth perfformiad o olygfeydd system, o brosesau a sesiynau i gyflwr y storfa byffer (er enghraifft,
Felly, wedi'i arfogi â rhyw fath o gasglwr metrigau (Telegraf, Metricbeat, Collectd), a all weithredu ymholiadau sql arferol, storfa o'r metrigau hyn (InfluxDB, Elasticsearch, Timescaledb) a delweddwr (Grafana, Kibana), gallwch gael gweddol. system fonitro hawdd a hyblyg a fydd wedi'i hintegreiddio'n dynn â metrigau system gyfan eraill (a geir, er enghraifft, gan weinydd y cais, gan yr OS, ac ati). Fel, er enghraifft, mae'n cael ei wneud yn pgwatch2, sy'n defnyddio bwndel InfluxDB + Grafana a set o ymholiadau i farn system, a all hefyd fod yn
Yn gyfan gwbl
A dim ond bras restr yw hon o'r hyn y gellir ei wneud gyda'n cronfa ddata gan ddefnyddio cod SQL cyffredin. Rwy'n siŵr y gallwch ddod o hyd i lawer mwy o geisiadau, ysgrifennwch y sylwadau. A byddwn yn siarad am sut (ac yn bwysicaf oll pam) i awtomeiddio hyn i gyd a'i gynnwys yn eich piblinell CI / CD y tro nesaf.
Ffynhonnell: hab.com