encontrar endereços duplicados no banco de dados e impedir que os usuários os insiram antecipadamente?

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

Pergunta

Como encontro endereços duplicados em um banco de dados, ou é melhor parar as pessoas já ao preencher o formulário?Acho que quanto mais cedo melhor?

Existe alguma boa maneira de abstrair rua, código postal, etc., para que erros de digitação e tentativas simples de obter 2 registros possam ser detectados?como:

Quellenstrasse 66/11 
Quellenstr. 66a-11

Estou falando de endereços alemães...Obrigado!

Foi útil?

Solução

João:

@PConroy:Este foi meu pensamento inicial também.a parte interessante disso é encontrar boas regras de transformação para as diferentes partes do endereço!Alguma boa sugestão?

Quando estávamos trabalhando nesse tipo de projeto antes, nossa abordagem era pegar nosso corpus existente de endereços (150 mil ou mais) e, em seguida, aplicar as transformações mais comuns para nosso domínio (Irlanda, então "Dr"->"Drive", " Rd"->"Estrada", etc.).Receio que não houvesse nenhum recurso on-line abrangente para essas coisas na época, então acabamos basicamente criando uma lista nós mesmos, verificando coisas como a lista telefônica (pressionado por espaço lá, os endereços são abreviados de todas as maneiras! ).Como mencionei anteriormente, você ficaria surpreso com quantas “duplicatas” você detectaria com a adição de apenas algumas regras comuns!

Recentemente me deparei com uma página com uma descrição bastante abrangente lista de abreviações de endereço, embora seja inglês americano, não tenho certeza de quão útil seria na Alemanha!Uma rápida pesquisa no Google revelou alguns sites, mas eles pareciam armadilhas de inscrição em boletins informativos com spam.Embora eu tenha pesquisado no Google em inglês, você pode dar uma olhada mais de perto em "abreviações de endereço em alemão" em alemão :)

Outras dicas

Você poderia usar o API GeoCode do Google

O que de fato dá resultados para ambos os seus exemplos, apenas tentei.Dessa forma você obtém resultados estruturados que podem ser salvos em seu banco de dados.Se a pesquisa falhar, peça ao usuário para escrever o endereço de outra forma.

Quanto mais cedo você parar as pessoas, mais fácil será no longo prazo!

Não estando muito familiarizado com seu esquema de banco de dados ou formulário de entrada de dados, sugiro uma rota parecida com a seguinte:

  • tenha campos distintos em seu banco de dados para cada "parte" do endereço, por exemplo.rua, cidade, código postal, Länder, etc.

  • tenha seu formulário de entrada de dados dividido de forma semelhante, por ex.rua, cidade, etc.

O raciocínio por trás do acima exposto é que cada parte provavelmente terá suas próprias "regras" específicas para verificar endereços ligeiramente alterados ("Quellenstrasse"->"Quellenstr.", "66/11"->"66a-11" acima) para que seu código de validação possa verificar se os valores apresentados para cada campo existem em seus respectivos campos de banco de dados.Caso contrário, você pode ter uma classe que aplique as regras de transformação para cada campo específico (por exemplo"strasse" resultou em "str") e verifica novamente se há duplicatas.

Obviamente, o método acima tem suas desvantagens:

  • pode ser lento, dependendo do seu conjunto de dados, deixando o usuário esperando

  • os usuários podem tentar contornar isso colocando o endereço "Partes" nos campos errados (anexando o código postal à cidade, etc.).mas, por experiência, descobrimos que a introdução de uma verificação simples como a acima impedirá que uma grande porcentagem de usuários insira endereços pré-existentes.

Depois de realizar a verificação básica, você poderá otimizar os acessos ao banco de dados necessários, refinar as regras, etc., para atender ao seu esquema específico.Você também pode dar uma olhada Função match() do MySQL para elaborar um texto semelhante.

Antes de começar a procurar endereços duplicados em seu banco de dados, primeiro certifique-se de armazenar os endereços em um formato padrão.

A maioria dos países tem uma forma padrão de formatação de endereços; nos EUA, é o sistema USPS CASS: http://www.usps.com/ncsc/addressservices/certprograms/cass.htm

Mas a maioria dos outros países tem um serviço/padrão semelhante.Experimente este site para mais formatos internacionais:http://bitboost.com/ref/international-address-formats.html

Isso não apenas ajuda a encontrar duplicatas, mas também economiza dinheiro ao enviar correspondências aos clientes (o serviço postal cobra menos se o endereço estiver em um formato padrão).

Dependendo da sua aplicação, em alguns casos você pode querer armazenar um registro de endereço "personalizado", bem como o registro de endereço padrão.Isso mantém seus clientes VIP satisfeitos.Um endereço "vaidade" pode ser algo como:

Rua Noventa e Um Oeste, 62
Apartamento 4D
Manhattan, Nova York, NY 10001

