Jaki typ danych powinien być używany do przechowywania numerów telefonów w SQL Server 2005?

85

Muszę przechowywać numery telefonów w tabeli. Proszę zasugerować, jakiego typu danych powinienem użyć? Czekać. Przeczytaj dalej, zanim klikniesz odpowiedź.

To pole musi być mocno zindeksowane, ponieważ przedstawiciele handlowi mogą używać tego pola do wyszukiwania (w tym wyszukiwania znaków wieloznacznych).

W tej chwili oczekujemy, że numery telefonów będą dostępne w wielu formatach (z pliku XML). Czy muszę napisać parser, aby przekonwertować na jednolity format? Mogą istnieć miliony danych (z duplikatami) i nie chcę ograniczać zasobów serwera (w działaniach takich jak zbyt duże przetwarzanie wstępne) za każdym razem, gdy przechodzą jakieś dane źródłowe.

Wszelkie sugestie są mile widziane.

Aktualizacja: nie mam kontroli nad danymi źródłowymi. Tylko, że struktura pliku xml jest standardowa. Chciałby ograniczyć analizę XML do minimum. Gdy znajdzie się w bazie danych, pobieranie powinno być szybkie. Jedną szaloną sugestią, która się tutaj pojawia, jest to, że powinien on działać nawet z funkcją autouzupełniania Ajax (aby przedstawiciele handlowi mogli natychmiast zobaczyć pasujące). O MÓJ BOŻE!!

Jan
źródło
1
Możesz użyć github.com/googlei18n/libphonenumber do analizowania / czyszczenia danych źródłowych.
Nicholas Hirras

Odpowiedzi:

60

Czy obejmuje to:

  • Numery międzynarodowe?
  • Rozszerzenia?
  • Czy masz inne informacje poza faktyczną liczbą (np. „Zapytaj o bobby”)?

Jeśli to wszystko oznacza „nie”, użyłbym pola 10 znaków i usunąłbym wszystkie dane nieliczbowe. Jeśli pierwsze to tak, a pozostałe dwa to nie, użyłbym dwóch pól varchar (50), jednego dla pierwotnego wejścia i jednego ze wszystkimi danymi nienumerycznymi rozłożonymi i używanymi do indeksowania. Jeśli 2 lub 3 to tak, myślę, że zrobiłbym dwa pola i jakiś szalony parser, aby określić, co to jest rozszerzenie lub inne dane i odpowiednio się z tym poradzić. Oczywiście możesz uniknąć drugiej kolumny, robiąc coś z indeksem, w którym usuwa on dodatkowe znaki podczas tworzenia indeksu, ale po prostu utworzyłbym drugą kolumnę i prawdopodobnie usunąłbym znaki za pomocą wyzwalacza.

Aktualizacja: aby rozwiązać problem AJAX, może nie być tak źle, jak myślisz. Jeśli realistycznie jest to główny sposób, w jaki cokolwiek jest robione z tabelą, przechowuj tylko cyfry w drugiej kolumnie, jak powiedziałem, a następnie utwórz indeks dla tej kolumny jako grupowany.

Kearns
źródło
1
Tak na wszystkie pytania. Nie mam kontroli nad danymi źródłowymi. Kilka dobrych sugestii. Dzięki.
John
13
Jestem wybredny, ale pole 10 znaków nie obejmowałoby większości brytyjskich numerów komórkowych i wielu brytyjskich numerów stacjonarnych. Pozwoliłoby więcej niż 10, nawet w USA, aby umożliwić przyszłe skalowanie numerów telefonów.
Jon Egerton,
2
Dlaczego nie decimal(10,0)zamiast char?
Pan Anderson,
1
@MrAnderson, myślę, że to dlatego decimal(10,0), że jeśli potrzebujesz, musisz
dopisać początkowe
W zależności od tego, gdzie jesteś na świecie, nie sądzę, że 10 znaków to wystarczająco długo , co również podkreśla odpowiedź Brada.
Richardissimo,
42

Używamy varchar (15) i oczywiście indeksu na tym polu.

Powodem jest to, że międzynarodowe standardy mogą obsługiwać do 15 cyfr

