데이터베이스 필드에 전화 번호를 저장하기위한 좋은 데이터 구조는 무엇입니까? 국제 전화 번호를 처리 할 수있을만큼 유연하고 번호의 다양한 부분을 효율적으로 쿼리 할 수있는 것을 찾고 있습니다.
편집 : 여기서 사용 사례를 명확히하기 위해 현재 단일 varchar 필드에 숫자를 저장하고 고객이 입력 한 그대로 둡니다. 그런 다음 코드에서 번호가 필요하면 정규화합니다. 문제는 일치하는 전화 번호를 찾기 위해 수백만 개의 행을 쿼리하려는 경우 다음과 같은 기능이 포함된다는 것입니다.
where dbo.f_normalizenum(num1) = dbo.f_normalizenum(num2)
매우 비효율적입니다. 또한 지역 번호와 같은 것을 찾는 쿼리는 단일 varchar 필드 일 때 매우 까다로워집니다.
[편집하다]
사람들은 여기에서 좋은 제안을 많이했습니다. 감사합니다! 업데이트로 지금 내가하고있는 작업은 다음과 같습니다. 입력 한 그대로 숫자를 varchar 필드에 저장하지만 쿼리시 항목을 정규화하는 대신 레코드가 삽입 될 때 모든 작업을 수행하는 트리거가 있습니다. 또는 업데이트되었습니다. 따라서 쿼리해야하는 모든 부분에 대한 int 또는 bigint가 있으며 이러한 필드는 쿼리를 더 빠르게 실행하기 위해 인덱싱됩니다.
답변
첫째, 국가 코드 외에는 실제 표준이 없습니다. 최선의 방법은 특정 전화 번호가 속한 국가를 국가 코드로 인식하고 해당 국가의 형식에 따라 나머지 번호를 처리하는 것입니다.
그러나 일반적으로 전화 장비 등은 표준화되어 있으므로 거의 항상 주어진 전화 번호를 다음 구성 요소로 나눌 수 있습니다.
- 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
할 수 있습니다. 독일과는 다릅니다.
전체 번호를 텍스트 필드 (국제화 포함)로 별도로 저장하여 나중에 돌아가서 상황이 변경 될 때 번호를 다시 구문 분석하거나 누군가가 특정 국가의 형식을 구문 분석하는 잘못된 방법을 제출하는 경우 백업으로 사용할 수도 있습니다. 정보를 잃습니다.
답변
KISS-많은 미국 웹 사이트가 지겨워지고 있습니다. 그들은 우편 번호와 전화 번호를 확인하기 위해 영리하게 작성된 코드를 가지고 있습니다. 완벽하게 유효한 노르웨이 연락처 정보를 입력 할 때 자주 거부되는 것을 발견합니다.
좀 더 고급에 대한 특별한 필요가 없다면 문자열로 남겨 두십시오.
답변
E.164 의 Wikipedia 페이지는 알아야 할 모든 것을 알려줍니다.
답변
제안 된 구조는 다음과 같습니다. 피드백에 감사드립니다.
전화 데이터베이스 필드는 다음 형식의 varchar (42) 여야합니다.
CountryCode-번호 x 내선
예를 들어 미국에서는 다음과 같이 할 수 있습니다.
1-2125551234×1234
이는 지역 번호 / 번호 (212) 555 1234 및 내선 번호 1234가있는 미국 번호 (국가 번호 1)를 나타냅니다.
국가 코드를 대시로 구분하면 데이터를 읽는 사람에게 국가 코드가 명확 해집니다. 이것은 아니다 엄격하게 국가 코드 “가 있기 때문에 필요한 접두사 코드 “(당신이 그들을 왼쪽에서 오른쪽으로 읽을 수 있습니다 당신은 항상 명확하게 국가를 결정할 수있을 것이다). 그러나 국가 코드는 길이가 다양하기 때문에 (현재 1 ~ 4 자 사이) 어떤 구분 기호를 사용하지 않으면 국가 코드를 한 눈에 쉽게 구분할 수 없습니다.
확장을 구분하기 위해 “x”를 사용합니다. 그렇지 않으면 (대부분의 경우) 어느 것이 번호이고 어느 것이 확장인지 알아낼 수 없기 때문입니다.
이러한 방식으로 국가 코드 및 내선 번호를 포함한 전체 번호를 단일 데이터베이스 필드에 저장할 수 있습니다. 그러면 지금까지 힘들게 해왔 던 사용자 정의 함수에 조인하는 대신 쿼리 속도를 높이는 데 사용할 수 있습니다. .
varchar (42)를 선택한 이유는 무엇입니까? 음, 우선 국제 전화 번호는 길이가 다양하므로 “var”가됩니다. 나는 대시와 “x”를 저장하고있다. 그래서 “char”를 설명한다. 어쨌든 당신은 전화 번호에 대해 정수 산술을하지 않을 것이다. . 42의 길이는 Adam Davis의 대답에 따라 합산 된 모든 필드의 가능한 최대 길이를 사용하고 대시와 ‘x’에 2를 더했습니다.
답변
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 필드 옆에 국가 / 국제 형식으로 전화기를 저장하십시오.
심각한 이유가없는 한 별도의 필드에 국가 코드를 저장하지 마십시오. 왜? UI에서 국가 코드를 묻지 말아야하기 때문입니다.
대부분 사람들은 들리는대로 전화기에 들어갑니다. 예를 들어 로컬 형식이 0
또는로 시작 8
하는 경우 사용자가 머리에서 숫자 변환을 수행하는 것이 성 가실 것입니다 (예 : ” 좋아, ‘0’을 입력하지 말고 국가를 선택하고 나머지 사람이이 분야에서 말했다 “).
파싱
Google이 귀하를 지원하고 libphonenumber 를 사용하여 모든 전화 번호를 확인하고 구문 분석 할 수 있습니다. 라이브러리 . 거의 모든 언어에 대한 포트가 있습니다.
따라서 사용자가 ” 0449053501
“또는 ” 04 4905 3501
“또는 ” (04) 4905 3501
“를 입력하도록합니다 . 도구가 나머지를 알아낼 것입니다.
얼마나 많은 도움이되는지 알아 보려면 공식 데모를 참조하십시오 .