Jakie są dobre praktyki SQL? Co jest ważne, gdy zaczynasz pisać kod SQL?
Wyobraź sobie swoje pierwsze zapytanie zapytanie SQL albo pierwszy kod który ujrzy produkcyjne światło:
- Jako świeżo mianowany data engineer: Na potrzeby projektu data.
- Na potrzeby testowania i sprawdzania jakości danych.
- Na potrzeby analizy i przygotowywania wymagań dla nowych zmian.
Są niektóre dobre praktyki, na które warto zwrócić uwagę na początku. Poznanie ich pozwoli Ci pisać lepszy i bardziej odporny na zmiany kod. Będzie on też lepiej przystosowany do późniejszych zmian albo udostępnienia członkom zespołu.
- SELECT * - czy to na pewno dobry pomysł
- Aliasy - jak, kiedy dlaczego
Zaczynasz z SQL i chcesz przejść na kolejny poziom? Zapraszam na Next Level SQL - tam znajdziesz linki do filmów:
Next Level SQL
select * - czy to na pewno dobry pomysł?
Oczywiście, że tak jeżeli budujesz profil danych, analizujesz je. Albo chcesz na szybko sprawdzić jakie dane są w tabeli. Co się załadowało, jakie są kolumny, czy na pewno jest tam co powinno? Czy na pewno do kolumny PESEL jest wstawiany PESEL a nie NIP? itd
Szybkie, jednorazowe sprawdzenia to jest właśnie dobry schemat na select *
Ale jeżeli to jest zapytanie, które chcesz komuś pokazać?
Albo zapytanie, które będziesz chciał użyć w przyszłości?
A może masz do czynienia z kodem produkcyjnym?
Czy wtedy wybierałbyś wszystkie kolumny z tabeli właśnie w ten sposób?
Są pewnie przypadki, że odpowiedź brzmi tak.
Kiedy to zdecydowanie jest zły pomysł?
Wyobraź sobie, że stworzyłeś widok w hurtowni danych, który działa na produkcyjnym środowisku. Widok wygląda w ten sposób:
create or replace view v_f_financial_information as
select * from f_financial_information;
Z tego widoku czyta dane system księgowy. Po każdym przeładowaniu danych w hurtowni odświeżasz ten widok. Korzystając z jego definicji.
Co się stanie, gdy nazwy kolumn w widoku ulegną zmianie? Gdy nie poinformujesz systemu księgowego o zmianach wtedy narażasz się na incydenty z ich strony, eskalację u menagera i pogorszenie reputacji.
Jak to zrobić trochę lepiej.
Aliasy - podstawy
Słyszałeś zapewne o aliasach. Dla przypomnienia aliasy możesz nadawać tabelom, kolumną, żeby nadać inną nazwę.
Na przykład kolumnę:
OrderNumber możesz nazwać OrderSymbol
Albo tabelę
OrderDetails możesz nazwać ord_details
Nie zmieniasz przy tym tego jak ona się nazywa w bazie danych. Ta zmiana przeprowadzana jest tylko na potrzeby wykonania tego zapytania. Jest ulotna albo wirtualna.
Dobre praktyki SQL - aliasy
To jak aliasy pomagają rozwiązać problem, który masz opisany powyżej?
Zróbmy to krok po kroku, najpierw wypiszmy kolumny, z tabeli financial_information
select
financial_info_tk,
owner_fk,
responsible_unit_fk,
information_symbol,
information_date,
information_comment
from f_financial_information;
Jak na razie widzisz bez aliasów, zacznijmy od aliasów dla kolumn
select
financial_info_tk as financial_info_tk,
owner_fk as owner_fk,
responsible_unit_fk as responsible_unit_fk,
information_symbol as information_symbol,
information_date as information_date,
information_comment as information_comment
from f_financial_information;
Teraz dodajmy jeszcze alias do tabeli.
select
fi.financial_info_tk as financial_info_tk,
fi.owner_fk as owner_fk,
fi.responsible_unit_fk as responsible_unit_fk,
fi.information_symbol as information_symbol,
fi.information_date as information_date,
fi.information_comment as information_comment
from f_financial_information fi;
To jest kod, z którego możesz być dumny!
To jest kod odporny na zmianę: gdy usuwasz lub zmieniasz nazwy kolumn, albo jest potrzeba dołączenia do zapytania jeszcze jednej tabeli.
Dobre praktyki SQL - odporność na zmianę
Rozwinę jeden argument za tym, żeby używać aliasów:
Wyobraź sobie do tego zapytania masz dołączyć jeszcze jedną tabelę. Wtedy jesteś przygotowany na to, żeby "pokazać" jakie jest źródło kolumny. Czyli z jakiej tabeli jest pobierana dana kolumna.
Taki kod jest nieakceptowalny, nie widać z jakiej tabeli pochodzą kolumny. Możesz tylko zgadywać:
select
financial_info_tk as financial_info_tk,
fi.owner_fk as owner_fk,
owner_name,
responsible_unit_fk as responsible_unit_fk,
information_symbol as information_symbol,
information_date as information_date,
information_comment as information_comment
from f_financial_information fi
Inner join d_owner ow on (fi.owner_fk = ow.owner_fk);
To jest oczekiwany, produkcyjny kod:
select
fi.financial_info_tk as financial_info_tk,
fi.owner_fk as owner_fk,
ow.owner_name as owner_name,
fi.responsible_unit_fk as responsible_unit_fk,
fi.information_symbol as information_symbol,
fi.information_date as information_date,
fi.information_comment as information_comment
from f_financial_information fi
Inner join d_owner ow on (fi.owner_fk = ow.owner_fk);
Widać źródło dla każdej kolumny, łatwo taki kod utrzymywać i dodawać kolejne tabele. Inni członkowie zespołu będą dumni z tego, że dostarczyłeś takie dzieło sztuki, zresztą gdybyś wrócił do tego zapytania też będzie Ci łatwiej z nim pracować.
Ps. Dbeaver ma taką super opcje, która rozszywa Ci alias_tabeli.* na nazwy kolumn. Wystarczy nacisnąć CTRL+SPACJA 😀