데이터베이스에서 중복된 주소를 찾아 사용자가 해당 주소를 조기에 입력하지 못하도록 하시겠습니까?

StackOverflow https://stackoverflow.com/questions/37568

문제

데이터베이스에서 중복된 주소를 찾으려면 어떻게 해야 합니까? 아니면 이미 양식을 작성할 때 사람들을 멈추는 것이 더 좋습니까?빠르면 빠를수록 좋은 것 같은데요?

2개의 등록을 얻으려는 오타와 단순한 시도를 감지할 수 있도록 거리, 우편번호 등을 추상화하는 좋은 방법이 있습니까?좋다:

Quellenstrasse 66/11 
Quellenstr. 66a-11

독일 주소 말하는 중인데...감사해요!

도움이 되었습니까?

해결책

요하네스:

@PConroy:이것은 나의 초기 생각이기도 했다.여기서 흥미로운 부분은 주소의 다양한 부분에 대한 좋은 변환 규칙을 찾는 것입니다!좋은 제안이 있나요?

이전에 이러한 유형의 프로젝트를 작업할 때 우리의 접근 방식은 기존 주소 모음(150,000개 정도)을 가져온 다음 도메인에 가장 일반적인 변환(아일랜드이므로 "Dr"->"Drive", ")을 적용하는 것이었습니다. Rd"->"도로" 등).유감스럽게도 당시에는 그러한 것에 대한 포괄적인 온라인 리소스가 없었기 때문에 기본적으로 우리는 전화번호부 같은 항목을 확인하면서 기본적으로 목록을 스스로 작성하게 되었습니다. (공간이 부족하여 주소가 온갖 방법으로 축약되었습니다!) ).앞서 언급했듯이 몇 가지 일반적인 규칙만 추가하면 얼마나 많은 "중복"을 감지할 수 있는지 놀라실 것입니다!

나는 최근 꽤 포괄적인 내용이 포함된 페이지를 우연히 발견했습니다. 주소 약어 목록, 미국식 영어인데 독일에서는 얼마나 도움이 될지 모르겠네요!구글링을 통해 몇 개의 사이트를 찾았지만 스팸성 뉴스레터 가입 트랩처럼 보였습니다.비록 제가 영어로 인터넷 검색을 하고 있었지만, 독일어로 된 "독일어 주소 약어"를 통해 더 많은 정보를 보실 수 있습니다 :)

다른 팁

당신은 구글 지오코드 API

실제로 두 예제 모두에 대한 결과를 제공하므로 시도해 보십시오.이렇게 하면 데이터베이스에 저장할 수 있는 구조화된 결과를 얻을 수 있습니다.조회에 실패하면 사용자에게 다른 방법으로 주소를 쓰도록 요청하세요.

사람들을 더 일찍 막을수록 장기적으로는 더 쉬워질 것입니다!

DB 스키마나 데이터 입력 양식에 익숙하지 않은 경우 다음과 같은 경로를 제안합니다.

  • 각 주소 "부분"에 대해 DB에 고유한 필드가 있습니다.거리, 도시, 우편번호, 주 등

  • 데이터 입력 양식을 비슷하게 분류하십시오.거리, 도시 등

위의 이유는 각 부분이 약간 변경된 주소를 확인하기 위한 고유한 "규칙"을 가질 가능성이 높기 때문입니다(위의 "Quellenstrasse"->"Quellenstr.", "66/11"->"66a-11"). 따라서 유효성 검사 코드는 각 필드에 표시된 값이 해당 DB 필드에 존재하는지 확인할 수 있습니다.그렇지 않은 경우 주어진 각 필드에 변환 규칙을 적용하는 클래스를 가질 수 있습니다(예:"strasse"는 "str"로 파생됨) 중복이 있는지 다시 확인합니다.

분명히 위의 방법에는 단점이 있습니다.

  • 데이터 세트에 따라 속도가 느려지고 사용자가 기다리게 될 수 있습니다.

  • 사용자는 잘못된 필드에 주소 "부품"을 입력하여 문제를 해결하려고 할 수 있습니다(도시에 우편번호 추가 등).하지만 경험상 위와 같은 간단한 검사만 도입해도 대다수의 사용자가 기존 주소를 입력하는 것을 방지할 수 있다는 사실을 발견했습니다.

