在数据库中找到重复的地址,阻止用户提前输入它们?

时间:2008-09-01 07:30:48

标签: database sanitization street-address

如何在数据库中找到重复的地址,或者在填写表单时更好地阻止人们?我想越早越好?

有没有什么好方法可以抽象街道,邮政编码等,以便可以检测到错别字和简单的尝试获得2次注册?喜欢:

Quellenstrasse 66/11 
Quellenstr. 66a-11

我在说德语地址...... 谢谢!

16 个答案:

答案 0 :(得分:10)

您可以使用Google GeoCode API

实际上,这两个例子都给出了结果,只是试了一下。这样您就可以获得可以保存在数据库中的结构化结果。如果查找失败,请让用户以另一种方式写入地址。

答案 1 :(得分:6)

越早阻止别人,从长远来看就越容易!

不太熟悉您的数据库架构或数据输入表单,我建议的路线如下:

  • 在数据库中为每个地址“部分”设置不同的字段,例如街道,城市,邮政编码,Länder等。

  • 将您的数据输入表单分类,例如街道,城市等

上述背后的原因是,每个部分都可能拥有自己特定的“规则”来检查稍微改变的地址,(“Quellenstrasse” - >“Quellenstr。”,“66/11” - >“66a -11“以上)所以你的验证码可以检查每个字段的值是否存在于各自的db字段中。如果没有,你可以有一个类,为每个给定的字段应用转换规则(例如,“strasse”被阻止为“str”)并再次检查重复项。

显然上述方法有其缺点:

  • 它可能很慢,具体取决于您的数据集,让用户等待

  • 用户可以尝试通过将地址“部件”放在错误的字段中(将邮政代码附加到城市等)来绕过它。 但根据经验,我们发现即使是如上所述的简单检查也会阻止大部分用户输入预先存在的地址。

完成基本检查后,您可以查看优化所需的数据库访问,优化规则等以满足您的特定模式。您也可以查看MySQL's match() function来制作类似的文字。

答案 2 :(得分:4)

  

约翰内斯:

     
    

@PConroy:这也是我最初的时候了。有趣的是,要找到地址不同部分的良好转换规则!有什么好的建议吗?

  

当我们之前处理这类项目时,我们的方法是采用我们现有的地址语料库(150k左右),然后对我们的域应用最常见的转换(爱尔兰,所以“Dr” - >“驾驶“,”Rd“ - >”道路“等)。我担心当时没有全面的在线资源可用,所以我们自己最终基本上都会列出一个列表,检查电话簿(在那里按空格键,地址以各种方式缩写! )。正如我之前提到的,只要添加一些常用规则,你就会惊讶地发现有多少“重复”!

我最近偶然发现了一个相当全面的list of address abbreviations页面,虽然它是美国英语,所以我不确定它在德国会有多大用处!一个快速的谷歌出现了几个网站,但他们似乎垃圾邮件通讯注册陷阱。虽然那是我用英语搜索谷歌,所以你可能会更多地看看德语中的“德语地址缩写”:)

答案 3 :(得分:2)

在开始在数据库中搜索重复地址之前,首先应确保以标准格式存储地址。

大多数国家都有标准的地址格式化方式,在美国它是USPS CASS系统:http://www.usps.com/ncsc/addressservices/certprograms/cass.htm

但大多数其他国家/地区都有类似的服务/标准。试试这个网站以获得更多国际格式: http://bitboost.com/ref/international-address-formats.html

这不仅有助于查找重复项,还可以在邮寄给客户时节省资金(如果地址采用标准格式,邮政服务费用会减少)。

根据您的应用程序,在某些情况下,您可能希望存储“虚荣”地址记录以及标准地址记录。这可以让您的VIP客户满意。 “虚荣”地址可能类似于:

西九十一街62号 4D公寓
曼哈顿,纽约,NY 10001

虽然标准地址可能如下所示:

