Adres e-mail unikalny czy klucz podstawowy?

11

Jestem nowicjuszem w bazach danych. Przeczytałem i przekonałem się, że prawdopodobnie nie jest dobrym pomysłem używanie adresu e-mail jako klucza podstawowego, ponieważ porównania ciągów są wolniejsze, co wpływa na wydajność w złożonych sprzężeniach, a jeśli e-mail się zmieni, musiałbym zmienić wszystkie klucze obce, co wymaga dużo wysiłku.

Ale jeśli moja tabela użytkowników wymaga, aby każdy użytkownik miał adres e-mail i każdy z tych adresów powinien być unikalny, czy dodanie unikalnego indeksu w kolumnie e-mail wystarczy? Ponieważ unikalne pola afaik dopuszczają wartości zerowe, podczas gdy wymagam od każdego użytkownika adresu e-mail, nie dopuszczając wartości zerowych. Czy czegoś tu brakuje? Czy też przypuszczam, aby kolumna e-mail była unikalna i upewnić się, że podczas sprawdzania poprawności danych na serwerze użytkownik wprowadzi adres e-mail, aby każdy użytkownik go miał?

aandis
źródło
3
Co się stanie, gdy użytkownik zmieni swój adres e-mail - podobnie jak np.
Zmieni
1
Porównywanie ciągów jest nie tylko wolniejsze, ale również ciągi są większe niż powiedzmy liczba całkowita, a zatem można zmieścić mniej na stronie w pamięci, zwiększając logiczne odczyty dla zapytań.
Bezimienny,

Odpowiedzi:

7

Najpierw rozróżnijmy klucze i indeksy, klucz jest częścią modelu logicznego i często jest implementowany z unikalnym indeksem. Można jednak utworzyć unikalny indeks bez tworzenia klucza, ale klucz obcy nie może do niego odwoływać.

Klucz kandydujący to coś, co jednoznacznie identyfikuje wiersz w tabeli, w SQL jeden z kluczy kandydujących jest zwykle używany jako klucz podstawowy (nigdy tak naprawdę nie rozumiałem, dlaczego jedno z ck jest „lepsze” od innych, ale to inny historia), a pozostałe ck staje się wyjątkowymi ograniczeniami.

Unikalne ograniczenie może być używane w taki sam sposób, jak klucz podstawowy. Rozważać:

create table A ( x ... not null
               , y ... not null
               , z ... not null
               ,     unique (x)
               ,     primary key (y,z) );

create table B ( x ...
               ,   ...
               ,     foreign key (x) references A (x) );

create table C ( y ...
               , z ...
               ,   ...
               ,     foreign key (y, z) references A (y, z) );  

B odwołuje się do ograniczenia unikalnego, a C odwołuje się do ograniczenia klucza podstawowego.

NOT NULL to kolejny rodzaj ograniczenia. W twoim przypadku możesz wymusić to dla e-maila, nie uznając go za wyjątkowy.

Kolejny aspekt twojego postu dotyczy stabilności klucza, klucz powinien być stabilny (ale to nie znaczy, że nigdy się nie zmieni, nie musi być niezmienny). Niektóre DBMS implementują NA AKTUALIZACJĘ KASKADY, które mogą być pomocne w takich operacjach, ale jeśli klucz zostanie rozprowadzony wokół twojego modelu, będzie to uciążliwe podczas jego aktualizacji.

W twoim przypadku prawdopodobnie wybrałbym inny klucz kandydujący jako klucz podstawowy i zadeklaruję adres e-mail jako NIE NULL i UNIKALNY.

Lennart
źródło
1
W SQL Server można odwoływać się do unikalnego indeksu jako FK.
Martin Smith
1
Nie mam dostępu do sql, więc nie mogę sam sprawdzić, czy to pośrednio tworzy unikalne ograniczenie podczas tworzenia unikalnego indeksu?
Lennart
1
Nie. Unikalne ograniczenie jest traktowane nieco inaczej i ma pewne dodatkowe metadane i dodatkowe ograniczenia w porównaniu z unikalnym indeksem, ale SQL Server pozwala na użycie obu w FK.
Martin Smith
1
To trochę dziwne, indeksy nie są nawet wspomniane w standardzie SQL, podczas gdy klucze są jego centralną częścią. W każdym razie dzięki za informację.
Lennart
Warto zauważyć, że jeśli istnieje wiele zapisów zapisanych w obcych kluczach do wiadomości e-mail, aktualizacja wszystkich tych rekordów może zająć sporo czasu, gdy aktualizacja zostanie przeprowadzona kaskadowo.
cimmanon
6

Tak, posiadanie unikalnego indeksu w kolumnie EmailAddress powinno być w porządku. Jedynym problemem byłoby, gdyby ktoś zrezygnował z adresu e-mail po zarejestrowaniu się w usłudze, ale ci nie powiedział, to ktokolwiek właściciel adresu e-mail spróbuje się zarejestrować. Ale to dość rzadki przypadek.

Co do tego, czy Unikalny Indeks dopuszcza wartości zerowe, które będą zależeć od platformy bazy danych. Oracle robi, SQL Server pozwala na pojedynczą wartość NULL. Możesz rozwiązać ten problem, powodując, że kolumna nie zezwala na wartości NULL, a następnie budując na niej unikalny indeks.

mrdenny
źródło
1
Nie dotyczy to serwera SQL. Możesz tworzyć indeksy z whereklauzulami, które pozwalają na przykład wykluczyć NULLwartości z indeksu.
Kirk Woll
1
Oświadczenie SQL Server allows a single NULL valuejest nadal prawdziwe. Nie oznacza to, że nie można uzyskać wielu NULLwartości. Myślę, że osoba udzielająca odpowiedzi starała się zachować prostotę odpowiedzi i nie wyjaśniać dodatkowych szczegółów (takich jak filtrowane indeksowanie).
Brandon
1
Tak, mogłem zanurkować królikowi w całości przefiltrowanych indeksów, ale proste pytanie zwykle wymaga prostej odpowiedzi. Bez platformy i wersji bazy danych moje odpowiedzi są ogólne.
mrdenny
2

Posiadanie unikalnego indeksu na EmailAddress jest w porządku.

Jak już powiedziałeś, że we wniosku znajduje się potwierdzenie poprawności adresu e-mail jako wymaganego, powiedziałbym, że ponieważ inna weryfikacja pochodziłaby z bazy danych, nie akceptuje ona użytkownika bez adresu e-mail i zapobiega również dwukrotnemu wprowadzeniu, a te sprawdzenie zostaną nałożone za pomocą tego unikalnego indeksu.

Jak stwierdzono w innej odpowiedzi dla programu SQL Server, należy utworzyć kolumnę, aby nie dopuszczała wartości zerowej przed budowaniem unikalnych indeksów.

vijayp
źródło