기본 점검이 완료되면 필요한 DB 액세스 최적화, 규칙 개선 등을 검토하여 특정 스키마를 충족할 수 있습니다.다음을 살펴보실 수도 있습니다. MySQL의 match() 함수 비슷한 텍스트를 작업하기 위해.

데이터베이스에서 중복 주소 검색을 시작하기 전에 먼저 주소를 표준 형식으로 저장해야 합니다.

대부분의 국가에는 주소 형식을 지정하는 표준 방법이 있으며, 미국에서는 USPS CASS 시스템을 사용합니다. http://www.usps.com/ncsc/addressservices/certprograms/cass.htm

그러나 대부분의 다른 국가에는 유사한 서비스/표준이 있습니다.더 많은 국제 형식을 보려면 이 사이트를 사용해 보세요.http://bitboost.com/ref/international-address-formats.html

이는 중복 항목을 찾는 데 도움이 될 뿐만 아니라 고객에게 우편으로 보낼 때 비용도 절약해 줍니다(주소가 표준 형식이면 우편 서비스 요금이 더 저렴합니다).

애플리케이션에 따라 어떤 경우에는 표준 주소 레코드뿐만 아니라 "가상" 주소 레코드를 저장해야 할 수도 있습니다.이를 통해 VIP 고객을 만족시킬 수 있습니다."가상" 주소는 다음과 같습니다.

62 웨스트 나인티 퍼스트 스트리트
아파트 4D
맨해튼, 뉴욕, NY 10001

표준 주소는 다음과 같습니다.

62W 91ST ST APT 4D
뉴욕 뉴욕 10024-1414

당신이 살펴보고 싶은 한 가지는 사운드덱스 철자 오류 및 축약어에 매우 유용한 검색입니다.

그러나 이는 데이터베이스 내 유효성 검사가 아니므로 원하는 것일 수도 있고 아닐 수도 있습니다.

또 다른 가능한 해결책(실제로 신뢰할 수 있는 주소 데이터가 필요하고 중복 계정을 방지하기 위한 방법으로 주소를 사용하는 것이 아니라고 가정)은 타사 웹 서비스를 사용하여 사용자가 제공한 주소를 표준화하는 것입니다.

이런 방식으로 작동합니다. 시스템은 온라인 양식을 통해 사용자의 주소를 받아들입니다.귀하의 양식은 사용자의 주소를 제3자 주소 표준화 웹 서비스에 전달합니다.웹 서비스는 동일한 주소를 제공하지만 이제는 데이터가 개별 주소 필드로 표준화되고 표준 약어 및 형식이 적용됩니다.애플리케이션은 DB에 데이터를 저장하기 전에 확인을 위해 이 표준화된 주소를 사용자에게 표시합니다.

모든 사용자 주소가 표준화 단계를 거쳐 표준화된 주소만 DB에 저장되면 사과와 사과를 비교하므로 중복 레코드 찾기가 크게 단순화되어야 합니다.

그러한 제3자 서비스 중 하나는 Global Address의 인터랙티브 서비스 지원되는 국가 목록에 독일이 포함되어 있으며 서비스 작동 방식을 보여주는 온라인 데모도 있습니다(데모 링크는 해당 웹 페이지에서 찾을 수 있음).

이 접근 방식에는 분명히 비용상의 단점이 있습니다.그러나 긍정적인 측면은 다음과 같습니다.

  1. 자체 주소 표준화 메타데이터를 생성하고 유지 관리할 필요가 없습니다.
  2. 주소 표준화 루틴을 지속적으로 향상시킬 필요가 없습니다.
  3. 귀하는 귀하의 요구 사항에 맞는 고유한 애플리케이션 부분에 소프트웨어 개발 에너지를 자유롭게 집중할 수 있습니다.

부인 성명:저는 Global Address에서 근무하지 않으며 해당 서비스를 사용해 본 적이 없습니다.실제로 플레이할 수 있는 온라인 데모가 있기 때문에 단지 예를 들어 언급하는 것뿐입니다.

내 질문에 답변을 추가하려면:

다른 방법은 사용자에게 휴대폰 번호를 묻고 확인을 위해 문자 메시지를 보내는 것입니다.이렇게 하면 대부분의 사람들이 중복된 주소로 장난을 치는 것을 막을 수 있습니다.

나는 개인적인 경험에서 이야기하고 있습니다.(감사해요 돼지등 !) 휴대폰을 통한 확인을 도입했습니다.이로 인해 계정이 2개가 없어졌습니다!:-)

