Poprawnie – w relacyjnych bazach danych to właśnie ograniczenie UNIQUE zapewnia, że wartości w danej kolumnie nie będą się powtarzały. Technicznie rzecz biorąc, UNIQUE to constraint integralności, który wymusza unikalność danych w obrębie wskazanej kolumny lub zestawu kolumn. Jeżeli spróbujesz wstawić rekord z wartością, która już istnieje w tej kolumnie, silnik bazy (np. MySQL, PostgreSQL, SQL Server) zgłosi błąd naruszenia ograniczenia unikalności. Można to zobaczyć na prostym przykładzie: CREATE TABLE uzytkownicy ( id INT PRIMARY KEY, email VARCHAR(255) UNIQUE, login VARCHAR(50) UNIQUE ); Tutaj zarówno email, jak i login nie mogą się duplikować. W praktyce to jest standardowa dobra praktyka: na polach takich jak email, numer PESEL, NIP, numer indeksu, numer seryjny urządzenia czy nawet nazwa użytkownika bardzo często zakłada się UNIQUE, żeby w systemie nie pojawiły się dwa różne konta z tym samym identyfikatorem. Moim zdaniem, przy projektowaniu bazy danych warto od razu zastanowić się, które pola mają pełnić rolę „identyfikatorów biznesowych” i od razu nadać im ograniczenie UNIQUE. Warto też wiedzieć, że UNIQUE nie oznacza „klucz główny”. PRIMARY KEY automatycznie jest unikalny i nie może być NULL, natomiast UNIQUE pozwala na NULL (zależnie od silnika bazy, ale zazwyczaj wiele NULL-i jest dozwolonych). To pozwala projektować tabele bardziej elastycznie, np. kolumna może być opcjonalna, ale jeśli już ktoś poda wartość, to musi być ona niepowtarzalna. W praktyce UNIQUE często łączy się z indeksami – większość systemów bazodanowych automatycznie zakłada indeks unikalny na takiej kolumnie, co przyspiesza wyszukiwanie i walidację danych. To rozwiązanie jest zgodne z dobrymi praktykami normalizacji i kontroli spójności danych w systemach produkcyjnych.
W bazach danych bardzo łatwo pomylić różne typy ograniczeń, bo wszystkie „coś ograniczają”, ale robią to w zupełnie inny sposób. W tym pytaniu chodzi konkretnie o to, żeby wartości w kolumnie się nie powtarzały – czyli o klasyczną unikalność danych. Do tego służy constraint UNIQUE, który jest standardowym mechanizmem w SQL do wymuszania niepowtarzalnych wartości w obrębie danej kolumny lub kombinacji kolumn. Pojawia się czasem intuicja, że może istnieje coś takiego jak SINGLE albo NO REPEAT, bo nazwa brzmi sensownie po angielsku. W specyfikacji SQL i w popularnych systemach baz danych takie słowa kluczowe jednak po prostu nie występują jako constrainty. SINGLE i NO REPEAT nie są standardowymi ograniczeniami, więc żadna poważna baza danych ich nie zrozumie. To typowy błąd: kierowanie się „ładnie brzmiącą nazwą”, a nie faktycznymi słowami kluczowymi języka SQL. Z kolei NOT NULL jest jak najbardziej prawdziwym ograniczeniem, ale rozwiązuje zupełnie inny problem. NOT NULL mówi tylko tyle, że w danej kolumnie nie wolno przechowywać wartości pustych (NULL). Możesz mieć tabelę, w której kolumna ma NOT NULL i jednocześnie wiele identycznych wartości, np. same zera albo ten sam tekst w każdym wierszu – baza nie będzie protestować, bo nie zabrania powtórek, tylko zabrania braku wartości. To ograniczenie często łączy się z innymi, np. PRIMARY KEY czy UNIQUE, ale samo w sobie nie zapewnia żadnej unikalności. Z mojego doświadczenia przy projektowaniu schematów baz danych najczęstszy błąd myślowy wygląda tak: ktoś zakłada, że skoro pole nie może być puste (NOT NULL), to „jakoś przy okazji” jest traktowane specjalnie i może nawet unikalnie. Niestety tak to nie działa. Dopiero dodanie UNIQUE albo zdefiniowanie PRIMARY KEY wymusza, że dana wartość nie pojawi się drugi raz. Dlatego przy każdej kolumnie, która ma pełnić rolę identyfikatora biznesowego (np. email, numer dokumentu, NIP), trzeba świadomie dobrać właściwy constraint, a nie liczyć na samo NOT NULL czy jakieś „domyślne” zachowanie bazy.