> Какой вид индекса используется по умолчанию в Django (Python)

Уровень: senior · Роль: backend · Язык: Python · Категория: Технические вопросы

Компании: JetLend

Стек: Python

> Пример ответа

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

В Django по умолчанию используется B-Tree индекс (через db_index=True или unique=True). Это стандартный индекс, создаваемый на уровне базы данных - в PostgreSQL, MySQL и SQLite это обычный B-Tree. Для полнотекстового поиска или JSON-полей нужно явно указывать другие типы индексов через Meta.indexes с GinIndex, BrinIndex и т.д.

Подробное объяснение

Когда вы объявляете поле модели с db_index=True или unique=True, Django добавляет в миграцию операцию AddIndex с типом Index (по умолчанию). Этот Index транслируется в CREATE INDEX без указания типа - база данных сама выбирает B-Tree, так как это дефолтный тип для обычных колонок.

Важно: Django не создаёт индекс автоматически для ForeignKey - он создаётся только если поле объявлено с db_index=True или если это unique=True. Однако на практике большинство БД (PostgreSQL, MySQL) автоматически создают индекс для внешних ключей, но это поведение самой БД, а не Django.

Для более специфичных случаев используются классы из django.contrib.postgres.indexes (только для PostgreSQL): GinIndex, BrinIndex, HashIndex, SpGistIndex. Для MySQL и SQLite доступен только стандартный Index.

На практике

На уровне senior важно понимать, что дефолтный B-Tree - это не всегда оптимально:

  • Для LIKE '%text%' или полнотекстового поиска B-Tree бесполезен - нужен GinIndex с trigram_similar или GinIndex с GinIndex(fields=['body'], opclasses=['gin_trgm_ops']).
  • Для JSONB-полей в PostgreSQL - GinIndex с jsonb_path_ops.
  • Для очень больших таблиц с редкими обновлениями - BrinIndex может дать выигрыш по размеру.

Также стоит помнить про Meta.indexes для составных индексов и Index(fields=['a', 'b'], name='...') - это всегда B-Tree, если не указан другой класс.

Пример кода

PYTHON
from django.db import models
from django.contrib.postgres.indexes import GinIndex
class Article(models.Model):
title = models.CharField(max_length=200, db_index=True) # B-Tree
body = models.TextField()
tags = models.JSONField(default=list)
class Meta:
indexes = [
models.Index(fields=['title'], name='title_idx'), # B-Tree
GinIndex(
fields=['body'],
opclasses=['gin_trgm_ops'],
name='body_trgm_idx',
), # GIN для полнотекстового поиска
]

Как отвечать на собеседовании

Начните с прямого ответа: "B-Tree". Затем добавьте, что это дефолт для всех стандартных полей, и что для специфических задач нужно явно указывать другие типы. Упомяните, что db_index=True и unique=True создают B-Tree, а для составных индексов используется Meta.indexes. Если спросят про PostgreSQL - расскажите про GinIndex и BrinIndex. Не углубляйтесь в детали реализации БД, если не просят.

Что проверяет интервьюер

  • Понимание, что Django не имеет собственного индекса - он делегирует создание БД.
  • Знание разницы между db_index и Meta.indexes.
  • Осознание ограничений B-Tree для нестандартных запросов.
  • Умение выбрать правильный тип индекса под задачу.

Типичные ошибки

  • Утверждение, что Django использует "индекс по умолчанию" - это не тип, а отсутствие явного указания.
  • Путаница с unique=True - это тоже B-Tree, но с ограничением уникальности.
  • Игнорирование того, что для ForeignKey индекс может создаваться автоматически на уровне БД, но не гарантированно в Django.
  • Предложение GinIndex для MySQL - он доступен только в PostgreSQL.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью