如何处理 Gmail 地址?

Posted

技术标签:

【中文标题】如何处理 Gmail 地址?【英文标题】:How to handle Gmail addresses? 【发布时间】:2010-07-01 21:21:11 【问题描述】:

背景

Gmail 允许使用 '.' 和 + 过滤器,允许无限数量的电子邮件地址都指向同一个 gmail 帐户。

即以下都指向同一个gmail帐户:

user@gmail.com u.ser@gmail.com user+spam@gmail.com u.ser+spam@gmail.com

问题

我们在生产环境中有一个表格,其中包含所有注册用户的数据,包括他们的电子邮件地址。

目前此表中的 gmail 电子邮件地址包含上述变体。

问题 1 - 如果用户在创建帐户后尝试使用与我们记录的不同的电子邮件地址变体重新登录,则不会找到该用户。 问题 2 - 用户可以使用各种不同的 gmail 电子邮件地址在外部站点上创建不同的帐户。

可能的解决方案:


一个建议的解决方案是创建一个函数...

CREATE FUNCTION STANDARDIZE_EMAIL (
    @Email varchar(255)
)
RETURNS varchar(255)
AS
BEGIN
    -- we make the email lowercase since email addresses are
    -- case independent 

    SET @Email = LOWER(@Email)

    -- if it is a gmail email address then we remove periods and filters from the username
    IF RIGHT(RTRIM(@Email), 10) = '@gmail.com'
    BEGIN
        -- remove domain
        SET @Email = REPLACE(@Email, '@gmail.com', '')

        --remove periods from username
        SET @Email = REPLACE(@Email, '.', '')

        -- remove '+' and filter
        IF CHARINDEX('+', @Email) > 0 
            SET @Email = SUBSTRING(@Email, 0, CHARINDEX('+', @Email))

        -- add back the domain
        SET @Email = @Email + '@gmail.com'
    END  

    RETURN (@Email)
END

使用示例:

SELECT * FROM table
WHERE STANDARDIZE_EMAIL(Email) = STANDARDIZE_EMAIL(@Email)

inb4: 运行一个流程来标准化当前在桌面上的所有电子邮件不是一种选择,因为可能存在重复,用户将失去 gmail +filter 功能

我们在数据库上搜索时对每条记录的电子邮件地址进行标准化是否过于昂贵?


另一个建议的解决方案是在表格中添加一个 GmailEmail 字段,并在第一次注册用户时将其 Gmail 电子邮件地址的标准化版本的副本保存到第二个字段中,以便在他们登录时进行比较回来了。

如果可能的话,我宁愿不必达到这种程度。

有人有什么想法吗?我欢迎任何和所有的意见。

【问题讨论】:

哲学讨论:您为什么要阻止用户按照他们明显的意图将它们视为单独的电子邮件地址?你不会阻止我注册 test1@yahoo.com 和 test2@gmail.com,那么为什么阻止我注册 test+1@gmail.com 和 test+2@gmail.com?出于所有意图和目的,这些都是单独的电子邮件地址。 什么版本的 SQL Server? 2005+,您只能通过创建 CLR 过程来获得正则表达式功能。除此之外,PATINDEX 提供有限的模式匹配:msdn.microsoft.com/en-us/library/ms188395.aspx 使用 + 号将多个地址发送到同一个邮箱绝不是 GMail 独有的功能。 除了 chris-s-r 所说的之外,我将我的 gmail 帐户用于大约 12 个不同的其他帐户,转发到或 pop3 等。我只登录我的 gmail 帐户,但对我来说使用的是使用 a.b@gmail.com 或使用 ab@gmail.com 与我没有什么不同,所以我真的不明白这一点,因为如果受到限制,我只会使用另一个帐户去同一个地方。如果您确实需要限制每个用户一个帐户,那么您需要做其他事情。也不是我真的鼓励你或你忘记在你的函数中包含@googlemail.com 的任何东西:P 我不会在您的数据库中放入任何与 GMail 相关的代码。数据库层不应该对来自某些用户的特定电子邮件地址进行特殊处理。 【参考方案1】:

正在标准化电子邮件地址 我们搜索的每条记录 数据库贵吗?

是的。即使这张表占用不到8页的存储空间,是的,也太贵了。

您是否需要跟踪用户输入的所有表单中的电子邮件地址?如果是这样,拥有第二个“干净”列可能很难看,但可能是必要的。 (根据您的函数创建计算列的性能与原始解决方案一样差。)

如果您不需要维护用户(每次)输入的地址,为什么不:

使用您的函数清理现有数据,例如更新...设置 EmailCol = dbo.STANDARDIZE_EMAIL(EmailCol) 只要将电子邮件地址添加到数据库中,就应用该规则来清理电子邮件地址

【讨论】:

+1:只想在搜索时标准化电子邮件?不要费心在列上放索引,它不会被使用... 谢谢,将进行第二次清洁列路线。【参考方案2】:

我想指出这些字符! # $ % & ' * + - / = ? ^ _ | ``~ 在电子邮件地址中都是有效的。对于实际上具有未将“+ 后缀”和句点映射到同一邮箱的邮箱的任何系统,您都会遇到问题。

我认为用户期望 user+spam@example.com 和 user@example.com 被视为唯一地址是合理的。

【讨论】:

【参考方案3】:

我的建议是使用您提供的功能创建一个“标准化”电子邮件字段(以空开头)。用户登录后,系统可以:

标准化他们用于登录的电子邮件 查看电子邮件是否存在于“标准化”字段中 如果有,让他们进来 如果不存在,请检查“未标准化”电子邮件是否存在 如果是这样: 将该样式标记为他们首选的电子邮件样式 创建“标准化”字段 让他们进来 如果不是: 拒绝登录

这具有将用户缓慢迁移到新系统的优势,并且(透明地)让他们首选的电子邮件用作他们的登录名。当然,请注意,在其 GMail 地址变体下使用多个帐户的用户将无法访问他们的其他帐户;因为你似乎想阻止这种情况,所以我将其称为功能。

您可能希望在开头添加一个检查,因此如果存在标准化字段并且存在非标准化字段(并且它们不匹配),您可以告知用户发生了什么并处理适当地使用它。

【讨论】:

【参考方案4】:

您可以创建一个 computed 列来标准化电子邮件。

我知道您说过这不是一个选项,但您可能需要再看一下标准化列 - 在您这样做之前,您的数据库中的数据会不一致。

【讨论】:

以上是关于如何处理 Gmail 地址?的主要内容,如果未能解决你的问题,请参考以下文章

主机网卡如何处理组播MAC地址

CUDA 如何处理内存地址的多次更新?

在没有虚拟内存的系统上如何处理ELF入口点地址?

地址栏中多个问号如何处理

如何处理动态IP地址mvc 4

EF7 如何处理嵌套实体的更新操作