Wikipedia - formaty numerów telefonów

Jeśli obsługujesz numery międzynarodowe, zalecam oddzielne przechowywanie kodu strefy światowej lub kodu kraju, aby lepiej filtrować zapytania, aby nie znaleźć się w analizowaniu i sprawdzaniu długości pól numeru telefonu w celu ograniczenia zwracanych połączeń do USA dla przykład

Brad Osterloo
źródło
2
Mogę przeoczyć coś oczywistego, ale jakie korzyści płyną z używania znakowego typu danych do przechowywania danych liczbowych? A jeśli przechowujesz więcej niż dane liczbowe (np. Ograniczniki), czy nie potrzebujesz więcej niż 15 znaków do zapisania sformatowanej 15-cyfrowej liczby?
FtDRbwLXw6
13
@drrcknlsn powodem jest wiodące zero - niektóre (większość w niektórych krajach) zaczynają od zera
Manse
16
@drrcknlsn Wiem, że ten komentarz ma 2 lata, ale na wypadek, gdyby ktoś natknął się na Twój komentarz: Zwykle zasada jest taka, że ​​do przechowywania danych liczbowych należy używać liczb całkowitych, które mają sens, a reszta to struny. Na przykład dodanie dwóch numerów telefonów lub pomnożenie numerów SIN / SSN nie ma sensu, więc powinny być przechowywane jako ciągi.
Marco Pietro Cirillo
2
@drrcknlsn dlaczego nie decimal(10,0)zamiast tego char?
Pan Anderson
@Mr A: Może dlatego, że długość numeru telefonu może się różnić w zależności od regionu / kraju. Wypełnienie początkowymi zerami spowodowałoby wówczas dodatkowy problem z analizą.
Trunk
5

Użyj znaku CHAR (10), jeśli przechowujesz tylko numery telefonów ze Stanów Zjednoczonych. Usuń wszystko oprócz cyfr.

Joseph Bui
źródło
3

Prawdopodobnie brakuje mi tego, co oczywiste, ale czy varchar nie byłby wystarczająco długi na Twój najdłużej oczekiwany numer telefonu?

Jeśli brakuje mi czegoś oczywistego, bardzo bym chciał, żeby ktoś to wskazał ...

cori
źródło
3

Użyłbym varchar (22). Wystarczająco duży, aby pomieścić numer telefonu z Ameryki Północnej z numerem wewnętrznym. Chciałbyś usunąć wszystkie paskudne znaki „(”, „)”, „-” lub po prostu przeanalizować je wszystkie w jeden jednolity format.

Alex

Alex Fort
źródło
2

SQL Server 2005 jest dość dobrze zoptymalizowany pod kątem zapytań podciągowych dla tekstu w indeksowanych polach varchar. W 2005 roku wprowadzili nowe statystyki do podsumowania ciągów dla pól indeksowych. To znacznie pomaga przy wyszukiwaniu pełnotekstowym.

Joseph Daigle
źródło
2

używanie varchar jest dość nieefektywne. użyj typu pieniędzy i utwórz z niego zadeklarowany przez użytkownika typ „numer telefonu” oraz utwórz regułę zezwalającą tylko na liczby dodatnie.

jeśli zadeklarujesz go jako (19,4), możesz nawet zapisać 4-cyfrowe rozszerzenie i być wystarczająco duże dla numerów międzynarodowych i zajmuje tylko 9 bajtów pamięci. Ponadto indeksy są szybkie.

fjleon
źródło
2
Grats. -1. Ingorance and not reading - co abuot% 233% - pełne skanowanie tabeli + konwersje? Jest to standardowy problem i istnieje standardowe rozwiązanie, a NIE jest to liczba. Co przy okazji usuwa całe formatowanie.
TomTom
@TomTom Chociaż zgadzam moneysię, nie jest odpowiedzią, jeśli wyszukiwanie według podłańcucha nie jest wymagane (i wyobrażam sobie, że wielu nie musi wyszukiwać rekordu na podstawie tylko części numeru telefonu), co byłoby złego w używaniu decimal(10,0)?
Pan Anderson,
1

