Podczas tworzenia tabeli produkty należy utworzyć pole cena będące reprezentacją ceny produktu. Odpowiedni typ dla tego pola to
A. TINYTEXT
B. ENUM
C. INTEGER(11)
D. DECIMAL(10, 2)
Pytanie z egzaminu CKE, czerwiec 2022 (arkusz EE.09-SG-22.06).
Typ DECIMAL(10, 2) jest właściwym wyborem dla pola cena, bo przechowuje liczby dziesiętne w sposób dokładny, a nie przybliżony. W bazach takich jak MySQL zapis DECIMAL(10, 2) oznacza, że wartość może mieć łącznie do 10 cyfr, z czego 2 cyfry są po przecinku. Czyli spokojnie zapiszesz np. 19.99, 1250.50 albo 99999999.99, zależnie od potrzeb sklepu. To jest bardzo ważne przy pieniądzach, bo ceny nie powinny się „rozjeżdżać” przez błędy zaokrągleń. Z mojego doświadczenia najlepiej unikać typów zmiennoprzecinkowych typu FLOAT czy DOUBLE dla kwot, bo one są dobre do obliczeń naukowych, ale nie do finansów. W praktycznej aplikacji sklepu internetowego pole cena mogłoby wyglądać np. cena DECIMAL(10, 2) NOT NULL. Często dodaje się też ograniczenie, żeby cena nie była ujemna, np. CHECK (cena >= 0), jeżeli silnik bazy to obsługuje. To jest zgodne z dobrymi praktykami projektowania baz danych: dane liczbowe przechowujemy jako liczby, a wartości finansowe jako typ stałoprzecinkowy, czyli właśnie DECIMAL.
Przy wyborze typu danych dla ceny produktu trzeba myśleć nie tylko o tym, że cena wygląda jak liczba, ale też o tym, że jest to wartość finansowa. Takie dane powinny być przechowywane precyzyjnie, z określoną liczbą miejsc po przecinku. Dlatego najlepszym wyborem jest DECIMAL(10, 2), a nie typy tekstowe czy ogólne typy całkowite.
INTEGER(11) może wydawać się kuszący, bo cena to przecież liczba. Problem w tym, że typ całkowity nie zapisze części groszowej, czyli np. 12.99. Dałoby się oczywiście przechowywać cenę w groszach, np. 1299 zamiast 12.99, ale wtedy trzeba bardzo konsekwentnie obsługiwać przeliczanie w całej aplikacji. W pytaniu chodzi o zwykłe pole cena reprezentujące cenę produktu, więc typ dziesiętny jest bardziej naturalny. Warto też wiedzieć, że w MySQL zapis INTEGER(11) nie oznacza zakresu do 11 cyfr w takim prostym sensie; dawniej dotyczył głównie szerokości wyświetlania, a obecnie to podejście jest raczej przestarzałe.
TINYTEXT jest typem znakowym, więc nadaje się do krótkich opisów, komentarzy albo nazw, ale nie do ceny. Gdy cena jest tekstem, baza nie traktuje jej jak liczby: sortowanie, porównywanie i obliczenia mogą dawać dziwne efekty. Na przykład tekstowe 100 może zostać potraktowane inaczej niż 20 przy sortowaniu alfabetycznym, no i sumowanie wartości robi się niepotrzebnie kłopotliwe.
ENUM służy do przechowywania jednej wartości z ustalonego zestawu, np. status produktu może mieć wartości dostępny, wycofany, promocja. Cena nie jest zamkniętą listą kilku etykiet, tylko zmienną wartością liczbową. Typowym błędem jest wybieranie typu po tym, jak dane „wyglądają” na ekranie, zamiast po tym, jakie operacje będzie się na nich wykonywać. A na cenach zwykle liczy się rabaty, sumy zamówień, podatki i porównania, więc baza powinna dostać typ liczbowy stałoprzecinkowy.
INTEGER(11) może wydawać się kuszący, bo cena to przecież liczba. Problem w tym, że typ całkowity nie zapisze części groszowej, czyli np. 12.99. Dałoby się oczywiście przechowywać cenę w groszach, np. 1299 zamiast 12.99, ale wtedy trzeba bardzo konsekwentnie obsługiwać przeliczanie w całej aplikacji. W pytaniu chodzi o zwykłe pole cena reprezentujące cenę produktu, więc typ dziesiętny jest bardziej naturalny. Warto też wiedzieć, że w MySQL zapis INTEGER(11) nie oznacza zakresu do 11 cyfr w takim prostym sensie; dawniej dotyczył głównie szerokości wyświetlania, a obecnie to podejście jest raczej przestarzałe.
TINYTEXT jest typem znakowym, więc nadaje się do krótkich opisów, komentarzy albo nazw, ale nie do ceny. Gdy cena jest tekstem, baza nie traktuje jej jak liczby: sortowanie, porównywanie i obliczenia mogą dawać dziwne efekty. Na przykład tekstowe 100 może zostać potraktowane inaczej niż 20 przy sortowaniu alfabetycznym, no i sumowanie wartości robi się niepotrzebnie kłopotliwe.
ENUM służy do przechowywania jednej wartości z ustalonego zestawu, np. status produktu może mieć wartości dostępny, wycofany, promocja. Cena nie jest zamkniętą listą kilku etykiet, tylko zmienną wartością liczbową. Typowym błędem jest wybieranie typu po tym, jak dane „wyglądają” na ekranie, zamiast po tym, jakie operacje będzie się na nich wykonywać. A na cenach zwykle liczy się rabaty, sumy zamówień, podatki i porównania, więc baza powinna dostać typ liczbowy stałoprzecinkowy.