Какой тип поля выбрать
Слаг — короткая строка из латинских букв, цифр и дефиса, поэтому подходит обычное строковое поле ограниченной длины. Не стоит использовать неограниченный текстовый тип: он хуже индексируется и не защищает от случайно длинных значений.
slug VARCHAR(190) NOT NULL
Разумная длина и её подводные камни
Значение около двухсот символов — компромисс между свободой формулировок и ограничениями индексов у некоторых баз данных. Слишком короткое поле обрежет длинные названия, а слишком длинное может не поместиться в индекс.
- уточните максимальную длину индексируемой строки в вашей системе;
- учитывайте кодировку: в многобайтовых кодировках лимит в символах меньше;
- дополнительно ограничивайте длину при генерации слага в приложении.
Уникальный индекс — обязательная защита
Проверка уникальности в коде приложения не спасает от одновременных запросов: две записи могут пройти её одновременно. Гарантию даёт только уникальный индекс на уровне базы, который заодно ускоряет поиск записи по слагу.
CREATE UNIQUE INDEX idx_posts_slug ON posts (slug);
Регистр и правила сравнения строк
Некоторые базы сравнивают строки без учёта регистра, другие — с учётом. Чтобы не получить два «разных» слага, отличающихся только заглавной буквой, приводите значение к нижнему регистру при сохранении и не полагайтесь на настройки сравнения.
Уникальность в пределах раздела
Вариант: если слаг должен быть уникальным лишь внутри категории, создайте составной уникальный индекс из идентификатора категории и слага. Тогда одинаковые слаги в разных разделах не конфликтуют.
Составные индексы для типичных запросов
Если поиск записи идёт по слагу внутри раздела или языка, эффективнее создать составной индекс сразу по нескольким полям. Порядок полей в индексе важен: сначала ставят те, по которым фильтруют чаще всего. Лишние индексы замедляют запись, поэтому создавать их стоит только под реальные запросы.
- слаг + язык — для мультиязычных проектов;
- слаг + раздел — если уникальность локальна;
- отдельный индекс по слагу — при глобальной уникальности.
Изменение схемы уже работающей базы
Добавлять уникальный индекс в большую действующую таблицу нужно осторожно: если в ней уже есть повторы, операция завершится ошибкой. Сначала находят и разрешают дубликаты, затем создают индекс, а на время операции планируют окно с минимальной нагрузкой.
Частые вопросы
Какой длины делать поле для слага?
Обычно около двухсот символов: этого хватает для осмысленных адресов и обычно помещается в индекс.
Достаточно ли проверять уникальность слага в коде приложения?
Нет, при одновременных запросах возможны совпадения, поэтому нужен уникальный индекс на уровне базы данных.
Как избежать различий слагов из-за регистра?
Приводить значение к нижнему регистру при сохранении, не полагаясь на настройки сравнения базы.
Готовый адрес можно собрать прямо сейчас: откройте генератор ЧПУ — он транслитерирует фразу по таблице Яндекса, уберёт служебные слова и покажет длину адреса.