Есть ли стандарт для хранения нормализованных номеров телефонов в базе данных?

Какова хорошая структура данных для хранения телефонных номеров в полях базы данных? Я ищу что-то достаточно гибкое, чтобы обрабатывать международные номера, а также то, что позволяет эффективно обрабатывать различные части номера.

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

where dbo.f_normalizenum(num1) = dbo.f_normalizenum(num2)

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

[изменить]

Люди сделали здесь много хороших предложений, спасибо! В качестве обновления, вот что я делаю сейчас: я все еще храню номера точно так же, как они были введены, в поле varchar, но вместо нормализации вещей во время запроса у меня есть триггер, который делает все, что работает, когда записи вставлены или обновлено. Поэтому у меня есть ints или bigints для любых частей, которые мне нужно запросить, и эти поля индексируются, чтобы запросы выполнялись быстрее.

Ответ 1

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

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

  • C Код страны 1-10 цифр (прямо сейчас 4 или менее, но это может измениться)
  • Код зоны (провинция/штат/регион) код 0-10 цифр (на самом деле может потребоваться поле региона и поле области отдельно, а не один код зоны)
  • E Код обмена (префикс или коммутатор) 0-10 цифр
  • L Номер строки 1-10 цифр

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

Кроме того, внутри каждой страны существуют разные стандарты. Вы всегда можете зависеть от (AAA) EEE-LLLL в США, но в другой стране вы можете иметь обмен в городах (AAA) EE-LLL и просто номера строк в сельской местности (AAA) LLLL. Вам нужно будет начинать вверху в дереве какой-то формы и форматировать их, поскольку у вас есть информация. Например, код страны 0 имеет известный формат для остальной части номера, но для кода страны 5432 вам может потребоваться изучить код области, прежде чем вы поймете остальную часть номера.

Вы также можете обрабатывать цифры vanity, такие как (800) Lucky-Guy, что требует признания того, что если у него номер в США, есть слишком много цифр (и вам может потребоваться полное представление для рекламы или других целей) и что в США буквы обозначаются цифрами по-разному, чем в Германии.

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

Ответ 2

КИСС. Я устал от многих американских веб-сайтов. У них есть хитрый код для проверки почтовых индексов и номеров телефонов. Когда я ввожу свою совершенно нормальную норвежскую контактную информацию, я обнаружил, что довольно часто ее отклоняют.

Оставьте это строкой, если у вас нет определенной потребности в чем-то более продвинутом.

Ответ 3

Страница Wikipedia на E.164 должна рассказать вам все, что вам нужно знать.

Ответ 4

Здесь моя предлагаемая структура, я буду благодарен за отзывы:

Поле базы данных телефона должно быть varchar (42) со следующим форматом:

Код страны - номер x Расширение

Так, например, в США мы могли бы:

1-2125551234x1234

Это будет представлять собой номер в США (код страны 1) с кодом города/номером (212) 555 1234 и расширением 1234.

Разделение кода страны на тире делает код страны понятным для кого-то, кто просматривает данные. Это не является абсолютно необходимым, потому что коды стран " префиксные коды" (вы можете прочитать их слева направо, и вы всегда сможете однозначно определить страна). Но, поскольку коды стран имеют разную длину (от 1 до 4 символов на данный момент), вы не можете легко сразу определить код страны, если вы не используете какой-то разделитель.

Я использую "x" для разделения расширения, потому что в противном случае было бы невозможно (во многих случаях) выяснить, какой из них является номером и который является расширением.

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

Почему я выбрал varchar (42)? Ну, во-первых, международные номера телефонов будут иметь разную длину, следовательно, "вар". Я сохраняю тире и "х", поэтому объясняет "char", и в любом случае вы не будете делать целочисленную арифметику по номерам телефонов (я думаю), поэтому нет смысла пытаться использовать числовой тип. Что касается длины 42, я использовал максимально возможную длину всех добавленных полей на основе ответа Адама Дэвиса и добавил 2 для тире и "х".

Ответ 5

