MYSQL中的案例敏感性和指数

时间:2009-12-22 16:13:59

标签: mysql hibernate grails

我正在创建一个系统,其中使用电子邮件地址作为唯一标识符。有时我需要通过电子邮件地址查找用户。如果用户输入所有小写的电子邮件地址,但数据库将其存储为大小写混合,是完全扫描,还是数据库仍然使用索引?

这确实是个问题,因为我在将用户添加到系统时尝试验证电子邮件地址是否有效。

我在后端为数据库使用带有MYSQL的grails。 我目前正在这样做以找到用户

def c = User.createCriteria()
def currentUser = c.get() { ilike('emailAddress',message.sender.address) }

我知道我可以在UI上强制执行此案例,但我也想在模型级别强制执行

谢谢,抱歉这个长期的问题

3 个答案:

答案 0 :(得分:2)

MySQL为每个字符列指定collation,可能区分大小写或不区分大小写。

使用列上指定的任何排序规则构建索引,因此:

  1. 更改您的表格以指定电子邮件列中不区分大小写的排序规则(例如,ascii-general-ci)。
  2. 重建索引。
  3. 享受。
  4. 请注意,针对电子邮件的所有查询现在都不区分大小写。

答案 1 :(得分:1)

不幸的是,MySQL不支持Postgres和Oracle等基于函数的索引。 (Source

MySQL中可能的解决方法是为小写电子邮件地址添加另一个列,并在所有更新和插入上使用小写电子邮件填充它。然后只需索引该列,并将其用于查找。

使用基于函数的索引,您可以执行以下操作:

CREATE INDEX 
    ix_users
ON 
    table_users
USING 
    lower(email_address);

答案 2 :(得分:0)

使用Grails,您可以选择一些模型来验证模型:

您可以write a setter for the emailAddress将其转换为一致的案例:

public void setEmailAddress(email){ 
    emailAddress = email
}

更为参与但正确的答案是create a custom editorPropertySupportEditor)会自动处理您的规范化。

如果emailAddress未正确规范化,您还需要编写自定义validator以确保Grails验证失败。如果你想让它变得非常优雅,你可以使用constraints plugin将验证器变成可重复使用的constrtaint,这可能会产生如下结果:

static constraints = {
    emailAddress(normalizedEmail:true)
}