SQL, daha basit ne olabilir? Her birimiz basit bir istek yazabiliriz - biz yazarız seçmek, gerekli sütunları listeleyin ve ardından itibaren, tablo adı, bazı koşullar nerede ve hepsi bu - yararlı veriler cebimizde ve (neredeyse) o sırada hangi DBMS'nin kaputun altında olduğuna bakılmaksızın (veya belki de)
Ve hemen başlayalım
Nesne-ilişkisel haritalama
ORM destekçileri geleneksel olarak hıza ve geliştirme kolaylığına, DBMS'den bağımsızlığa ve temiz koda değer verir. Birçoğumuz için veritabanıyla (ve çoğunlukla veritabanının kendisiyle) çalışmanın kodu
genelde şöyle görünür...
@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 akıllı açıklamalarla süslenmiştir ve perde arkasında bir yerde güçlü bir ORM tonlarca SQL kodu üretip çalıştırır. Bu arada, geliştiriciler kilometrelerce soyutlamayla kendilerini veritabanlarından izole etmek için ellerinden geleni yapıyorlar;
Barikatların diğer tarafında, saf "el yapımı" SQL taraftarları, ek katmanlar ve soyutlamalar olmadan DBMS'lerinin tüm suyunu sıkabilme yeteneğine dikkat çekiyor. Sonuç olarak, özel eğitimli kişilerin veritabanına dahil olduğu (bunlar aynı zamanda “temelciler”, aynı zamanda “temelciler”, aynı zamanda “bazdenschiki” vb.) ve geliştiricilerin dahil olduğu “veri merkezli” projeler ortaya çıkıyor. ayrıntılara girmeden yalnızca hazır görünümleri ve saklı prosedürleri "çekmeniz" gerekir.
Ya her iki dünyanın da en iyisine sahip olsaydık? Bu, yaşamı onaylayan bir isme sahip harika bir araçla nasıl yapılır?
Clojure, DSL oluşturmak için harika bir dildir, ancak SQL'in kendisi de harika bir DSL'dir ve başka bir dile ihtiyacımız yok. S ifadeleri harika ama buraya yeni bir şey eklemiyorlar. Sonuç olarak, parantez uğruna parantez alıyoruz. Katılmıyorum? Daha sonra veritabanı üzerindeki soyutlamanın sızmaya başlayacağı ve fonksiyonla kavga etmeye başlayacağınız anı bekleyin. (ham-sql)
Peki ne yapmalıyım? SQL'i normal SQL olarak bırakalım - istek başına bir dosya:
-- name: users-by-country
select *
from users
where country_code = :country_code
... ve ardından bu dosyayı normal bir Clojure işlevine dönüştürerek okuyun:
(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'in kendisi, Clojure'un kendisi" ilkesine bağlı kalarak şunları elde edersiniz:
- Sözdizimsel sürprizler yok. Veritabanınız (diğerleri gibi) SQL standardıyla %100 uyumlu değil - ancak bu Yesql için önemli değil. SQL eşdeğer sözdizimine sahip işlevleri aramak için asla zaman kaybetmezsiniz. Bir işleve asla geri dönmek zorunda kalmayacaksınız (raw-sql "bazı('funky'::SÖZDİZİMİ))").
- En iyi editör desteği. Editörünüz zaten mükemmel SQL desteğine sahip. SQL'i SQL olarak kaydederek kolayca kullanabilirsiniz.
- Takım uyumluluğu. DBA'larınız Clojure projenizde kullandığınız SQL'i okuyabilir ve yazabilir.
- Daha kolay performans ayarı. Sorunlu bir sorgu için bir plan mı oluşturmanız gerekiyor? Sorgunuz normal SQL olduğunda bu bir sorun değildir.
- Sorguları yeniden kullanma Aynı SQL dosyalarını diğer projelere sürükleyip bırakın çünkü bu sadece eski bir SQL'dir; sadece paylaşın.
Bana göre fikir çok havalı ve aynı zamanda çok basit, bu sayede proje pek çok şey kazandı
IDE ve DB yöneticileri
Basit bir günlük görevle başlayalım. Çoğunlukla veritabanındaki bazı nesneleri aramamız gerekir; örneğin şemada bir tablo bulmamız ve yapısını (hangi sütunların, anahtarların, dizinlerin, kısıtlamaların vb. kullanıldığı) incelememiz gerekir. Ve herhangi bir grafiksel IDE'den veya küçük bir DB yöneticisinden, her şeyden önce tam olarak bu yetenekleri bekliyoruz. Böylece hızlı olur ve gerekli bilgileri içeren bir pencere çizilene kadar yarım saat beklemenize gerek kalmaz (özellikle uzak bir veritabanına yavaş bağlantı durumunda) ve aynı zamanda alınan bilgiler taze ve alakalı olur, ve önbelleğe alınmış önemsiz şeyler değil. Üstelik veri tabanı ne kadar karmaşık ve büyük olursa ve bunların sayısı da o kadar fazla olur, bunu yapmak da o kadar zor olur.
Ama genellikle fareyi atıyorum ve sadece kod yazıyorum. Diyelim ki "HR" şemasında hangi tabloların (ve hangi özelliklerle) yer aldığını bulmanız gerekiyor. Çoğu DBMS'de istenen sonuca, information_schema'dan gelen bu basit sorguyla ulaşılabilir:
select table_name
, ...
from information_schema.tables
where schema = 'HR'
Bu tür referans tablolarının içeriği, veritabanından veritabanına her DBMS'nin yeteneklerine bağlı olarak değişir. Ve örneğin MySQL için aynı referans kitabından bu DBMS'ye özel tablo parametrelerini alabilirsiniz:
select table_name
, storage_engine -- Используемый "движок" ("MyISAM", "InnoDB" etc)
, row_format -- Формат строки ("Fixed", "Dynamic" etc)
, ...
from information_schema.tables
where schema = 'HR'
Oracle bilgi_şemasını bilmiyor ancak var
select table_name
, pct_free -- Минимум свободного места в блоке данных (%)
, pct_used -- Минимум используемого места в блоке данных (%)
, last_analyzed -- Дата последнего сбора статистики
, ...
from all_tables
where owner = 'HR'
ClickHouse bir istisna değildir:
select name
, engine -- Используемый "движок" ("MergeTree", "Dictionary" etc)
, ...
from system.tables
where database = 'HR'
Benzer bir şey Cassandra'da da yapılabilir (tablolar yerine sütun aileleri ve şemalar yerine anahtar uzayları vardır):
select columnfamily_name
, compaction_strategy_class -- Стратегия сборки мусора
, gc_grace_seconds -- Время жизни мусора
, ...
from system.schema_columnfamilies
where keyspace_name = 'HR'
Diğer birçok veritabanı için de benzer sorgular bulabilirsiniz (Mongo'nun bile
Elbette bu sayede sadece tablolar hakkında değil genel olarak her türlü nesne hakkında bilgi alabilirsiniz. Zaman zaman nazik insanlar bu tür kodları farklı veritabanları için paylaşırlar; örneğin, Habra'nın “PostgreSQL veritabanlarını belgeleme işlevleri” başlıklı makale serisinde (
Sonuç olarak, nesnelerde gezinmenin ve nesneleri aramanın bu yöntemi çok daha esnektir, çok zaman kazandırır ve bilgileri tam olarak gerekli olan biçimde (örneğin, gönderide açıklandığı gibi) almanızı sağlar.
Nesnelerle işlemler
Gerekli nesneleri bulup inceledikten sonra onlarla faydalı bir şeyler yapmanın zamanı geldi. Doğal olarak parmaklarınızı klavyeden ayırmadan.
Bir tabloyu silmenin neredeyse tüm veritabanlarında aynı görüneceği bir sır değil:
drop table hr.persons
Ancak tablonun oluşturulmasıyla daha ilginç hale geliyor. Hemen hemen her DBMS (birçok NoSQL dahil) şu veya bu şekilde "tablo oluşturabilir" ve ana kısmı biraz farklılık gösterebilir (ad, sütun listesi, veri türleri), ancak diğer ayrıntılar önemli ölçüde farklılık gösterebilir ve kullanılan tabloya bağlı olabilir. belirli bir DBMS'nin dahili cihazı ve yetenekleri. En sevdiğim örnek, Oracle belgelerinde "tablo oluştur" sözdizimi için yalnızca "çıplak" BNF'lerin bulunmasıdır
Ayrıca birçok DBMS'nin, diğer DBMS'lerde bulunmayan kendine özgü nesne türleri vardır. Üstelik, yalnızca veritabanı nesneleri üzerinde değil, aynı zamanda DBMS'nin kendisinde de işlemler gerçekleştirebiliriz; örneğin, bir işlemi "sonlandırmak", bir miktar bellek alanı boşaltmak, izlemeyi etkinleştirmek, "salt okunur" moduna geçmek ve çok daha fazlası.
Şimdi biraz çizelim
En yaygın görevlerden biri, veritabanı nesneleriyle bir diyagram oluşturmak ve nesneleri ve aralarındaki bağlantıları güzel bir resimde görmektir. Hemen hemen her grafiksel IDE, ayrı “komut satırı” yardımcı programları, özel grafik araçları ve modelleyiciler bunu yapabilir. Sizin için “ellerinden geldiğince” bir şeyler çizecekler ve siz de ancak konfigürasyon dosyasındaki birkaç parametre veya arayüzdeki onay kutularının yardımıyla bu süreci biraz etkileyebilirsiniz.
Ancak bu sorun çok daha basit, daha esnek ve zarif bir şekilde ve elbette kod yardımıyla çözülebilir. Herhangi bir karmaşıklıkta diyagramlar oluşturmak için, birkaç özel işaretleme dilimiz (DOT, GraphML vb.) ve onlar için bu tür talimatları okuyabilen ve bunları çeşitli formatlarda görselleştirebilen çok çeşitli uygulamalar (GraphViz, PlantUML, Mermaid) var. . Nesneler ve aralarındaki bağlantılar hakkında nasıl bilgi edineceğimizi zaten biliyoruz.
İşte PlantUML kullanılarak bunun nasıl görünebileceğine dair küçük bir örnek ve
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'
Ve eğer biraz denersen, o zaman
SQL sorgusu biraz daha karmaşıktır
-- Шапка
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'
Yakından bakarsanız pek çok görselleştirme aracının da benzer sorguları kullandığını görürsünüz. Doğru, bu istekler genellikle derinden
Metrikler ve izleme
Geleneksel olarak karmaşık bir konuya geçelim: veritabanı performansının izlenmesi. Bana “arkadaşlarımdan birinin” anlattığı küçük, gerçek bir hikayeyi hatırlıyorum. Başka bir projede güçlü bir DBA yaşıyordu ve geliştiricilerden çok azı onu kişisel olarak tanıyordu veya onu şahsen görmüştü (söylentilere göre yan binada bir yerde çalıştığı gerçeğine rağmen) . Büyük bir perakendecinin üretim sistemi bir kez daha "kötü hissetmeye" başladığında "X" saatinde, Oracle Enterprise Manager'dan sessizce grafiklerin ekran görüntülerini gönderdi ve bu ekran görüntülerinde kritik yerleri "anlaşılırlık" için kırmızı bir işaretleyiciyle dikkatlice vurguladı ( en hafif tabirle bunun pek bir faydası olmadı). Ve bu "fotoğraf kartına" dayanarak tedavi etmek zorunda kaldım. Aynı zamanda, hiç kimsenin değerli (kelimenin her iki anlamında da) İşletme Yöneticisine erişimi yoktu, çünkü sistem karmaşık ve pahalıdır, birdenbire "geliştiriciler bir şeye rastlar ve her şeyi bozar." Bu nedenle geliştiriciler, frenlerin yerini ve nedenini "deneysel olarak" buldular ve bir yama yayınladılar. Eğer DBA'dan gelen tehditkar mektup yakın gelecekte tekrar gelmezse, o zaman herkes rahat bir nefes alacak ve mevcut görevlerine geri dönecektir (yeni Mektup'a kadar).
Ancak izleme süreci herkes için daha eğlenceli ve samimi, en önemlisi de erişilebilir ve şeffaf görünebilir. En azından ana izleme sistemlerine ek olarak temel kısmı (kesinlikle faydalıdır ve birçok durumda yeri doldurulamaz). Herhangi bir DBMS'nin mevcut durumu ve performansı hakkında bilgi paylaşımı serbestçe ve kesinlikle ücretsizdir. Aynı "kanlı" Oracle DB'de, performansla ilgili hemen hemen her türlü bilgi, süreçlerden ve oturumlardan arabellek önbelleğinin durumuna kadar sistem görünümlerinden elde edilebilir (örneğin,
Böylece, özel sql sorguları gerçekleştirebilen bir tür metrik toplayıcı (Telegraf, Metricbeat, Collectd), bu metriklerin depolandığı (InfluxDB, Elasticsearch, Timescaledb) ve bir görselleştirici (Grafana, Kibana) ile donatılmış olarak, oldukça kolay bir şekilde elde edebilirsiniz. ve sistem çapındaki diğer ölçümlerle (örneğin uygulama sunucusundan, işletim sisteminden vb. elde edilen) yakından entegre olacak esnek bir izleme sistemi. Örneğin bu, InfluxDB + Grafana kombinasyonunu ve ayrıca erişilebilen sistem görünümlerine yönelik bir dizi sorguyu kullanan pgwatch2'de yapılır.
Toplam
Ve bu, normal SQL kodunu kullanarak veritabanımızla neler yapılabileceğinin yalnızca yaklaşık bir listesidir. Eminim daha birçok kullanım alanı bulabilirsiniz, yorumlara yazın. Ve tüm bunları nasıl (ve en önemlisi neden) otomatikleştireceğimizi ve bir dahaki sefere bunu CI/CD ardışık düzeninize nasıl dahil edebileceğinizi konuşacağız.
Kaynak: habr.com