Martwi mnie to od dłuższego czasu. W większości przypadków, gdy chodzi o przechowywanie danych w strukturach takich jak tabele, programiści, książki i artykuły, nalega, aby indeksowanie elementów w tych strukturach według wartości ciągu było uważane za złą praktykę. Jednak jak dotąd nie znalazłem żadnego takiego źródła, które wyjaśniałoby również DLACZEGO uważa się to za złą praktykę. Czy to zależy od języka programowania? Na podstawowych zasadach? W sprawie wdrożenia?
Weź dwa proste przykłady, jeśli to pomoże:
Tabela podobna do SQL, w której wiersze są indeksowane kluczem podstawowym String.
Słownik .NET, w którym kluczami są ciągi znaków.
username
ponieważ klucz podstawowyusers
tabeli prawdopodobnie nie jest najlepszym pomysłem i wolisz identyfikator automatycznego przyrostu. Ale tenusername
ciąg jest przypadkowy, ponieważOdpowiedzi:
Wszystko to ma zasadniczo związek z dwiema rzeczami:
1) Szybkość wyszukiwania (na przykład liczby całkowite są znacznie lepsze)
2) Rozmiar indeksów (gdzie wybuchłyby indeksy łańcuchowe)
Teraz wszystko zależy od twoich potrzeb i wielkości zbioru danych. Jeśli tabela lub kolekcja zawiera 10-20 elementów, typ klucza nie ma znaczenia. Będzie bardzo szybki, nawet z kluczem ciągowym.
PS Może nie być związane z twoim pytaniem, ale Guids są również uważane za złe dla kluczy bazy danych (16 bajtów Guid vs. 4 bajty całkowite). W przypadku dużych ilości danych prowadnice spowalniają wyszukiwanie.
źródło
Jest jeszcze jeden problem z używaniem ciągów jako kluczy, a ściślej - z użyciem literałów ciągów jako kluczy, pomijając czystą wydajność / wydajność. Literówki. Jeśli użyjesz literałów łańcuchowych jako kluczy w słowniku, przygotujesz się na nieprzyjemną niespodziankę, gdy
"ReceiverId"
zostaniesz"RecieverId"
. Skonfiguruj stałe do przechowywania kluczowych wartości i użyj ich ponownie przy każdym dostępie do słownika.Trywialne i oczywiste, można powiedzieć, ale oszałamiająca liczba przykładów kodu .NET w sieci używa literałów łańcuchowych, propagując tę wątpliwą praktykę. Szczególnie winny jest program ASP.NET ze wszystkimi sesjami, ViewStates i QueryParams rozmieszczonymi w całej bazie kodu.
źródło
"1"
i"1 "
w tej samej tabeli.Jest tu wiele kompromisów. Właściwie często używam kluczy łańcuchowych, ale często dołączam zastępcze klucze zastępcze dla złączeń (oczywiście byłoby odwrotnie, gdybym używał MySQL). Są jednak przypadki, w których ja tego nie robię.
Po pierwsze jestem fanem deklarowania kluczy naturalnych jako klucza podstawowego, gdzie db może sobie z tym poradzić (na przykład PostgreSQL). Pomaga to w normalizacji i zapewnia bardziej przejrzysty projekt bazy danych. Klawisze zastępcze ułatwiają łączenie.
Są dwa powody, dla których zwykle dodam klucze zastępcze:
Nie zawsze jest jasne, czym jest naturalny klucz. Czasami trzeba je zmienić. Zmiana naturalnego, złożonego klucza, gdy jest on używany do łączenia i integralności referencyjnej, jest skomplikowana i podatna na błędy.
Łączenie wydajności na klawiszach kompozytowych jest problematyczne i kiedy pójdziesz naturalną trasą klucza, utkniesz tam.
Jednak w przypadkach, gdy klucz naturalny jest definicją, pojedynczą kolumną i tekstem, zwykle dołączam klucz ciągowy. Moim powodem jest to, że często unika się łączenia podczas wyszukiwania. Najczęstszym zastosowaniem jest zapewnienie odpowiedniego projektu db wokół przypadku użycia typów wyliczeniowych. W większości przypadków nie wymagają one dodatkowego łączenia w przypadku rutynowych zapytań. W takim przypadku klucze łańcuchowe jako klawisze łączenia mają więc sens.
Na przykład w LedgerSMB przechowujemy kategoryzacje kont. Są one identyfikowane przez odwołanie do ciągu. A niektóre inne dane są przechowywane z odwołaniem do ciągu, który służy do egzekwowania reguł dotyczących kombinacji kategoryzacji, które mogą mieć wpływ na konto. Logika jest potrzebna tylko przy zapisywaniu zestawu kategoryzacji, więc dołączamy do klucza ciąg.
Jeśli chodzi o to, dlaczego domyślnie byłyby to klucze całkowite, nie sądzę, że to tylko kwestia rozmiaru indeksu. Dużym problemem jest zarządzanie kluczami. Ponieważ klucz jest dowolny i możesz mieć do czynienia z milionami rekordów, musisz mieć sposób na generowanie unikatowych ciągów. Są przypadki, w których ludzie używają do tego UUID, ale istnieje niezerowa szansa na kolizję UUID, a gdzie przechowywane są miliardy rekordów, szansa ta staje się wystarczająco wysoka, którą można rzeczywiście zobaczyć, podczas gdy szansa na kolizję z przyrostowymi typami liczb całkowitych wynosi zero zgodnie z definicją.
źródło
Istnieje wiele potencjalnych problemów z używaniem ciągów jako kluczy, szczególnie jeśli chodzi o tabele podobne do sql. Jak wspomniano przez @bunny, indeksy dla twoich tabel będą większe, ale myślę, że co ważniejsze, wszelkie relacje kluczy obcych do tabeli będą obejmowały OBA tabele zawierające łańcuch w przeciwieństwie do identyfikatora lżejszej (całkowitej) . Jeśli okaże się, że istnieje jeszcze więcej tabel z odniesieniami do pierwszej, klucze ciągów zostaną rozpowszechnione w całej bazie danych.
źródło
Sam w sobie nie jest złym pomysłem, zwykle z perspektywy 20/20 to zły kompromis projektowy. Elastyczność i zakres sznurka w porównaniu do dodatkowych kosztów i złożoności.
Jeśli liczba całkowita odpowiada zakresowi zadań, a większość kosztownego przetwarzania nie musi wiedzieć, co reprezentuje liczba całkowita, użyj jednego.
źródło
W jakiś sposób odzyskałeś nieprawidłowe dane z Hashtable.
Miałeś na myśli „DaytimeTelefon” lub „EveningTelefon”?
lub
Miałeś na myśli 1234567 lub 1234576?
Chociaż liczby są prawdopodobnie bardziej wydajne dla maszyny , za każdym razem, gdy coś pójdzie nie tak (i tak się dzieje), to do ciebie i mnie należy zrozumienie, co się stało, i w tym momencie oszczędność kilku bajtów pamięci i kilka mikro (nano?) sekund za każdym razem traci wyrazistość .
źródło
Wiele kompromisów i nie ma jednej właściwej odpowiedzi. Wielu programistów nigdy nie rozważyłoby użycia kluczy łańcuchowych w bazie danych, ponieważ nie są świadomi haszowania i działania bazy danych. Klucze ciągów, o ile są albo wyjątkowo stabilne, albo pozbawione znaczenia (zastępcze), są dobrym wyborem w wielu przypadkach.
źródło
klucz łańcucha ma sens, jeśli chodzi o tabelę wyszukiwania zawierającą około 10-100 krótkich rekordów łańcucha; powiązane dane są bardziej czytelne + np. śledzenie zmian (numeryczny / identyfikator GUID vs. ciąg np. „Administrator”); btw, baza danych członkostwa ASP.NET używa kluczy ciągów dla AspNetRoles.
źródło