원본 게시물이 독일 주소에만 적용된다는 것을 알고 있지만 이는 일반적인 주소에 대한 좋은 질문입니다.

미국에는 배송지 바코드라는 주소 부분이 있습니다.이는 단일 배송 지점을 식별하고 주소의 고유 식별자 역할을 할 수 있는 고유한 12자리 숫자입니다.이 값을 얻으려면 주소 확인 또는 주소 표준화 웹 서비스 API를 사용하는 것이 좋습니다. 이 API는 요청량에 따라 월 20달러 정도 비용이 들 수 있습니다.

완전한 공개를 위해 저는 SmartyStreets의 창립자입니다.우리는 바로 그러한 것을 제공합니다 주소 검증 웹 서비스 API LiveAddress라고 합니다.궁금한 점이 있으면 개인적으로 저에게 연락해 주세요.

기계 학습과 AI에는 문자열 유사성과 중복 측정값을 찾는 알고리즘이 있습니다.

레코드 연결 또는 동등한 레코드를 일치시키는 작업 구문론적으로 다른 것은 1950년대 후반에 처음 탐구되었습니다 그리고 1960년대.

의 벡터를 사용하여 모든 레코드 쌍을 나타낼 수 있습니다. 개별 레코드 필드 간의 유사성을 설명하는 기능입니다.

예를 들어, 학습 가능한 문자열을 사용한 적응형 중복 감지 유사성 측정.예를 들어, 이 문서를 읽어보세요

  1. 잠재적 중복의 유사성을 추정하기 위해 일반 또는 수동으로 조정된 거리 측정법을 사용할 수 있습니다.

  2. 두 문자열 사이의 공통 문자 수와 순서를 기반으로 하는 Jaro 메트릭과 같은 적응형 이름 일치 알고리즘을 사용할 수 있습니다.

  3. 토큰 기반 및 하이브리드 거리.이러한 경우 문자열 s 및 t를 토큰 다중 집합(각 토큰이 단어인 경우)에 추가하고 이러한 다중 집합에 대한 유사성 메트릭을 고려합니다.

데이터 기반 의미에서 데이터가 "고유"하도록 보장하기 위해 데이터베이스에서 제약 조건을 사용하는 경우가 많습니다.

"동형"에 관해서는 당신이 스스로 코드를 작성해야 한다고 생각합니다.데이터베이스에 있으면 트리거를 사용할 수 있습니다.

미국 주소로 된 답변을 찾고 있습니다.

문제의 문제는 사용자가 다음과 같은 중복 항목을 입력하지 못하게 하는 것입니다.

Quellenstrasse 66/11 그리고 Quellenstr. 66a-11

이는 사용자가 입력 상자에 전체 주소를 입력하도록 허용한 경우 발생합니다.

이를 방지하기 위해 사용할 수 있는 몇 가지 방법이 있습니다.

1.RegEx를 사용한 균일한 형식 지정

  • 사용자에게 일정한 형식으로 세부 정보를 입력하라는 메시지를 표시할 수 있습니다.
  • 쿼리하는 동안에도 매우 효율적입니다.
  • 일부 정규식에 대해 사용자가 입력한 값을 테스트하고 실패하면 사용자에게 수정하도록 요청합니다.

2. Google 지도와 같은 지도 API를 사용하고 사용자에게 세부정보를 선택하도록 요청하세요.

  • Google 지도를 선택하면 역지오코딩을 사용하여 지도를 얻을 수 있습니다.

에서 Google 개발자 가이드,

지오코딩이라는 용어는 일반적으로 사람이 읽을 수 있는 주소를 지도상의 위치로 변환하는 것을 의미합니다. 지도상의 위치를 ​​사람이 읽을 수 있는 주소로 변환하는 반대 프로세스를 다음과 같이 알려져 있습니다. 역지오코딩.

삼.질문에 표시된 대로 이질적인 데이터를 허용하고 이를 다른 형식과 비교합니다.

  • 질문에서 OP는 다른 형식의 주소를 허용합니다.
  • 이러한 경우에는 다른 형태로 변경하여 데이터베이스로 확인하여 해결방안을 찾아보실 수 있습니다.
  • 시간이 더 걸릴 수 있으며 시간은 전적으로 테스트 사례 수에 따라 다릅니다.

