Чувствительность к регистру и индексы в MYSQL - PullRequest
1 голос
/ 22 декабря 2009

Я создаю систему, в которой в качестве уникального идентификатора используется адрес электронной почты. Иногда мне нужно искать пользователя по адресу электронной почты. Если пользователь вводит адрес электронной почты в нижнем регистре, но база данных хранит его как смешанный регистр, это полное сканирование, или база данных все еще будет использовать индекс?

Это действительно проблема, потому что я пытаюсь подтвердить, что адрес электронной почты действителен при добавлении пользователя в систему.

Я использую Grails с MYSQL на сервере для базы данных. В настоящее время я делаю это, чтобы найти пользователя

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

Я знаю, что могу форсировать дело в пользовательском интерфейсе, но я также хотел бы форсировать это на уровне модели

Спасибо и простите за длинный вопрос

Ответы [ 3 ]

2 голосов
/ 22 декабря 2009

MySQL указывает сопоставление для каждого символьного столбца, который может быть чувствительным к регистру или без учета регистра.

Индекс строится с использованием любого сопоставления, указанного в столбце, поэтому:

  1. Измените таблицу, указав сопоставление без учета регистра в столбце электронной почты (например, ascii-general-ci).
  2. Перестройте свой индекс.
  3. Наслаждайтесь.

Имейте в виду, что все запросы к электронной почте теперь будут без учета регистра.

1 голос
/ 22 декабря 2009

К сожалению, MySQL не поддерживает индексы на основе функций, такие как Postgres и Oracle. ( Источник )

Возможный обходной путь в MySQL заключается в добавлении еще одного столбца для адресов электронной почты в нижнем регистре и триггера, который заполняет его сообщениями в нижнем регистре для всех обновлений и вставок. Затем просто индексируйте этот столбец и используйте его для поиска.

С помощью индекса на основе функций вы могли бы сделать следующее:

CREATE INDEX 
    ix_users
ON 
    table_users
USING 
    lower(email_address);
0 голосов
/ 22 декабря 2009

С Grails у вас есть несколько вариантов для проверки модели:

Вы можете написать установщик для адреса электронной почты , который преобразует его в согласованный регистр:

public void setEmailAddress(email){ 
    emailAddress = email
}

Более сложный, но правильный ответ: создать собственный редактор ( PropertySupportEditor ), который автоматически обработает для вас нормализацию.

Вы также захотите написать собственный валидатор , чтобы гарантировать, что валидация Grails завершится неудачно, если emailAddress неправильно нормализован. Если вы хотите сделать его действительно элегантным, вы можете превратить валидатор в повторно используемый constrtaint, используя плагин ограничений , что может привести к чему-то вроде этого:

static constraints = {
    emailAddress(normalizedEmail:true)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...