Какие способы создания индексов базы данных существуют в Django ORM?

«Какие способы создания индексов базы данных существуют в Django ORM?» — вопрос из категории Django, который задают на 10% собеседований Python Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

В Django ORM есть несколько способов определить индексы для полей модели, что критически важно для ускорения операций поиска (SELECT) по этим полям.

1. Простой индекс на одно поле (db_index=True)

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

from django.db import models

class User(models.Model):
    # Создаст индекс для поля username
    username = models.CharField(max_length=100, db_index=True, unique=True)

2. Составные и именованные индексы (Meta.indexes)

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

from django.db import models

class User(models.Model):
    first_name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=100)

    class Meta:
        indexes = [
            # Индекс по одному полю (аналог db_index=True)
            models.Index(fields=['first_name']),
            # Составной индекс по двум полям с кастомным именем
            models.Index(fields=['last_name', 'first_name'], name='full_name_idx'),
        ]

3. Функциональные индексы (Django 3.2+)

Позволяют создавать индексы на основе выражений или функций базы данных. Очень полезно для регистронезависимого поиска.

from django.db import models
from django.db.models.functions import Lower

class User(models.Model):
    username = models.CharField(max_length=100)

    class Meta:
        indexes = [
            # Индекс по значению поля в нижнем регистре
            models.Index(Lower('username'), name='username_lower_idx'),
        ]

Что нужно помнить:

  • Производительность: Индексы значительно ускоряют чтение (поиск, фильтрацию), но немного замедляют операции записи (INSERT, UPDATE), так как индекс тоже нужно обновлять.
  • Миграции: После добавления или изменения индексов в модели необходимо создать и применить миграции:
    python manage.py makemigrations
    python manage.py migrate