Какова хорошая структура данных для хранения телефонных номеров в полях базы данных? Я ищу что-то достаточно гибкое, чтобы обрабатывать международные номера, а также что-то, что позволяет эффективно запрашивать различные части номера.
Изменить: просто чтобы прояснить здесь вариант использования: в настоящее время я храню числа в одном поле varchar и оставляю их так же, как их ввел клиент. Потом, когда номер нужен по коду, нормализую. Проблема в том, что если я хочу запросить несколько миллионов строк, чтобы найти совпадающие номера телефонов, это включает в себя функцию, например
where dbo.f_normalizenum(num1) = dbo.f_normalizenum(num2)
что ужасно неэффективно. Кроме того, запросы, которые ищут такие вещи, как код города, становятся чрезвычайно сложными, когда это всего лишь одно поле varchar.
[Редактировать]
Здесь много хороших предложений, спасибо! В качестве обновления вот что я делаю сейчас: я все еще храню числа в том виде, в котором они были введены, в поле varchar, но вместо нормализации вещей во время запроса у меня есть триггер, который выполняет все, что работает при вставке записей или обновлено. Итак, у меня есть целые числа или большие значения для любых частей, которые мне нужно запросить, и эти поля индексируются, чтобы запросы выполнялись быстрее.
Ответы:
Во-первых, за пределами кода страны нет настоящего стандарта. Лучшее, что вы можете сделать, это узнать по коду страны, к какой стране принадлежит конкретный номер телефона, и обработать остальную часть номера в соответствии с форматом этой страны.
Однако, как правило, телефонное оборудование и тому подобное стандартизировано, поэтому вы почти всегда можете разбить данный номер телефона на следующие компоненты.
С помощью этого метода вы можете потенциально разделить номера, чтобы вы могли найти, например, людей, которые могут быть близки друг к другу, потому что у них одинаковые коды страны, региона и биржи. Однако с сотовыми телефонами на это больше нельзя рассчитывать.
Кроме того, внутри каждой страны существуют разные стандарты. Вы всегда можете рассчитывать на (AAA) EEE-LLLL в США, но в другой стране у вас могут быть телефонные станции в городах (AAA) EE-LLL и просто номера линий в сельской местности (AAA) LLLL. Вам нужно будет начать с вершины дерева некоторой формы и отформатировать их по мере того, как у вас есть информация. Например, код страны 0 имеет известный формат для остальной части номера, но для кода страны 5432 вам может потребоваться изучить код города, прежде чем вы поймете остальную часть номера.
Вы также можете обрабатывать
vanity
числа, такие как(800) Lucky-Guy
, что требует признания того, что, если это номер в США, там слишком много цифр (и вам может потребоваться полное представление для рекламы или других целей) и что в США буквы сопоставляются с номера иначе, чем в Германии.Вы также можете сохранить весь номер отдельно в виде текстового поля (с интернационализацией), чтобы вы могли вернуться позже и повторно проанализировать числа, когда что-то изменится, или в качестве резервной копии на случай, если кто-то отправит неверный метод для анализа формата конкретной страны. и теряет информацию.
источник
KISS - Я устаю от многих американских веб-сайтов. У них есть грамотно написанный код для проверки почтовых индексов и номеров телефонов. Когда я ввожу свою совершенно действительную норвежскую контактную информацию, я обнаруживаю, что довольно часто она отклоняется.
Оставьте строку, если вам не нужно что-то более сложное.
источник
nvarchar(42)
с небольшой проверкой/^+?[0-9 -\.\(\)#*]{4,41}$/
работает очень хорошо!Страница Википедии о E.164 должна рассказать вам все, что вам нужно знать.
источник
Вот моя предлагаемая структура, буду благодарен за отзывы:
Поле базы данных телефонов должно быть varchar (42) в следующем формате:
CountryCode - номер x добавочный номер
Так, например, в США мы могли бы иметь:
1-2125551234x1234
Это будет представлять собой номер в США (код страны 1) с кодом / номером зоны (212) 555 1234 и добавочным номером 1234.
Разделение кода страны тире делает код страны понятным для тех, кто просматривает данные. Это не является строго необходимым, поскольку коды стран являются « кодами префиксов » (вы можете читать их слева направо, и вы всегда сможете однозначно определить страну). Но, поскольку коды стран имеют разную длину (на данный момент от 1 до 4 символов), вы не можете легко определить код страны, если не используете какой-либо разделитель.
Я использую «x» для разделения расширения, потому что в противном случае было бы невозможно (во многих случаях) определить, какой номер был, а какой - расширение.
Таким образом, вы можете хранить весь номер, включая код страны и расширение, в одном поле базы данных, которое затем можно использовать для ускорения ваших запросов, вместо того, чтобы присоединяться к пользовательской функции, как вы мучительно делали до сих пор. .
Почему я выбрал varchar (42)? Во-первых, международные телефонные номера будут иметь разную длину, отсюда и слово «вар». Я храню тире и «x», так что это объясняет «char», и в любом случае вы не будете выполнять целочисленные арифметические операции с телефонными номерами (я полагаю), поэтому нет смысла пытаться использовать числовой тип . Что касается длины 42, я использовал максимально возможную длину всех суммированных полей, основываясь на ответе Адама Дэвиса, и добавил 2 для тире и «x».
источник
Найдите E.164. Обычно вы храните номер телефона в виде кода, начинающегося с префикса страны и необязательного суффикса PBX. Тогда дисплей - это проблема локализации. Проверка также может выполняться, но это также проблема локализации (на основе префикса страны).
Например, + 12125551212 + 202 будет отформатирован в локали en_US как (212) 555-1212 x202. У него был бы другой формат в
en_GB
илиde_DE
.Информации о ITU-T E.164 довольно много, но она довольно загадочная.
источник
Мне лично нравится идея хранения нормализованного телефонного номера varchar (например, 9991234567), а затем, конечно же, форматирования этого телефонного номера в строке при его отображении.
Таким образом, все данные в вашей базе данных будут «чистыми» и без форматирования.
источник
Место хранения
Храните телефоны в RFC 3966 (например
+1-202-555-0252
,+1-202-555-7166;ext=22
). Основное отличие от E.164 :Чтобы оптимизировать производительность операций просмотра, сохраните телефон в национальном / международном формате рядом с полем RFC 3966.
Не храните код страны в отдельном поле, если у вас нет для этого серьезной причины. Зачем? Потому что вы не должны запрашивать код страны в пользовательском интерфейсе.
В основном люди входят в телефоны, когда их слышат. Например, если локальный формат будет начинаться с
0
или8
, пользователю будет неприятно выполнять преобразование чисел в заголовке (например, « Хорошо, не вводите« 0 », выберите страну и введите остальную часть того, что человек сказал в этой области ").Парсинг
У Google есть ваша спина, и вы можете проверить и проанализировать любой номер телефона с помощью их библиотеки libphonenumber . Есть порты практически на любой язык.
Так что пусть пользователь просто вводит "
0449053501
" или "04 4905 3501
" или "(04) 4905 3501
". Все остальное инструмент сделает за вас.Посмотрите официальную демонстрацию , чтобы понять, насколько это помогает.
источник
Возможно, сохранение разделов телефонных номеров в разных столбцах, позволяющих вводить пустые или пустые записи?
источник
Итак, исходя из информации на этой странице, вот начало валидатора международных телефонных номеров:
Примерно на основе сценария с этой страницы: http://www.webcheatsheet.com/javascript/form_validation.php
источник
Стандарт форматирования чисел - e.164. Вы всегда должны хранить числа в этом формате. Никогда не разрешайте добавочный номер в одно поле с номером телефона, они должны храниться отдельно. Что касается числовых и буквенно-цифровых, это зависит от того, что вы собираетесь делать с этими данными.
источник
Я думаю, что свободный текст (возможно, varchar (25)) - наиболее широко используемый стандарт. Это позволит использовать любой формат, как внутренний, так и международный.
Я предполагаю, что основным движущим фактором может быть то, как именно вы запрашиваете эти числа и что вы делаете с ними.
источник
Я считаю, что большинство веб-форм правильно позволяют ввести код страны, код города, а затем оставшиеся 7 цифр, но почти всегда забывают разрешить ввод расширения. Это почти всегда приводит к тому, что я говорю гневные слова, так как на работе у нас нет портье, и мне нужен внутренний номер.
источник
Мне бы пришлось проверить, но я думаю, что наша схема БД похожа. У нас есть код страны (по умолчанию он может быть США, не уверен), код города, 7 цифр и добавочный номер.
источник
Как насчет сохранения столбца с произвольным текстом, который показывает удобную для пользователя версию телефонного номера, а затем нормализованную версию, в которой удаляются пробелы, скобки и расширяется '+'. Например:
Удобный:Удобно +44 (0) 181 4642542
Нормализованный: 00441814642542
источник
Я бы выбрал поле с произвольным текстом и поле, содержащее чисто числовую версию номера телефона. Я бы оставил представление номера телефона пользователю и использовал нормализованное поле специально для сравнения номеров телефонов в приложениях на основе TAPI или при попытке найти двойные записи в телефонном справочнике. Конечно, это не повредит предоставлению пользователю схемы ввода, которая добавляет интеллектуальные функции, такие как отдельные поля для кода страны (при необходимости), кода города, базового номера и добавочного номера.
источник
Откуда у вас телефонные номера? Если вы получаете их из части телефонной сети, вы получите строку цифр, а также тип номера и план, например
441234567890 тип / план 0x11 (что означает международный E.164)
В большинстве случаев лучше всего сохранить все это как есть и нормализовать для отображения, хотя хранение нормализованных чисел может быть полезно, если вы хотите использовать их в качестве уникального ключа или аналогичного.
источник
(0) недействителен в международном формате. См. Стандарт ITU-T E.123.
«Нормализованный» формат бесполезен для читателей из США, поскольку они используют 011 для международного доступа.
источник
Я использовал 3 разных способа хранения телефонных номеров в зависимости от требований использования.
источник