Porządek
Ostatnią z rzeczy, których powinniśmy się dowiedzieć o bazach danych, jest zrozumienie w jaki sposób bazy danych pomagają utrzymać porządek w danych.
Popatrzmy na naszą tabelę z osobami.
SELECT * FROM osoby ; login | imie | nazwisko | mail -------+------------------+-------------+------------------------ a | Adam | Kowalski | adam.kowalski@mail.pl b | Basia | Nowak | basia.nowak@mail.pl f | :) | nasza-klasa | tralalala d | Ewa | Piątek | Basia na belwederskiej d | Basia | Piątek | Ewa na belwederskiej c | cYPRIAN | pan | cyprian.pl e | A TO mój znajomy | Wtorek | (7 rows)
Jakie widzimy problemy?
• Są dwie osoby z tym samym loginem
• Niektóre imiona wyraźnie nie są imionami
• Podobnie nazwiska
• Maile nie są poprawnymi adresami
• Nie wszyscy mają wprowadzone maile
Spróbujmy sobie poradzić z tymi problemami.
Na czym polega problem z dwoma osobami o tym samym loginie? Ano na tym, że nie wiadomo jaka jest odpowiedź na pytanie kto ma login d. Chcielibyśmy, żeby ten login jednoznacznie identyfikował osobę. W bazach danych kolumna bądź kolumny jednoznacznie identyfikujące wiersz nazywa się kluczem głównym. Takim kluczem w naszej tabeli jest kolumna login. Dodajmy zatem klucz do tabeli. Robi się to za pomocą:
ALTER TABLE osoby ADD PRIMARY KEY(login); -- NOTICE: ALTER TABLE / ADD PRIMARY KEY will create implicit index "osoby_pkey" for table "osoby" -- ERROR: could not create unique index "osoby_pkey" -- DETAIL: Table contains duplicated values.
System napisał, że nie może dodać klucza na kolumnie (login), gdyż tabela zawiera duplikaty. To prawda, usuńmy zatem Ewę Piątek i spróbujmy jeszcze raz.
DELETE FROM osoby WHERE imie = 'Ewa' AND nazwisko = 'Piątek'; -- DELETE 1 ALTER TABLE osoby ADD PRIMARY KEY(login); -- NOTICE: ALTER TABLE / ADD PRIMARY KEY will create implicit index "osoby_pkey" for table "osoby" -- ALTER TABLE
Tym razem się udało. Sprawdźmy czy klucz zadział.
INSERT INTO osoby VALUES('a'); -- ERROR: duplicate key value violates unique constraint "osoby_pkey" INSERT INTO osoby VALUES('g'); -- INSERT 0 1
Zadziałał! Nie udało się wprowadzić osoby o loginie 'a', natomiast udało się wprowadzić osobę o loginie 'g'.
No ale mamy inny problem. Mianowicie nie wszystkie pola w bazie są wypełnione. Jeśli pole nie jest wypełnione to ma ono specjalną wartość NULL. Chcielibyśmy, żeby wszystkie pola były wypełnione. Aby kolumna login nigdy nie była pusta, używamy następującej konstrukcji:
ALTER TABLE osoby ALTER COLUMN login SET NOT NULL; -- ALTER TABLE
Spróbujmy zrobić podobną operację z innymi kolumnami.
ALTER TABLE osoby ALTER COLUMN imie SET NOT NULL; -- ERROR: column "imie" contains null values
Nie udało się, dlaczego? Bo kolumna imie zawiera puste wartości. Poprawmy to:
UPDATE osoby SET imie = 'Imie' WHERE imie IS NULL; -- UPDATE 1 ALTER TABLE osoby ALTER COLUMN imie SET NOT NULL; -- ALTER TABLE
Czy wszystko na pewno zadziałało. Spróbujmy wstawić do tabeli wiersz bez wypełnionego pola imie.
INSERT INTO osoby VALUES('h'); ERROR: NULL value IN COLUMN "imie" violates not-NULL constraint
Zadziałało! Nie można wstawić wiersza bez wypełnionego imienia.
Bazy danych pozwalają na tworzenie dużo ciekawszych warunków poprawności. Przykładowo instrukcja
ALTER TABLE osoby ADD CHECK (imie SIMILAR TO '[A-Z][a-z]*');
sprawdza czy wszystkie imiona mają poprawną postać, czyli składają się z małych liter poprzedzonych wielką.