4.주소를 여러 부분으로 분할하여 db에 저장하고 해당 형식을 사용자에게 제공합니다.

  • 즉, 거리, 도시, 주 등을 데이터베이스에 저장할 수 있는 다양한 필드를 제공합니다.
  • 또한 사용자가 거리, 도시, 주 등을 하향식 형식으로 입력할 수 있도록 다양한 입력 필드를 제공합니다.
  • 사용자가 상태를 입력하면 해당 상태에 대해서만 속이는 항목을 찾도록 쿼리 범위를 좁힙니다.
  • 사용자가 도시를 입력하면 해당 도시로만 범위를 좁힙니다.
  • 사용자가 거리에 진입하면 해당 거리로 범위를 좁힙니다.

그리고 마지막으로

  • 사용자가 주소를 입력하면 이를 다른 형식으로 변경하고 데이터베이스와 비교하여 테스트하십시오.

이는 테스트 사례 수가 많더라도 효율적이며, 테스트하는 항목 수가 매우 적으므로 시간이 매우 적게 소모됩니다.

미국에서는 USPS를 이용할 수 있습니다. 주소 표준화 웹 도구.주소를 확인하고 정규화합니다.이렇게 하면 주소가 데이터베이스에 이미 존재하는지 확인하기 전에 주소를 정규화할 수 있습니다.데이터베이스의 모든 주소가 이미 정규화되어 있으면 중복된 주소를 쉽게 찾을 수 있습니다.

샘플 URL:

https://production.shippingapis.com/ShippingAPI.dll?API=Verify&XML=insert_request_XML_here

샘플 요청:

<AddressValidateRequest USERID="XXXXX">
  <IncludeOptionalElements>true</IncludeOptionalElements>
  <ReturnCarrierRoute>true</ReturnCarrierRoute>
  <Address ID="0">  
    <FirmName />   
    <Address1 />   
    <Address2>205 bagwell ave</Address2>   
    <City>nutter fort</City>   
    <State>wv</State>   
    <Zip5></Zip5>   
    <Zip4></Zip4> 
  </Address>      
</AddressValidateRequest>

샘플 응답:

<AddressValidateResponse>
  <Address ID="0">
    <Address2>205 BAGWELL AVE</Address2>
    <City>NUTTER FORT</City>
    <State>WV</State>
    <Zip5>26301</Zip5>
    <Zip4>4322</Zip4>
    <DeliveryPoint>05</DeliveryPoint>
    <CarrierRoute>C025</CarrierRoute>
  </Address>
</AddressValidateResponse>

다른 국가에는 자체 API가 있을 수 있습니다.다른 사람들은 경우에 따라 유용할 수 있는 여러 국가를 지원하는 타사 API를 언급했습니다.

Google이 검색 제안을 가져오면 데이터베이스 주소 필드를 검색할 수 있습니다.

먼저 index.htm(l) 파일을 만들어 보겠습니다.

    <!DOCTYPE html>
    <html lang="en">

    <head>
        <meta http-equiv="Content-Language" content="en-us">
        <title>Address Autocomplete</title>
        <meta charset="utf-8">
        <link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet">
        <script src="//code.jquery.com/jquery-2.1.4.min.js"></script>
        <script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
        <script src="//netsh.pp.ua/upwork-demo/1/js/typeahead.js"></script>
        <style>
            h1 {
                font-size: 20px;
                color: #111;
            }

            .content {
                width: 80%;
                margin: 0 auto;
                margin-top: 50px;
            }

            .tt-hint,
            .city {
                border: 2px solid #CCCCCC;
                border-radius: 8px 8px 8px 8px;
                font-size: 24px;
                height: 45px;
                line-height: 30px;
                outline: medium none;
                padding: 8px 12px;
                width: 400px;
            }

            .tt-dropdown-menu {
                width: 400px;
                margin-top: 5px;
                padding: 8px 12px;
                background-color: #fff;
                border: 1px solid #ccc;
                border: 1px solid rgba(0, 0, 0, 0.2);
                border-radius: 8px 8px 8px 8px;
                font-size: 18px;
                color: #111;
                background-color: #F1F1F1;
            }
        </style>
        <script>
            $(document).ready(function() {

                $('input.city').typeahead({
                    name: 'city',
                    remote: 'city.php?query=%QUERY'

                });

            })
        </script>

    <script>
            function register_address()
            {
                $.ajax({
                    type: "POST",
                    data: {
                        City: $('#city').val(),
                    },
                    url: "addressexists.php",
                    success: function(data)
                    {
                        if(data === 'ADDRESS_EXISTS')
                        {
                            $('#address')
                                .css('color', 'red')
                                .html("This address already exists!");
                        }

                    }
                })              
            }
        </script>
    </head>

    <body>
        <div class="content">

            <form>
                <h1>Try it yourself</h1>
                <input type="text" name="city" size="30" id="city" class="city" placeholder="Please Enter City or ZIP code">
