Jaka jest dobra struktura danych do przechowywania numerów telefonów w polach bazy danych? Szukam czegoś, co jest wystarczająco elastyczne, aby obsługiwać numery międzynarodowe, a także czegoś, co umożliwia wydajne przeszukiwanie różnych części numeru.
Edycja: aby wyjaśnić tutaj przypadek użycia: obecnie przechowuję liczby w jednym polu varchar i zostawiam je tak, jak wprowadził je klient. Następnie, gdy numer jest potrzebny przez kod, normalizuję go. Problem polega na tym, że jeśli chcę przeszukać kilka milionów wierszy, aby znaleźć pasujące numery telefonów, obejmuje to funkcję, taką jak
where dbo.f_normalizenum(num1) = dbo.f_normalizenum(num2)
co jest strasznie nieefektywne. Również zapytania, które szukają rzeczy, takich jak numer kierunkowy, stają się niezwykle trudne, gdy jest to tylko jedno pole varchar.
[Edytować]
Ludzie podali tutaj wiele dobrych sugestii, dzięki! Jako aktualizacja, oto, co teraz robię: nadal przechowuję liczby dokładnie tak, jak zostały wprowadzone, w polu varchar, ale zamiast normalizować rzeczy w czasie zapytania, mam wyzwalacz, który działa, gdy rekordy są wstawiane lub zaktualizowany. Mam więc ints lub biginty dla wszystkich części, które muszę zapytać, a te pola są indeksowane, aby zapytania działały szybciej.
Odpowiedzi:
Po pierwsze, poza kodem kraju nie ma prawdziwego standardu. Najlepsze, co możesz zrobić, to rozpoznać po kodzie kraju, do którego kraju należy dany numer telefonu, i zająć się resztą numeru zgodnie z formatem tego kraju.
Generalnie jednak sprzęt telefoniczny i taki jest znormalizowany, więc prawie zawsze można podzielić dany numer telefonu na następujące elementy
Dzięki tej metodzie możesz potencjalnie oddzielić numery, na przykład znaleźć osoby, które mogą być blisko siebie, ponieważ mają ten sam kraj, obszar i kod wymiany. Z telefonami komórkowymi nie można już na to liczyć.
Ponadto w każdym kraju obowiązują różne standardy. Zawsze możesz polegać na (AAA) EEE-LLLL w USA, ale w innym kraju możesz mieć wymiany w miastach (AAA) EE-LLL i po prostu numery linii na obszarach wiejskich (AAA) LLLL. Będziesz musiał zacząć od góry w drzewie w jakiejś formie i sformatować je tak, jak masz informacje. Na przykład kod kraju 0 ma znany format reszty numeru, ale w przypadku kodu kraju 5432 może być konieczne sprawdzenie numeru kierunkowego, zanim zrozumiesz pozostałą część numeru.
Możesz także sobie poradzić
vanity
liczby, takie jak(800) Lucky-Guy
, co wymaga uznania, że jeśli jest to numer w USA, jest o jedną za dużo cyfr (i może być konieczne pełne przedstawienie do celów reklamowych lub innych) oraz że w Stanach Zjednoczonych litery są odwzorowywane na numery inaczej niż w Niemczech.Możesz również zapisać cały numer osobno jako pole tekstowe (z internacjonalizacją), aby móc wrócić później i ponownie przeanalizować liczby, gdy sytuacja się zmieni, lub jako kopię zapasową na wypadek, gdyby ktoś przesłał złą metodę analizy formatu określonego kraju i traci informacje.
źródło
KISS - Mam dość wielu amerykańskich witryn internetowych. Mają sprytnie napisany kod do weryfikacji kodów pocztowych i numerów telefonów. Kiedy wpisuję moje doskonale prawidłowe norweskie dane kontaktowe, okazuje się, że dość często są one odrzucane.
Pozostaw to jako ciąg znaków, chyba że potrzebujesz czegoś bardziej zaawansowanego.
źródło
nvarchar(42)
z odrobiną walidacji/^+?[0-9 -\.\(\)#*]{4,41}$/
działa bardzo dobrze!Strona Wikipedii pod adresem E.164 powinna zawierać wszystko, co musisz wiedzieć.
źródło
Oto moja proponowana struktura, byłbym wdzięczny za opinie:
Pole bazy danych telefonów powinno mieć postać varchar (42) o następującym formacie:
Kod kraju - numer x rozszerzenie
Na przykład w USA moglibyśmy mieć:
1-2125551234x1234
Oznaczałoby to numer amerykański (kod kraju 1) z numerem kierunkowym / numerem (212) 555 1234 i numerem wewnętrznym 1234.
Oddzielenie kodu kraju myślnikiem sprawia, że kod kraju jest jasny dla kogoś, kto przegląda dane. Nie jest to absolutnie konieczne, ponieważ kody krajów są „ kodami prefiksowymi ” (można je czytać od lewej do prawej i zawsze można jednoznacznie określić kraj). Ponieważ jednak kody krajów mają różną długość (w tej chwili od 1 do 4 znaków), nie można łatwo określić na pierwszy rzut oka kodu kraju, chyba że użyjesz jakiegoś separatora.
Używam znaku „x” do oddzielenia rozszerzenia, ponieważ w przeciwnym razie naprawdę nie byłoby możliwe (w wielu przypadkach) ustalenie, która jest liczbą, a która jest rozszerzeniem.
W ten sposób możesz przechowywać cały numer, w tym kod kraju i rozszerzenie, w jednym polu bazy danych, którego możesz następnie użyć do przyspieszenia zapytań, zamiast dołączać do funkcji zdefiniowanej przez użytkownika, tak jak dotychczas boleśnie .
Dlaczego wybrałem varchar (42)? Po pierwsze, międzynarodowe numery telefonów będą miały różną długość, stąd nazwa „zmienna”. Przechowuję myślnik i „x”, więc to wyjaśnia „znak”, a poza tym nie będziesz wykonywać arytmetyki całkowitoliczbowej na numerach telefonów (tak sądzę), więc nie ma sensu używać typu liczbowego . Jeśli chodzi o długość 42, użyłem maksymalnej możliwej długości wszystkich zsumowanych pól, na podstawie odpowiedzi Adama Davisa, i dodałem 2 dla myślnika i „x”.
źródło
Wyszukaj E.164. Zasadniczo przechowujesz numer telefonu jako kod zaczynający się od prefiksu kraju i opcjonalnego sufiksu pbx. Wyświetlacz jest wtedy problemem lokalizacji. Można również przeprowadzić walidację, ale jest to również problem z lokalizacją (na podstawie prefiksu kraju).
Na przykład + 12125551212 + 202 zostanie sformatowany w ustawieniach regionalnych en_US jako (212) 555-1212 x202. Miałby inny format w
en_GB
lubde_DE
.Jest sporo informacji o ITU-T E.164, ale są one dość tajemnicze.
źródło
Osobiście podoba mi się pomysł przechowywania znormalizowanego numeru telefonu varchar (np. 9991234567), a następnie oczywiście formatowanie tego numeru w tekście podczas jego wyświetlania.
W ten sposób wszystkie dane w Twojej bazie danych są „czyste” i wolne od formatowania
źródło
Przechowywanie
Przechowuj telefony w RFC 3966 (na przykład
+1-202-555-0252
,+1-202-555-7166;ext=22
). Główną różnicą w stosunku do E.164 sąAby zoptymalizować wydajność operacji przeglądania, przechowuj telefon w formacie krajowym / międzynarodowym obok pola RFC 3966.
Nie przechowuj kodu kraju w osobnym polu, chyba że masz ku temu poważny powód. Czemu? Ponieważ nie powinieneś pytać o kod kraju w interfejsie użytkownika.
Przeważnie ludzie wchodzą do telefonów, gdy je słyszą. Np. Jeśli format lokalny będzie zaczynał się od
0
lub8
, denerwowałoby użytkownika dokonywanie transformacji liczb w nagłówku (np. „ OK, nie wpisuj„ 0 ”, wybierz kraj i wpisz resztę osoba powiedziała w tej dziedzinie ”).Rozbiór gramatyczny zdania
Google jest za twoimi plecami i możesz zweryfikować i przeanalizować dowolny numer telefonu za pomocą jego libphonenumber biblioteki . Istnieją porty na prawie każdy język.
Pozwól więc użytkownikowi po prostu wpisać „
0449053501
”, „04 4905 3501
” lub „(04) 4905 3501
”. Narzędzie wykona resztę za Ciebie.Zobacz oficjalne demo , aby przekonać się, jak bardzo to pomaga.
źródło
Być może przechowywanie sekcji numerów telefonów w różnych kolumnach, umożliwiając puste lub puste wpisy?
źródło
Ok, więc w oparciu o informacje na tej stronie, oto początek międzynarodowego walidatora numerów telefonów:
Luźno oparty na skrypcie z tej strony: http://www.webcheatsheet.com/javascript/form_validation.php
źródło
Standardem formatowania liczb jest e.164. Liczby należy zawsze przechowywać w tym formacie. Nigdy nie należy zezwalać na umieszczanie numeru wewnętrznego w tym samym polu z numerem telefonu, należy je przechowywać oddzielnie. Jeśli chodzi o wartości numeryczne i alfanumeryczne, zależy to od tego, co będziesz robić z tymi danymi.
źródło
Myślę, że dowolny tekst (może varchar (25)) jest najczęściej używanym standardem. Pozwoli to na dowolny format, zarówno krajowy, jak i międzynarodowy.
Myślę, że głównym czynnikiem sprawczym może być to, jak dokładnie sprawdzasz te liczby i co z nimi robisz.
źródło
Uważam, że większość formularzy internetowych poprawnie dopuszcza kod kraju, numer kierunkowy, a następnie pozostałe 7 cyfr, ale prawie zawsze zapominam o zezwoleniu na wprowadzenie numeru wewnętrznego. To prawie zawsze powoduje, że wypowiadam gniewne słowa, ponieważ w pracy nie mamy recepcjonistki, a mój numer wewnętrzny # jest potrzebny, aby do mnie dotrzeć.
źródło
Musiałbym sprawdzić, ale myślę, że nasz schemat bazy danych jest podobny. Posiadamy kod kraju (może to być domyślnie USA, nie jestem pewien), numer kierunkowy, 7 cyfr i numer wewnętrzny.
źródło
A co z przechowywaniem kolumny z wolnym tekstem, która wyświetla przyjazną dla użytkownika wersję numeru telefonu, a następnie znormalizowaną wersję, która usuwa spacje, nawiasy i rozwija „+”. Na przykład:
Przyjazny dla użytkownika: +44 (0) 181 4642542
Znormalizowany: 00441814642542
źródło
Wybrałbym wolne pole i pole zawierające czysto numeryczną wersję numeru telefonu. Pozostawiłbym reprezentację numeru telefonu użytkownikowi i użyłbym znormalizowanego pola specjalnie do porównań numerów telefonów w aplikacjach opartych na TAPI lub podczas próby znalezienia podwójnych wpisów w książce telefonicznej. Oczywiście nie zaszkodzi dostarczenie użytkownikowi schematu wejścia, który dodaje inteligencję, jak oddzielne pola na kod kraju (jeśli to konieczne), numer kierunkowy, numer bazowy i rozszerzenie.
źródło
Skąd bierzesz numery telefonów? Jeśli pobierasz je z części sieci telefonicznej, otrzymasz ciąg cyfr oraz typ numeru i plan, np
441234567890 typ / plan 0x11 (co oznacza międzynarodowy E.164)
W większości przypadków najlepszym rozwiązaniem jest przechowywanie ich wszystkich w niezmienionej postaci i normalizowanie ich wyświetlania, chociaż przechowywanie znormalizowanych liczb może być przydatne, jeśli chcesz ich używać jako unikalnego klucza lub podobnego.
źródło
(0) nie jest ważne w formacie międzynarodowym. Zobacz normę ITU-T E.123.
„Znormalizowany” format nie byłby przydatny dla czytelników w USA, ponieważ używają oni 011 do dostępu międzynarodowego.
źródło
Użyłem 3 różnych sposobów przechowywania numerów telefonów w zależności od wymagań użytkowania.
źródło