Embora o endereço padrão possa ser assim:

62 W 91ST ST APTO 4D
NOVA IORQUE NY 10024-1414

Uma coisa que você pode querer observar é Soundex pesquisas, que são bastante úteis para erros ortográficos e contrações.

No entanto, isso não é uma validação no banco de dados, portanto pode ou não ser o que você está procurando.

Outra solução possível (supondo que você realmente precise de dados de endereço confiáveis ​​e não esteja usando endereços apenas como forma de evitar contas duplicadas) é usar um serviço web de terceiros para padronizar os endereços fornecidos por seus usuários.

Funciona desta forma: seu sistema aceita o endereço de um usuário por meio de um formulário online.Seu formulário transfere o endereço do usuário para o serviço web de padronização de endereços de terceiros.O serviço web retorna o mesmo endereço, mas agora com os dados padronizados em campos de endereço distintos e com abreviações e formatos padrão aplicados.Seu aplicativo exibe esse endereço padronizado ao usuário para confirmação antes de tentar salvar os dados em seu banco de dados.

Se todos os endereços de usuários passarem por uma etapa de padronização e apenas endereços padronizados forem salvos em seu banco de dados, a localização de registros duplicados deverá ser bastante simplificada, pois agora você está comparando maçãs com maçãs.

Um desses serviços de terceiros é Serviço interativo da Global Address que inclui a Alemanha na lista de países suportados, e também tem uma demonstração online que demonstra como funciona o seu serviço (o link da demonstração pode ser encontrado nessa página web).

Há uma desvantagem de custo nessa abordagem, obviamente.No entanto, do lado positivo:

  1. você não precisaria criar e manter seus próprios metadados de padronização de endereço
  2. você não precisará aprimorar continuamente suas rotinas de padronização de endereços e
  3. você está livre para concentrar sua energia de desenvolvimento de software nas partes do aplicativo que são exclusivas para seus requisitos

Isenção de responsabilidade:Não trabalho para a Global Address e não tentei usar o serviço deles.Estou apenas mencionando-os como exemplo, pois eles têm uma demonstração online com a qual você pode realmente jogar.

Para adicionar uma resposta à minha própria pergunta:

Uma maneira diferente de fazer isso é pedir aos usuários o número do celular e enviar uma mensagem de texto para verificação.Isso impede que a maioria das pessoas mexa com endereços duplicados.

Estou falando por experiência pessoal.(obrigado porco !) Eles introduziram a confirmação através do celular.Isso me impediu de ter 2 contas!:-)

Sei que a postagem original é específica para endereços alemães, mas esta é uma boa pergunta para endereços em geral.

Nos Estados Unidos, existe uma parte de um endereço chamada código de barras do ponto de entrega.É um número exclusivo de 12 dígitos que identifica um único ponto de entrega e pode servir como identificador exclusivo de um endereço.Para obter esse valor, você desejará usar uma API de serviço da web de verificação de endereço ou padronização de endereço, que pode custar cerca de US$ 20/mês, dependendo do volume de solicitações feitas a ela.

No interesse da divulgação completa, sou o fundador do SmartyStreets.Oferecemos exatamente esse API de serviço web de validação de endereço chamado LiveAddress.Você é mais que bem-vindo para entrar em contato comigo pessoalmente caso tenha alguma dúvida.

O aprendizado de máquina e a IA possuem algoritmos para encontrar semelhanças de strings e medidas duplicadas.

O vínculo de registro ou a tarefa de corresponder registros equivalentes que diferem sintaticamente - foi explorada pela primeira vez no final dos anos 1950 e 1960.

Você pode representar todos os pares de registros usando um vetor de recursos que descrevem a semelhança entre os campos de registro individuais.

Por exemplo, detecção duplicada adaptativa usando medidas de similaridade de cordas aprendidas.por exemplo, leia este documento

  1. Você pode usar métricas de distância genéricas ou ajustadas manualmente para estimar a similaridade de possíveis duplicatas.

  2. Você pode usar algoritmos adaptativos de correspondência de nomes, como a métrica Jaro, que se baseia no número e na ordem de caracteres comuns entre duas strings.

  3. Distância híbrida e baseada em token.Nesses casos, podemos converter as cordas s e t em multisets token (onde cada token é uma palavra) e considerar métricas de similaridade nesses multisets.

Freqüentemente, você usa restrições em um banco de dados para garantir que os dados sejam "únicos" no sentido baseado em dados.

Em relação aos "isomorfismos", acho que você está por conta própria, ou seja, escrevendo o código sozinho.Se estiver no banco de dados você poderia usar um gatilho.

Estou procurando uma resposta abordando endereços nos Estados Unidos

O problema em questão é evitar que os usuários insiram duplicatas como

Quellenstrasse 66/11 e Quellenstr. 66a-11

