Temat: Antywzorce programisty baz danych
To jest napisane z poziomu klepacza PL/SQL
Niektóre z poniższych błędów i ja sam popełniałem
1. No comments
BEGIN
....
.....
EXCEPTION
WHEN OTHERS THEN
COMMIT ;
END;
-----------------------------------------
2. Brak NVL w algorytmach obliczeniowych
DECLARE
a INTEGER;
b INTEGER :=1;
BEGIN
DBMS_OUTPUT.PUT_LINE(a + b);
END:
inna sprawa, że wg mnie pola używane do obliczeń powinny być DEFAULT 0 NOT NULL. Nawet jeśli się to przestrzega, warto wstawiać NVL dla świętego spokoju..
Nieznajomość faktu, że niektóre funkcje agregujące np AVG zadziałają inaczej dla wartości NULL i NOT NULL
SELECT AVG(pole_liczbowe) FROM tabela
zadziała inaczej
SELECT AVG( NVL(pole_liczbowe,0)) FROM tabela
jeśli pole liczbowe bedzie przyjmować wartości NULL
3 Nadużywanie DBMS_OUTPUT w pętlach po dużych tabelach
4. Warunek LENGTH( zmienna_tekstowa) =0 zamiast zmienna tekstowa IS NULL
5. Deklarowanie zmiennych odpowiadających polom w tabeli bez korzystania z zakotwiczeń %TYPE. Szczególnie ciekawym przypadkiem jest inna maksymalna długość VARCHAR2 w polu tabeli i jako zmienna w kodzie
6. W obrębie bazy deklarowanie tabel z polami VARCHAR2 ( size CHAR)i VARCHAR2( size BYTE)
7. Nadużywanie dynamicznego SQL - chociaż czasami bywa niezbędny
8. Nadawanie id rekordom w inny sposób niż przy użyciu sekwencji
9. Dokonywanie konwersji ze stringów na liczby i na daty bez podania masek - taki kod jest nieprzenośny zupełnie
10. Stosowanie zmiennych typu CHAR
11. Niepodawanie obiektom baz danych w kodzie PL/SQL nazw schematów. I to wszystkim bez wyjątku !!! Czasami w dużej bazie może pojawić się kilka tabel klienci w rożnych schematach i mamy pewne źródło problemów. Przy migracji i scalaniu baz podawanie ownerów mocno ułatwia życie... Dlatego też sądzę, że dla kluczowych tabel należy tworzyć publiczne synonimy coby mniej rozgarnięci userzy nie popełnili ich w swoich schematach...
12. Stosowanie hintów w zapytaniach.
SELECT /*+ INDEX( t idx_klienci_nazwa) */ from schemat.tbl_klienci t where t.nazwa = vc_Nazwa
Po mojemu hintów już od bazy 10g nie powinno się używać - wbudowany optymalizator radzi sobie z optymalizacją dobrze. Zaszycie hinta niesie za sobą niebezpieczeństwa związane z przebudową, usunięciem, rozszerzeniem indeksów, przeprowadzką rzadkich indeksów na bitmapowe przy migracji na enterprise, zmianą liczebności zbiorów danych i sposobem ich przechowywania( np.partycjonowanie tabel) - co może spowodować spory spadek wydajności... Lepiej jest więcej czasu poświęcić na rozpracowanie opornego zapytania niż umieszczać wskazówki w kodzie...
13. Pogrzebmy w bebechach
select UPPER(username), UPPER (osuser), UPPER (program), UPPER( machine)
into vc_UserName, vc_OSUser, vc_Program, vc_Machine
from v$session
where sid = USERENV('sid');
Staranie się, aby unikać odwołań do tabeli słownikowych, a jeśli się tego nie uda to takowe wywołania wsadzić do osobnego pakietu i korzystać tylko i wyłącznie z funkcji pakietowych... Tak samo w przypadku pakietów systemowych - wywołania należy opakować
14. Uprawnienia
grant SELECT, INSERT, DELETE, UPDATE on fk.tbl_faktury to PANI_BASIA;
grant SELECT on fk.tbl_faktury to PANI_JOLA.
Wszelakie uprawnienia do obiektów bazodanowych rozdzielać wyłącznie za pomocą ról, użytkownikom nie wolno nadawać ról bezpośrednio, to prowadzi do trudnego do opanowania chaosu w kodzie. Bywają czasami pojętni użytkownicy piszący własne procedury, dla nich można zrobić wyjątek, dla pozostałych lamerów nie
15 czytelność kodu
select * from schemat.klienci... Stosowanie standaryzowanych przedrostków (tbl_, vw_, seq_, mv_, pdb_, pckg_ ) do obiektów baz danych - aby w wypadku choroby genialnego kodera lub błędów runtime dało się cokolwiek zrozumieć, co genialny twórca miał na myśli
Kazik Szkaradnik edytował(a) ten post dnia 13.07.09 o godzinie 21:26