Посмотрите E.164. В основном вы храните номер телефона в виде кода, начинающегося с префикса страны и необязательного суффикса pbx. Дисплей - это проблема локализации. Валидация также может быть выполнена, но это также проблема локализации (на основе префикса страны).

Например, +12125551212 + 202 будет отформатирован в локале en_US как (212) 555-1212 x202. Он имел бы другой формат в en_GB или de_DE.

Существует довольно много информации о ITU-T E.164, но это довольно загадочно.

Ответ 6

Мне лично нравится идея сохранить нормализованный номер телефона varchar (например, 9991234567), и, конечно же, форматирование этого номера телефона, когда вы его показываете.

Таким образом, все данные в вашей базе данных "чисты" и не имеют форматирования

Ответ 7

Возможно сохранение разделов номера телефона в разных столбцах, допускающих пустые или нулевые записи?

Ответ 8

Хорошо, поэтому, основываясь на информации на этой странице, вот начало на валидаторе международного номера телефона:

function validatePhone(phoneNumber) {
    var valid = true;
    var stripped = phoneNumber.replace(/[\(\)\.\-\ \+\x]/g, '');    

    if(phoneNumber == ""){
        valid = false;
    }else if (isNaN(parseInt(stripped))) {
        valid = false;
    }else if (stripped.length > 40) {
        valid = false;
    }
    return valid;
}

На основе script на этой странице: http://www.webcheatsheet.com/javascript/form_validation.php

Ответ 9

Я думаю, что свободный текст (возможно, varchar (25)) является наиболее широко используемым стандартом. Это позволит использовать любой формат, будь то внутренний или международный.

Я думаю, основным фактором может быть то, как именно вы запрашиваете эти цифры и что вы делаете с ними.

Ответ 10

Как насчет сохранения столбца freetext, который показывает удобную версию номера телефона, а затем нормализованную версию, которая удаляет пробелы, скобки и расширяет "+". Например:

Дружественный к пользователю: +44 (0) 181 4642542

Нормализованный: 00441814642542

Ответ 11

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

Ответ 12

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

Мне нужно было бы проверить, но я думаю, что наша схема БД похожа. Мы держим код страны (он может по умолчанию для США, не уверен), код области, 7 цифр и расширение.

Ответ 13

Я хотел бы получить поле freetext и поле, содержащее чисто числовую версию номера телефона. Я хотел бы оставить представление номера телефона пользователю и использовать нормализованное поле специально для сравнения номеров телефонов в приложениях на основе TAPI или при попытке найти двойные записи в телефонной книге. Конечно, это не мешает предоставить пользователю схему входа, которая добавляет интеллект, как отдельные поля для кода страны (при необходимости), код зоны, базовый номер и расширение.

Ответ 14

Я использовал 3 разных способа хранения телефонных номеров в зависимости от требований к использованию.

  • Если номер хранится только для поиска человека и не будет использоваться для поиска его сохраненного в поле типа строки точно так же, как пользователь ввел его.
  • Если поле будет искать, любые дополнительные символы, такие как +, пробелы и скобки и т.д., будут удалены, а оставшееся число будет сохранено в поле типа строки.
  • Наконец, если номер телефона будет использоваться приложением для компьютера/телефона, тогда в этом случае его нужно будет ввести и сохранить в качестве действительного номера телефона, который может использоваться системой, этот вариант, конечно, является наиболее сложно кодировать.

Ответ 15

Откуда вы получаете номера телефонов? Если вы получаете их из части телефонной сети, вы получите строку цифр и числовой тип и план, например

441234567890 тип/план 0x11 (что означает международный E.164)

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

Ответ 16

Дружественный к пользователю: +44 (0) 181 464 2542 нормализованный: 00441814642542

Значение (0) недопустимо в международном формате. См. Стандарт ITU-T E.123.

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

Ответ 17

Стандарт для чисел форматирования e.164, вы всегда должны хранить номера в этом формате. Вы никогда не должны допускать добавочный номер в том же поле с номером телефона, который должен храниться отдельно. Что касается числового и буквенно-цифрового, это зависит от того, что вы собираетесь делать с этими данными.