62 W 91ST ST APT 4D
纽约纽约10024-1414

答案 4 :(得分:2)

您可能想要查看的一件事是Soundex次搜索,这对于拼写错误和收缩非常有用。

然而,这不是数据库内验证,因此它可能或可能不是您正在寻找的。

答案 5 :(得分:2)

另一种可能的解决方案(假设您确实需要可靠的地址数据,并且您不仅仅使用地址作为防止重复帐户的方法)是使用第三方Web服务来标准化用户提供的地址。

它以这种方式工作 - 您的系统通过在线表单接受用户的地址。您的表单将用户的地址移交给第三方地址标准化Web服务。 Web服务为您提供相同的地址,但现在将数据标准化为离散地址字段,并应用标准缩写和格式。在尝试将数据保存到数据库之前,您的应用程序会将此标准化地址显示给您的用户进行确认。

如果所有用户地址都经过标准化步骤并且只有标准化地址保存到您的数据库中,那么应该大大简化查找重复记录,因为您现在正在比较苹果和苹果。

其中一个第三方服务是Global Address's Interactive Service,其中包括德国在受支持国家/地区的列表,还有一个在线演示,演示了他们的服务如何运作(演示链接可以在该网页上找到)。 / p>

显然,这种方法存在成本劣势。但是,从正面看:

  1. 您不需要创建和维护自己的地址标准化元数据
  2. 您无需持续增强地址标准化例程,
  3. 您可以将软件开发的精力集中在应用程序中与您的要求无关的部分
  4. 免责声明:我不为Global Address工作,也没有尝试使用他们的服务。我只是提到它们作为一个例子,因为它们有一个你可以实际玩的在线演示。

答案 6 :(得分:1)

为我自己的问题添加答案:

另一种方法是向用户询问他们的手机号码,向他们发送文本消息以进行验证。这可以阻止大多数人弄乱重复的地址。

我是在谈论个人经历。 (感谢pigsback!)他们通过手机推出了确认。这阻止了我有2个帐户! : - )

答案 7 :(得分:1)

我意识到原始帖子是德语地址的特定内容,但这对于一般地址来说是一个很好的问题。

在美国,有一个地址的一部分称为交付点条形码。它是一个唯一的12位数字,用于标识单个交付点,并可用作地址的唯一标识符。要获得此值,您需要使用地址验证或地址标准化网络服务API,根据您对其提出的请求量,每个网站的成本约为20美元。

为了充分披露,我是SmartyStreets的创始人。我们提供了一个名为LiveAddress的address validation web service API。如果您有任何问题,我们非常欢迎您亲自与我联系。

答案 8 :(得分:1)

机器学习和AI具有查找字符串相似性和重复度量的算法。

记录链接或匹配等效记录的任务 在语法上有所不同 - 最初是在20世纪50年代后期探索过的 和20世纪60年代。

您可以使用向量表示每对记录 描述各个记录字段之间相似性的功能。

例如,使用可学习字符串进行自适应重复检测 相似度量。例如,read this doc

  1. 您可以使用通用或手动调整的距离指标来估算潜在重复项的相似性。

  2. 您可以使用自适应名称匹配算法,例如Jaro指标,它基于两个字符串之间常见字符的数量和顺序。

  3. 基于令牌和混合距离。在这种情况下,我们可以转换 字符串s和t到令牌多重集(每个令牌都是一个单词)并考虑这些多集的相似度量。

答案 9 :(得分:0)

通常,您在数据库中使用约束来确保数据在基于数据的意义上是“唯一的”。

关于“同构”,我认为你是独立的,即自己编写代码。如果在数据库中,您可以使用触发器。

答案 10 :(得分:0)

  

我正在寻找解决美国地址的答案

有问题的是阻止用户输入重复项,例如

  

Quellenstrasse 66/11和     Quellenstr. 66a-11

当您让用户在输入框中输入完整地址时会发生这种情况。

