Какой тип данных следует использовать для хранения телефонных номеров в SQL Server 2005?


85

Мне нужно хранить номера телефонов в таблице. Подскажите, пожалуйста, какой тип данных мне использовать? Подождите. Пожалуйста, прочтите, прежде чем ответить.

Это поле необходимо тщательно проиндексировать, поскольку торговые представители могут использовать это поле для поиска (включая поиск с использованием диких символов).

На данный момент мы ожидаем, что телефонные номера будут иметь несколько форматов (из файла XML). Надо ли писать парсер для преобразования в единый формат? Могут быть миллионы данных (с дубликатами), и я не хочу связывать ресурсы сервера (например, слишком много предварительной обработки) каждый раз, когда приходят какие-то исходные данные.

Любые предложения приветствуются ..

Обновление: у меня нет контроля над исходными данными. Просто структура xml файла стандартная. Хотелось бы свести синтаксический анализ xml к минимуму. Как только он будет в базе данных, поиск должен быть быстрым. Здесь звучит безумное предложение, что он должен работать даже с функцией Ajax AutoComplete (чтобы торговые представители могли сразу увидеть соответствующие). О, МОЙ БОГ!!


1
Возможно, вы захотите использовать github.com/googlei18n/libphonenumber для анализа / очистки исходных данных.
Николас Хиррас

Ответы:


60

Включает ли это:

  • Международные номера?
  • Расширения?
  • Другая информация, кроме фактического номера (например, «спросить Бобби»)?

Если все это нет, я бы использовал поле из 10 символов и вырезал все нечисловые данные. Если первое - да, а два других - нет, я бы использовал два поля varchar (50), одно для исходного ввода и одно со всеми нечисловыми данными, разделенными полосами и используемыми для индексации. Если 2 или 3 - да, я бы сделал два поля и какой-нибудь сумасшедший парсер, чтобы определить, что такое расширение или другие данные, и обработать их соответствующим образом. Конечно, вы могли бы избежать второго столбца, сделав что-нибудь с индексом, где он удаляет лишние символы при создании индекса, но я бы просто сделал второй столбец и, вероятно, сделал бы удаление символов с помощью триггера.

Обновление: для решения проблемы AJAX это может быть не так плохо, как вы думаете. Если это действительно основной способ, которым что-либо делается с таблицей, сохраните только цифры во вторичном столбце, как я сказал, а затем сделайте индекс для этого столбца кластеризованным.


1
Да на все вопросы. Я не контролирую исходные данные. Есть несколько хороших предложений. Благодарю.
Джон,

13
Я придираюсь к мелочам, но 10-символьное поле не покрывает большинство мобильных номеров Великобритании и многие номера наземных линий Великобритании. Это позволило бы более 10 даже в США, чтобы обеспечить масштабирование телефонных номеров в будущем.
Джон Эгертон

2
Почему не decimal(10,0)вместо char?
Мистер Андерсон,

1
@MrAnderson, я думаю, это потому, что decimal(10,0)вы должны вводить начальные нули обратно в число, когда вам это нужно ..
Mathijs Flietstra

В зависимости от того, где вы находитесь в мире, я не думаю, что 10 символов достаточно долго , что также подчеркивается ответом Брэда.
Ричардиссимо

42

Мы используем varchar (15) и обязательно index для этого поля.

Причина в том, что международные стандарты могут поддерживать до 15 цифр.

Википедия - Форматы телефонных номеров

Если вы поддерживаете международные номера, я рекомендую отдельное хранение кода мировой зоны или кода страны, чтобы лучше фильтровать запросы, чтобы вам не пришлось разбирать и проверять длину полей номера телефона, чтобы ограничить количество возвращаемых вызовов в США для пример


2
Возможно, я упускаю из виду кое-что очевидное, но какая польза от использования символьного типа данных для хранения числовых данных? А если вы храните больше, чем числовые данные (например, разделители), разве вам не понадобится более 15 символов для хранения отформатированного 15-значного числа?
FtDRbwLXw6,

13
@drrcknlsn причина в ведущем нуле - некоторые (большинство в некоторых странах) начинаются с нуля
Мансе

16
@drrcknlsn Я знаю, что этому комментарию 2 года, но в случае, если кто-нибудь встретит ваш комментарий: Обычно практическое правило заключается в том, что для хранения числовых данных, которые имеют смысл выполнять математические вычисления, следует использовать целые типы данных, а остальные струны. Например, сложение двух телефонных номеров или умножение номеров SIN / SSN не имеет смысла, поэтому их следует хранить в виде строк.
Марко Пьетро Чирилло

2
@drrcknlsn почему не decimal(10,0)то вместо char?
Мистер Андерсон,

