200 satır uzunluğunda fonksiyonlara sahip bir uygulama yazmazsınız. Bu uzun işlevleri, her biri açıkça tanımlanmış tek bir sorumluluğa sahip olan daha küçük işlevlere ayırırsınız.
SQL'inizi neden böyle yazasınız?
Tıpkı işlevlerinizi ayrıştırdığınız gibi sorgularınızı ayrıştırın. Bu, onları daha kısa, daha basit, anlaşılması daha kolay, test etmesi daha kolay, yeniden düzenlemesi daha kolay hale getirir . Ve tıpkı prosedür kodunda yaptığınız gibi, aralarına "şim" ve etraflarına "sarmalayıcılar" eklemenize izin verir.
Bunu nasıl yapıyorsun? Bir sorgunun yaptığı her önemli şeyi bir görünümde yaparak Sonra oluşturmak daha ilkel fonksiyonların dışında daha karmaşık işlevleri oluşturmak gibi, bu basit görüşlerin daha karmaşık sorgular.
Ve harika olan şey, çoğu görünüm kompozisyonu için , RDBMS'nizden tamamen aynı performansı alacaksınız. (Bazıları için yapmayacaksınız; öyleyse ne? Erken optimizasyon tüm kötülüklerin köküdür. Önce doğru kodlayın, sonra gerekirse optimize edin.)
Aşağıda, karmaşık bir sorguyu ayrıştırmak için çeşitli görünümlerin kullanımına bir örnek verilmiştir.
Örnekte, her görünüm yalnızca bir dönüşüm eklediğinden, her biri hataları bulmak için bağımsız olarak test edilebilir ve testler basittir.
Örnekteki temel tablo şu şekildedir:
create table month_value(
eid int not null, month int, year int, value int );
Bu tablo kusurludur, çünkü bir veriyi, mutlak bir ayı temsil etmek için ay ve yıl olmak üzere iki sütun kullanır. Yeni, hesaplanmış sütun için spesifikasyonumuz şu şekildedir:
Bunu doğrusal bir dönüşüm olarak yapacağız, öyle ki (yıl, ay) ile aynı sıralanıyor ve öyle ki herhangi bir (yıl, ay) demet için tek bir değer var ve tüm değerler ardışık:
create view cm_absolute_month as
select *, year * 12 + month as absolute_month from month_value;
Şimdi test etmemiz gereken şey bizim spesifikasyonumuzun doğasında var, yani herhangi bir demet (yıl, ay) için bir ve sadece bir (mutlak_ay) vardır ve bu (mutlak_ay) ların ardışık olmasıdır. Bazı testler yazalım.
select
Testimiz, aşağıdaki yapıya sahip bir SQL sorgusu olacaktır : bir test adı ve bir araya getirilmiş bir durum ifadesi. Test adı sadece rastgele bir dizedir. Case ifadesi sadece case when
test ifadeleridir then 'passed' else 'failed' end
.
Test ifadeleri, testin geçmesi için doğru olması gereken SQL seçimleri (alt sorgular) olacaktır.
İşte ilk testimiz:
--a select statement that catenates the test name and the case statement
select concat(
-- the test name
'For every (year, month) there is one and only one (absolute_month): ',
-- the case statement
case when
-- one or more subqueries
-- in this case, an expected value and an actual value
-- that must be equal for the test to pass
( select count(distinct year, month) from month_value)
--expected value,
= ( select count(distinct absolute_month) from cm_absolute_month)
-- actual value
-- the then and else branches of the case statement
then 'passed' else 'failed' end
-- close the concat function and terminate the query
);
-- test result.
Bu sorguyu çalıştırmak şu sonucu verir: For every (year, month) there is one and only one (absolute_month): passed
Month_value içinde yeterli test verisi olduğu sürece bu test çalışır.
Yeterli test verileri için bir test de ekleyebiliriz:
select concat( 'Sufficient and sufficiently varied month_value test data: ',
case when
( select count(distinct year, month) from month_value) > 10
and ( select count(distinct year) from month_value) > 3
and ... more tests
then 'passed' else 'failed' end );
Şimdi ardışık olduğunu test edelim:
select concat( '(absolute_month)s are consecutive: ',
case when ( select count(*) from cm_absolute_month a join cm_absolute_month b
on ( (a.month + 1 = b.month and a.year = b.year)
or (a.month = 12 and b.month = 1 and a.year + 1 = b.year) )
where a.absolute_month + 1 <> b.absolute_month ) = 0
then 'passed' else 'failed' end );
Şimdi sadece sorgular olan testlerimizi bir dosyaya koyalım ve o betiği veritabanında çalıştıralım. Nitekim, görünüm tanımlarımızı bir komut dosyasında (veya komut dosyalarında, ilgili görünüm başına bir dosya) veritabanına karşı çalıştıracak şekilde depolarsak, her görünüm için testlerimizi aynı komut dosyasına ekleyebiliriz , böylece (re -) görünümümüzü oluşturmak, görünümün testlerini de çalıştırır. Bu şekilde, görünümleri yeniden oluşturduğumuzda ikimiz de regresyon testleri alırız ve görünüm oluşturma, üretime karşı çalıştığında, görünüm de üretimde test edilir.