Логотип YeaHub

База вопросов

Собеседования

Тренажёр

База ресурсов

Обучение

Навыки

Задачи

Войти

Выбери, каким будет IT завтра — вместе c нами!

YeaHub — это полностью открытый проект, призванный объединить и улучшить IT-сферу. Наш исходный код доступен для просмотра на GitHub. Дизайн проекта также открыт для ознакомления в Figma.

© 2026 YeaHub

AI info

Карта сайта

Документы

Медиа

Назад
Вопрос про PHP: unique, null, database

Как обеспечить уникальность необязательного поля (например, рабочего телефона) с учётом NULL-значений?

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

Короткий ответ

Для обеспечения уникальности необязательного поля с NULL нужно использовать уникальный индекс, который в большинстве СУБД позволяет несколько NULL значений. Альтернативно можно использовать default значение вместо NULL или частичный индекс только для NOT NULL значений. Также можно создать вычисляемую колонку или использовать триггеры для кастомной валидации. Самый простой способ — полагаться на поведение уникального индекса с NULL.

Длинный ответ

Проблема уникальности опциональных полей имеет несколько решений в зависимости от СУБД и требований.

Стандартное решение — Unique Index:

CREATE TABLE employees (
    id INT PRIMARY KEY,
    work_phone VARCHAR(20) NULL,
    UNIQUE KEY uk_work_phone (work_phone)
);

Поведение в разных СУБД:

  • MySQL: Multiple NULLs allowed in unique index

  • PostgreSQL: Multiple NULLs allowed

  • SQL Server: Multiple NULLs allowed (можно изменить)

  • Oracle: Multiple NULLs allowed

Альтернативные подходы:

  1. Замена NULL на default значение:

CREATE TABLE employees (
    work_phone VARCHAR(20) DEFAULT 'NOT_PROVIDED',
    UNIQUE KEY uk_work_phone (work_phone)
);
  1. Частичный/фильтрованный индекс (PostgreSQL, SQL Server):

-- Только для PostgreSQL/SQL Server
CREATE UNIQUE INDEX idx_work_phone_not_null 
ON employees (work_phone) 
WHERE work_phone IS NOT NULL;
  1. Вычисляемая колонка (SQL Server):

ALTER TABLE employees 
ADD work_phone_unique AS 
    CASE WHEN work_phone IS NULL THEN 'user_' + CAST(id AS VARCHAR) 
         ELSE work_phone 
    END;

CREATE UNIQUE INDEX uk_work_phone ON employees(work_phone_unique);

Проверка на уровне приложения:

class EmployeeService {
    public function create($data) {
        if ($data['work_phone'] && $this->phoneExists($data['work_phone'])) {
            throw new ValidationException('Phone already exists');
        }
        return Employee::create($data);
    }
}
  • Аватар

    PHP Guru

    Mikhail Savin

    Guru – это эксперты YeaHub, которые помогают развивать комьюнити.

Уровень

  • Рейтинг:

    3

  • Сложность:

    7

Навыки

  • PHP

    PHP

  • Postgres

    Postgres

Ключевые слова

#unique

#null

#database

Подпишись на PHP Developer в телеграм

  • Аватар

    PHP Guru

    Mikhail Savin

    Guru – это эксперты YeaHub, которые помогают развивать комьюнити.