<span id="address"></span>
            </form>
        </div>
    </body>
</html>

이제 쿼리를 MySQL DB에 집계하고 JSON으로 응답을 제공하는 city.php 파일을 생성하겠습니다.코드는 다음과 같습니다.

<?php

//CREDENTIALS FOR DB
define ('DBSERVER', 'localhost');
define ('DBUSER', 'user');
define ('DBPASS','password');
define ('DBNAME','dbname');

//LET'S INITIATE CONNECT TO DB
$connection = mysqli_connect(DBSERVER, DBUSER, DBPASS,"DBNAME") or die("Can't connect to server. Please check credentials and try again");


//CREATE QUERY TO DB AND PUT RECEIVED DATA INTO ASSOCIATIVE ARRAY
if (isset($_REQUEST['query'])) {
    $query = $_REQUEST['query'];
    $sql = mysqli_query ($connection ,"SELECT zip, city FROM zips WHERE city LIKE '%{$query}%' OR zip LIKE '%{$query}%'");
    $array = array();
    while ($row = mysqli_fetch_array($sql,MYSQLI_NUM)) {
        $array[] = array (
            'label' => $row['city'].', '.$row['zip'],
            'value' => $row['city'],
        );
    }
    //RETURN JSON ARRAY
    echo json_encode ($array);
}

?>

그런 다음 테이블 열에 중복이 발견되면 데이터베이스에 저장하지 못하게 합니다.

그리고 addressexists.php 코드의 경우:

<?php//CREDENTIALS FOR DB
    define ('DBSERVER', 'localhost');
    define ('DBUSER', 'user');
    define ('DBPASS','password');
    define ('DBNAME','dbname');

    //LET'S INITIATE CONNECT TO DB
    $connection = mysqli_connect(DBSERVER, DBUSER, DBPASS,"DBNAME") or die("Can't connect to server. Please check credentials and try again");


    $city= mysqli_real_escape_string($_POST['city']); // $_POST is an array (not a function)
    // mysqli_real_escape_string is to prevent sql injection

    $sql = "SELECT username FROM ".TABLENAME." WHERE city='".$city."'"; // City must enclosed in two quotations

    $query = mysqli_query($connection,$sql);

    if(mysqli_num_rows($query) != 0)

    {
        echo('ADDRESS_EXISTS');
    }
?>

중복을 감지하려면 주소를 DET BundesPost에서 제공한 주소와 일치시키세요.

DET는 아마도 미국처럼 CD를 판매할 것입니다.그러면 문제는 Bundespost 주소와 일치하게 됩니다.약어를 사후 승인된 약어 등으로 대체하는 긴 과정입니다.

미국에서도 마찬가지다.중복된 주소를 찾으려면 USPostOffice 주소와 일치하십시오(비용이 많이 들기 때문에 완전히 공개된 CD는 미국 우체국에서 구할 수 없습니다).

이것은 오래된 질문이지만 또 다른 접근 방식은 주소까지의 Levenshtein 거리를 계산하는 것입니다. 이 방법을 사용하면 매우 유사한 기존 주소를 찾을 수 있습니다.여기에서 더 많은 내용을 볼 수 있습니다. SQL에서 Levenshtein 거리 측정법을 사용하여 중복 주소 찾기

제 생각에는 DB에 이미 많은 더티 데이터가 있다고 가정하면,

최대 독일어 약어를 감지할 수 있는 "수제" 더티 필터를 만들어야 합니다.

하지만 많은 양의 데이터를 처리하면 위양성 샘플과 참음성 샘플을 찾을 위험이 있습니다.

마지막으로 반자동 작업(위양성 또는 진음성 가능성이 너무 높을 때 인간의 도움을 받는 기계)이 최선의 솔루션이 될 것입니다.

"예외"를 더 많이 처리하면(데이터를 채울 때 사람이 예외를 발생시키므로) "수제" 필터가 요구 사항에 더 적합할 것입니다.

반면에, 사용자 측에서는 독일 주소 확인 서비스를 사용하고, 확인된 주소만 저장할 수도 있습니다...

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top