nvarchar z przetwarzaniem wstępnym, aby ujednolicić je w jak największym stopniu. Prawdopodobnie będziesz chciał wyodrębnić rozszerzenia i zapisać je w innym polu.

John Sheehan
źródło
1

Normalizuj dane, a następnie zapisz je jako varchar. Normalizacja może być trudna.

To powinno być jednorazowe trafienie. Następnie, gdy pojawia się nowy rekord, porównujesz go ze znormalizowanymi danymi. Powinien być bardzo szybki.

Iain Holder
źródło
1

Ponieważ musisz uwzględnić wiele różnych formatów numerów telefonów (i prawdopodobnie zawierać takie elementy, jak rozszerzenia itp.), Najbardziej sensowne może być traktowanie go tak, jak każdego innego varchar. Gdybyś mógł kontrolować dane wejściowe, mógłbyś zastosować kilka podejść, aby uczynić dane bardziej użytecznymi, ale to nie brzmi w ten sposób.

Gdy zdecydujesz się traktować go po prostu jak każdy inny ciąg, możesz skupić się na przezwyciężeniu nieuniknionych problemów dotyczących złych danych, tajemniczego formatowania numeru telefonu i wszystkiego innego, co się pojawi. Wyzwaniem będzie zbudowanie dobrej strategii wyszukiwania danych, a nie sposobu ich przechowywania, moim zdaniem. Praca z dużą ilością danych, nad gromadzeniem których nie miałeś kontroli, jest zawsze trudnym zadaniem.


źródło
1

Użyj SSIS, aby wyodrębnić i przetworzyć informacje. W ten sposób będziesz mieć przetwarzanie plików XML oddzielonych od SQL Server. W razie potrzeby możesz również przeprowadzić transformacje SSIS na oddzielnym serwerze. Przechowuj numery telefonów w standardowym formacie za pomocą VARCHAR. NVARCHAR byłby niepotrzebny, ponieważ mówimy o liczbach i być może kilku innych znakach, takich jak „+”, „”, „(”, „)” i „-”.

Magnus Johansson
źródło
1

Użyj varcharpola z ograniczeniem długości.

user13270
źródło
1

Dość często używa się „x” lub „ext” do wskazania rozszerzeń, więc dopuszczaj 15 znaków (dla pełnej obsługi międzynarodowej) plus 3 (dla „ext”) plus 4 (dla samego rozszerzenia), co daje łącznie 22 znaki . To powinno zapewnić ci bezpieczeństwo.

Alternatywnie, znormalizuj dane wejściowe, aby każde „rozszerzenie” zostało przetłumaczone na „x”, dając maksymalnie 20.

Rob G
źródło
1

Zawsze lepiej jest mieć oddzielne tabele dla atrybutów wielowartościowych, takich jak numer telefonu.

Ponieważ nie masz kontroli nad danymi źródłowymi, możesz przeanalizować dane z pliku XML i przekonwertować je do odpowiedniego formatu, aby nie było problemu z formatami danego kraju i przechowywać je w osobnej tabeli, aby indeksowanie i odzyskiwanie obu będzie wydajne .

Dziękuję Ci.

Jayghosh Wankar
źródło
Nie odpowiada w pełni na pytanie.
Smart Manoj
1

Zdaję sobie sprawę, że ten wątek jest stary, ale warto wspomnieć o zaletach przechowywania jako typu numerycznego do celów formatowania, szczególnie w ramach .NET.

TO ZNACZY

.DefaultCellStyle.Format = "(###)###-####" // Will not work on a string
Panie Tripodi
źródło
0

Zamiast tego użyj typu danych long ... nie używaj int, ponieważ zezwala on tylko na liczby całkowite z przedziału od -32 768 do 32767, ale jeśli używasz typu danych long, możesz wstawić liczby z przedziału od -2 147 483 648 do 2 147 483 647.

Ej Manalo Carbona
źródło
1
To jest w porządku, ale nie możesz przechowywać numerów międzynarodowych z kodem kraju, ponieważ niektóre numery zaczynają się od kodu kraju. Np .: 0094777123123, Lepiej użyj pola varchar (15) z pewną walidacją wyrażeń regularnych.
Bubashan_kushan