Isso acontece quando você permite que o usuário insira o endereço completo na caixa de entrada.

Existem alguns métodos que você pode usar para evitar isso.

1.Formatação uniforme usando RegEx

  • Você pode solicitar que os usuários insiram os detalhes em um formato uniforme.
  • Isso é muito eficiente durante a consulta também
  • teste o valor inserido pelo usuário em relação a algumas expressões regulares e, se falhar, peça ao usuário para corrigi-lo.

2. Use uma API de mapa como o Google Maps e peça ao usuário para selecionar detalhes dela.

  • Se você escolher o Google Maps, poderá consegui-lo usando a geocodificação reversa.

De Guia do desenvolvedor do Google,

O termo geocodificação geralmente se refere à tradução de um endereço legível por humanos em um local em um mapa. O processo de fazer o oposto, traduzindo uma localização no mapa em um endereço legível por humanos, é conhecido como geocodificação reversa.

3.Permita dados heterogêneos conforme mostrado na pergunta e compare-os com formatações diferentes.

  • Na pergunta, o OP permite endereço em formato diferente.
  • Nesse caso, você pode alterá-lo para diferentes formatos e verificar no banco de dados para obter uma solução.
  • Isso pode levar mais tempo e depende totalmente do número de casos de teste.

4.Divida o endereço em partes diferentes, armazene-o em banco de dados e forneça esse formulário ao usuário.

  • Isso fornece diferentes campos para armazenar Rua, cidade, estado etc. no banco de dados.
  • Forneça também os diferentes campos de entrada ao usuário para inserir rua, cidade, estado, etc. no formato de cima para baixo.
  • Quando o usuário entra no estado, restrinja a consulta para encontrar ingênuos apenas para esse estado.
  • Quando o usuário insere a cidade, restrinja-o apenas a essa cidade.
  • Quando o usuário entrar na rua, restrinja-o a essa rua.

E finalmente

  • Quando o usuário inserir o endereço, altere-o para formatos diferentes e teste-o no banco de dados.

Isso é eficiente, mesmo que o número de casos de teste seja alto, o número de entradas testadas será muito menor e, portanto, consumirá muito menos tempo.

Nos EUA, você pode usar o USPS Ferramenta Web de padronização de endereços.Ele verifica e normaliza endereços para você.Dessa forma, você pode normalizar o endereço antes de verificar se ele já existe no banco de dados.Se todos os endereços no banco de dados já estiverem normalizados, você poderá detectar duplicatas facilmente.

URL de exemplo:

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

Pedido de amostra:

<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>

Exemplo de resposta:

<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>

Outros países podem ter as suas próprias APIs.Outras pessoas mencionaram APIs de terceiros que oferecem suporte a vários países e que podem ser úteis em alguns casos.

Como o Google busca sugestões para pesquisa, você pode pesquisar campos de endereço do banco de dados

Primeiro, vamos criar um arquivo 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>

Agora criaremos um arquivo city.php que agregará nossa consulta ao banco de dados MySQL e dará resposta como JSON.Aqui está o código:

<?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);
}

?>

e, em seguida, evite salvá-los no banco de dados se forem encontrados duplicados na coluna da tabela

E para o seu código 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');
    }
?>

Combine o endereço com os endereços fornecidos pelo DET BundesPost para detectar duplicatas.

O DET provavelmente vende um CD como os EUA.O problema então passa a ser a correspondência com os endereços do Bundespost.Apenas um longo processo de substituição de abreviaturas por abreviações pós-aprovadas e tal.

Da mesma forma nos EUA.Combine com os endereços do USPostOffice (desculpe, eles custam dinheiro, então seus CDs não totalmente abertos estão disponíveis nos correios dos EUA) para encontrar duplicatas.

Essa é uma questão antiga, mas outra abordagem é calcular a distância de Levenshtein até os endereços e assim você poderá encontrar endereços já existentes que sejam muito semelhantes.Você pode ver mais aqui. Encontrando endereços duplicados usando a métrica de distância de Levenshtein em SQL.

Na minha opinião, supondo que você já tenha muitos dados sujos no seu banco de dados,

Você tem que construir seu filtro sujo "feito à mão" que poderá detectar no máximo a abreviação alemã ...

Mas se você tratar muitos dados, correrá o risco de encontrar algumas amostras falso-positivas e verdadeiro-negativas...

Finalmente um trabalho semiautomático (máquina com assistência humana quando a probabilidade de um caso de falso-positivo ou verdadeiro-negativo for muito alta) será a melhor solução.

Quanto mais você trata a "exceção" (porque o humano gera exceção ao preencher os dados), mais o seu filtro "feito à mão" atenderá às suas necessidades.

Por outro lado, você também pode usar um serviço de verificação de endereço na Alemanha do lado do usuário e armazenar apenas o verificado...

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top