@ Г-н А: Может быть, потому что длина телефонного номера может варьироваться от одного региона / страны к другому. Заполнение начальными нулями тогда создало бы дополнительную проблему синтаксического анализа.
Магистральный

5

Используйте CHAR (10), если вы сохраняете только номера телефонов США. Удалите все, кроме цифр.


3

Я, вероятно, упускаю из виду очевидное, но разве varchar не будет достаточно длинным для вашего долгожданного телефонного номера?

Если мне не хватает чего-то очевидного, я бы хотел, чтобы кто-нибудь на это указал ...


3

Я бы использовал varchar (22). Достаточно большой, чтобы вместить телефонный номер в Северной Америке с добавочным номером. Вы бы хотели удалить все неприятные символы '(', ')', '-' или просто разобрать их в одном едином формате.

Alex


2

SQL Server 2005 довольно хорошо оптимизирован для запросов подстроки для текста в индексированных полях varchar. В 2005 году они ввели новую статистику в строковую сводку для полей индекса. Это значительно помогает при полнотекстовом поиске.


2

использование varchar довольно неэффективно. используйте тип денег и создайте из него объявленный пользователем тип "номер телефона" и создайте правило, разрешающее только положительные числа.

если вы объявите его как (19,4), вы даже можете сохранить 4-значное расширение и быть достаточно большим для международных номеров, и займет всего 9 байт памяти. Кроме того, индексы быстрые.


2
Решетки. -1. Невежество, а не чтение - что насчет% 233% - полное сканирование таблицы + преобразование? Это стандартная проблема, и есть стандартное решение, и это НЕ число. Что удаляет все форматирование, кстати.
TomTom

@TomTom Хотя я согласен, что moneyэто не ответ, но если поиск по подстроке не требуется (и я предполагаю, что многим не нужно искать запись, основанную только на части телефонного номера), что будет неправильным в использовании decimal(10,0)?
Мистер Андерсон,

1

nvarchar с предварительной обработкой, чтобы максимально стандартизировать их. Вы, вероятно, захотите извлечь расширения и сохранить их в другом поле.


1

Нормализовать данные, а затем сохранить как varchar. Нормализация может быть сложной задачей.

Это должно быть разовое попадание. Затем по мере поступления новой записи вы сравниваете ее с нормализованными данными. Должно быть очень быстро.


1

Поскольку вам нужно поддерживать множество различных форматов телефонных номеров (и, вероятно, включать такие вещи, как расширения и т. Д.), Может иметь смысл просто обращаться с ним, как с любым другим varchar. Если бы вы могли контролировать ввод, вы могли бы использовать несколько подходов, чтобы сделать данные более полезными, но это не так.

Как только вы решите просто рассматривать ее как любую другую строку, вы можете сосредоточиться на преодолении неизбежных проблем, связанных с неверными данными, загадочным форматированием телефонного номера и всем остальным, что может появиться. На мой взгляд, проблема будет заключаться в создании хорошей стратегии поиска данных, а не в том, как вы их храните. Всегда сложно иметь дело с большим количеством данных, которые вы не можете контролировать.


1

Используйте SSIS для извлечения и обработки информации. Таким образом, обработка файлов XML будет отделена от SQL Server. При необходимости вы также можете выполнять преобразования SSIS на отдельном сервере. Сохраните телефонные номера в стандартном формате с помощью VARCHAR. В NVARCHAR нет необходимости, так как мы говорим о числах и, возможно, о нескольких других символах, таких как '+', '', '(', ')' и '-'.



1

Довольно часто для обозначения расширений используются символы «x» или «ext», поэтому допускается использование 15 символов (для полной международной поддержки) плюс 3 (для «ext») плюс 4 (для самого расширения), что в сумме дает 22 символа. . Это должно защитить вас.

В качестве альтернативы, нормализуйте вход, чтобы любой "ext" переводился в "x", давая максимум 20.


1

Всегда лучше иметь отдельные таблицы для многозначных атрибутов, таких как номер телефона.

Поскольку у вас нет контроля над исходными данными, вы можете проанализировать данные из XML-файла и преобразовать их в соответствующий формат, чтобы не возникало проблем с форматами конкретной страны и сохранить их в отдельной таблице, чтобы индексирование и извлечение будет эффективным .

Спасибо.


Не отвечает на вопрос полностью.
Smart Manoj


0

Вместо этого используйте тип данных long .. не используйте int, потому что он допускает только целые числа от -32 768 до 32 767, но если вы используете длинный тип данных, вы можете вставлять числа от -2 147 483 648 до 2 147 483 647.


1
Это нормально, но вы не можете хранить международные номера с кодом страны, поскольку некоторые номера начинаются с кода страны. Например: 0094777123123. Лучше использовать поле varchar (15) с некоторой проверкой регулярного выражения.
Bubashan_kushan
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.