Лучше хранить телефон в трех полях или как одно? - PullRequest
4 голосов
/ 16 февраля 2011

Я борюсь с решением разделить телефонные номера, хранящиеся в базе данных MySQL.

Одна из идей состоит в том, чтобы взломать телефон как:

  • код города (123)
  • префикс (123)
  • суффикс (1234)

Другой способ - просто поместить файл в одно поле с любым форматированием, которое будет сочтено целесообразным:

  • 123456789
  • (123) 123-4567
  • 123-456-7890

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

Есть ли действительно «правильный» способ сделать это? Я понимаю, что в сочетании с PHP я могу извлекать и переформатировать все, что захочу, но я бы хотел использовать лучшие практики.

Спасибо за ваш совет

EDIT

Пока я буду хранить только номера телефонов в Северной Америке

Ответы [ 8 ]

7 голосов
/ 16 февраля 2011

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

2 голосов
/ 16 февраля 2011

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

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

Так как они были полезны для меня, вот что я написал до сих пор:

public static function cleanPhoneNumbers($input) {
        return preg_replace("/[^0-9]/", "", $input);
    }

public static function formatPhoneNumbers($phone_number) {
     if(strlen($phone_number) == 7) {
          return preg_replace("/([0-9]{3})([0-9]{4})/", "$1-$2", $phone_number);
     } elseif(strlen($phone_number) == 10) {
          return preg_replace("/([0-9]{3})([0-9]{3})([0-9]{4})/", "$1-$2-$3", $phone_number);
     } else {
          return $phone_number;
     }

}

Некоторые предостережения: мое приложение сейчас недоступно для международных клиентов (в него встроено приложение voip, которое мы сейчас не хотим разрешать звонить за пределы США), поэтому яНе нашли время, чтобы настроить для международных возможностей.Кроме того, поскольку это происходит, я, вероятно, вернусь к рефакторингу и поддержу эти функции позже.

Я обнаружил одну слабость, которая до сих пор доставляла мне немного боли.В моем приложении я должен запретить звонки по часовому поясу в зависимости от времени суток (например, не разрешать звонить кому-либо на западном побережье в 6:00, когда на востоке 9:00).Для этого мне нужно присоединить отдельную таблицу кодов зоны к моей таблице с телефонными номерами, сравнив трехзначные коды зоны, чтобы получить часовой пояс.Но я не могу просто сравнить почтовый индекс с моим полем номера телефона, потому что они никогда не будут совпадать.Итак, мне приходится иметь дело с дополнительным SQL, чтобы получить только первые три цифры номера.Не изменит правила игры, но, тем не менее, больше работы и путаницы.

2 голосов
/ 16 февраля 2011

Я буду хранить номера телефонов в виде строк, а не номеров.

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

Удалите номер телефона только из цифр и сохраните добавочный номер в отдельном поле.

Это позволит впоследствии равномерно форматировать.

Для США удалите добавленную цифру 1 (и определите форматирование на основе длины строки (10 цифр для США)).

2 голосов
/ 16 февраля 2011

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

1 голос
/ 16 февраля 2011

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

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

ОДНАКО, имейте в виду, что телефонные номера в формате XXX-XXX-XXXX можно найти только в США, Канаде и других небольших территориях Карибского бассейна, которые подпадают под действие системы NANPA. Различные регионы мира (ЕС, Африка, АСЕАН) имеют очень разные стандарты нумерации. В таких случаях разделение эквивалента «кода города» может не иметь смысла. Кроме того, если все, что вам нужно, это отобразить номер телефона для пользователя, просто сохраните его в виде строки.

Хранить номер в формате или нет - это в основном личное предпочтение. Сохранение необработанного числа позволяет легко изменять форматирование; Вы можете перейти от XXX-XXX-XXXX к (XXX) XXX-XXXX, изменив пару строк кода вместо того, чтобы переформатировать уже имеющиеся у вас 10 миллионов номеров. Удаление специальных символов из номера телефона также является относительно простым регулярным выражением. Хранение без форматирования также сэкономит вам несколько байтов на число и позволит вам использовать поле фиксированной длины (сохраняя дополнительные накладные расходы, присущие varchars). Это может быть полезно в мобильном приложении, где хранилище стоит дорого. Однако этот 5-терабайтный распределенный кластер SQL в вашей серверной комнате, вероятно, не заметит большой разницы между char (10) и varchar (15). Хранение их в формате также ускоряет загрузку данных; Вам не нужно сначала форматировать его, просто вытяните его из БД и наклейте на страницу.

1 голос
/ 16 февраля 2011

это действительно зависит от пары факторов:

  1. возможно, у вас будут международные номера?
  2. сколько будет выполняться поиск / манипулирование кодом города / кодом города?

Независимо от того, что я буду хранить только числа, достаточно просто отформатировать в MySQL или PHP и добавить скобки и тире.

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

Если возможно, что в будущем вы будете использовать международные номера:

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

1 голос
/ 16 февраля 2011

Я думаю, что разделение числа на 3 поля - лучший вариант, если вы хотите использовать коды городов в качестве фильтров, в противном случае вам следует использовать только 1 поле.

Не забудьте использовать ZEROFILL, если вы планируетесохраняя их как числа;)

1 голос
/ 16 февраля 2011

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

...