Разрешит ли PostgreSQL создать индекс по неуникальному полю?

«Разрешит ли PostgreSQL создать индекс по неуникальному полю?» — вопрос из категории Базы данных, который задают на 26% собеседований Node.js Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Да, PostgreSQL не только разрешает, но и часто требует создания индексов по неуникальным полям для ускорения запросов. Индекс на неуникальном поле (например, category_id, status, created_at) не накладывает ограничение уникальности, но значительно ускоряет операции SELECT, UPDATE, DELETE с условиями WHERE, JOIN, а также ORDER BY по этому полю.

Например, в Node.js-приложении для таблицы заказов (orders) индекс по полю user_id (которое явно не уникально) был критически важен:

CREATE INDEX idx_orders_user_id ON orders(user_id);

Этот индекс делает мгновенным запрос на получение всех заказов пользователя, который часто используется в API:

SELECT * FROM orders WHERE user_id = 12345 ORDER BY created_at DESC;

Для такого запроса можно создать и составной индекс для еще большей эффективности:

CREATE INDEX idx_orders_user_created ON orders(user_id, created_at DESC);

При работе с ORM Sequelize в Node.js я указывал такие индексы прямо в определении модели:

// Модель Order
user_id: {
  type: DataTypes.INTEGER,
  references: { model: 'Users', key: 'id' },
  index: true // Создаст некластеризованный индекс B-tree
}

Важно помнить, что индексы ускоряют чтение, но замедляют операции записи (INSERT, UPDATE, DELETE), так как сам индекс也需要 обновлять. Поэтому их добавляют обдуманно, основываясь на паттернах запросов приложения.