Перейти к основному содержанию

Индексы

Неофициальный Бета-перевод

Эта страница переведена PageTurner AI (бета). Не одобрена официально проектом. Нашли ошибку? Сообщить о проблеме →

Индексы на столбцах

Вы можете создать индекс для конкретного столбца, используя @Index над нужным столбцом. Индексы можно создавать для любых столбцов вашей сущности. Пример:

import { Entity, PrimaryGeneratedColumn, Column, Index } from "typeorm"

@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number

@Index()
@Column()
firstName: string

@Column()
@Index()
lastName: string
}

Также можно указать имя индекса:

import { Entity, PrimaryGeneratedColumn, Column, Index } from "typeorm"

@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number

@Index("name1-idx")
@Column()
firstName: string

@Column()
@Index("name2-idx")
lastName: string
}

Уникальные индексы

Чтобы создать уникальный индекс, укажите { unique: true } в настройках индекса:

Примечание: CockroachDB хранит уникальные индексы как UNIQUE-ограничения

import { Entity, PrimaryGeneratedColumn, Column, Index } from "typeorm"

@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number

@Index({ unique: true })
@Column()
firstName: string

@Column()
@Index({ unique: true })
lastName: string
}

Индексы с несколькими столбцами

Для создания индекса с несколькими столбцами разместите @Index на самой сущности и перечислите все свойства-столбцы, которые должны входить в индекс. Пример:

import { Entity, PrimaryGeneratedColumn, Column, Index } from "typeorm"

@Entity()
@Index(["firstName", "lastName"])
@Index(["firstName", "middleName", "lastName"], { unique: true })
export class User {
@PrimaryGeneratedColumn()
id: number

@Column()
firstName: string

@Column()
middleName: string

@Column()
lastName: string
}

Пространственные индексы

MySQL, CockroachDB и PostgreSQL (при наличии PostGIS) поддерживают пространственные индексы.

Чтобы создать пространственный индекс в MySQL, добавьте Index с spatial: true к столбцу пространственного типа (geometry, point, linestring, polygon, multipoint, multilinestring, multipolygon, geometrycollection):

@Entity()
export class Thing {
@Column("point")
@Index({ spatial: true })
point: string
}

Чтобы создать пространственный индекс на столбце, добавьте Index с spatial: true к столбцу пространственного типа (geometry, geography):

export interface Geometry {
type: "Point"
coordinates: [Number, Number]
}

@Entity()
export class Thing {
@Column("geometry", {
spatialFeatureType: "Point",
srid: 4326,
})
@Index({ spatial: true })
point: Geometry
}

Параллельное создание

Чтобы избежать необходимости получения блокировки ACCESS EXCLUSIVE при создании и удалении индексов в Postgres, используйте модификатор CONCURRENTLY. Для использования параллельного варианта задайте migrationsTransactionMode: none в настройках источника данных.

TypeORM поддерживает генерацию SQL с этой опцией, когда для индекса указана опция concurrent.

@Index(["firstName", "middleName", "lastName"], { concurrent: true })

Подробнее см. документацию PostgreSQL.

Тип индекса

Если вам нужно указать пользовательский тип индекса, используйте свойство type. Если задано свойство spatial, это поле будет игнорироваться.

@Index({ type: 'hash' })

Эта возможность в настоящее время поддерживается только в PostgreSQL.

Отключение синхронизации

TypeORM не поддерживает некоторые параметры и определения индексов (например, lower, pg_trgm) из-за множества различий в конкретных базах данных и проблем с получением информации о существующих индексах базы данных и их автоматической синхронизацией. В таких случаях вы должны создать индекс вручную (например, в миграциях) с любой необходимой сигнатурой индекса. Чтобы TypeORM игнорировал эти индексы во время синхронизации, используйте опцию synchronize: false в декораторе @Index.

Например, вы создаёте индекс с регистронезависимым сравнением:

CREATE INDEX "POST_NAME_INDEX" ON "post" (lower("name"))

после этого отключите синхронизацию для этого индекса, чтобы избежать его удаления при следующей синхронизации схемы:

@Entity()
@Index("POST_NAME_INDEX", { synchronize: false })
export class Post {
@PrimaryGeneratedColumn()
id: number

@Column()
name: string
}