您可以使用一些方法来防止这种情况。

1。使用RegEx进行统一格式化

  • 您可以提示用户以统一格式输入详细信息。
  • 查询时效率非常高
  • 测试用户对某些正则表达式输入的值,如果失败,请让用户更正。

2.使用谷歌地图api,并要求用户从中选择详细信息。

  • 如果选择谷歌地图,则可以使用反向地理编码来实现。

来自Google Developer's guide

  

术语地理编码通常是指将人类可读地址转换为地图上的位置。 执行相反操作的过程,将地图上的位置转换为人类可读的地址,称为反向地理编码

3。允许问题中显示的异构数据,并将其与不同的格式进行比较。

  • 在问题中,OP允许使用不同格式的地址。
  • 在这种情况下,您可以将其更改为不同的表单,并使用数据库进行检查以获得解决方案。
  • 这可能需要更多时间,时间完全取决于测试用例的数量。

4。将地址拆分为不同的部分并将其存储在db中,并为用户提供这样的表单。

  • 这提供了在数据库中存储街道,城市,州等的不同字段。
  • 还为用户提供不同的输入字段,以自上而下的格式输入街道,城市,州等。
  • 当用户进入州时,缩小查询范围以查找仅限该状态的欺骗行为。
  • 当用户进入城市时,只将其缩小到该城市。
  • 当用户进入街道时,将其缩小到该街道。

最后

  • 当用户输入地址时,将其更改为不同的格式并根据数据库进行测试。
  

即使测试用例的数量可能很高,这也是有效的,您测试的条目数量将会非常少,因此它将消耗非常少的时间。

答案 11 :(得分:0)

在美国,您可以使用USPS Address Standardization Web Tool。它会为您验证和规范化地址。这样,您可以在检查地址是否已存在于数据库之前规范化地址。如果数据库中的所有地址都已经规范化,您就可以轻松地发现重复数据。

示例网址:

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,在某些情况下可能会有用。

答案 12 :(得分:0)

谷歌搜索搜索建议时,您可以搜索数据库地址字段

首先,让我们创建一个index.htm(l)文件:

const Range = (start, end) => ({
  *[Symbol.iterator]() {
    while (start < end) 
        yield start++;
  }
})

for (var x of Range(1, 10)) {
  console.log(x)
}

现在我们将创建一个city.php文件,该文件将我们的查询聚合到MySQL DB并将响应作为JSON。这是代码:

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

然后阻止将它们保存到数据库中,如果在表列中找到重复

对于你的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");


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

?>

答案 13 :(得分:0)

将地址与DET BundesPost提供的地址进行匹配,以检测重复项。

DET可能会出售像美国一样的CD。然后问题变得与Bundespost地址匹配。只需用过去批准​​的缩写等替换缩写即可。

在美国也一样。匹配USPostOffice地址(对不起,这些费用,因此它不是完全开放的CD可从美国邮局获得),以找到重复。

答案 14 :(得分:0)

这是一个古老的问题,但是另一种方法是计算到地址的Levenshtein距离,这样您就可以找到已经非常相似的地址。您可以在这里看到更多。 Finding Duplicate Addresses Using the Levenshtein Distance Metric in SQL.

答案 15 :(得分:-1)

在我看来,假设您的数据库中已经有很多脏数据,

你必须建立你的&#34;手工制作&#34;脏过滤器可能检测到最大的德国缩减......

但如果您处理大量数据,您将冒险找到一些假阳性和真阴性样本......

最后一个半自动化的工作(当假阳性或真阴性的概率太高时,带有人工辅助的机器)将是最好的解决方案。

你更多的待遇&#34;例外&#34; (因为人类在填写数据时会引发异常),更多的是你的&#34;手工制作&#34;过滤器符合您的要求。

另一方面,您也可以在用户端使用德国地址验证服务,并仅存储经过验证的服务...