索引

声明索引

wrapper.table.createTable(...)或wrapper.table.syncTable(...)生成 DDL 时,会读取@TableIndex元数据。运行时的索引元数据结构是KTableIndex。

单列索引使用类级别的@TableIndex,并在columns中写一个列名。

添加索引定义前,可先查看 📚表与列 中的表名和列名映射。

单列索引

columns只传一个列名即可。

single column

import com.kotlinorm.annotations.Table
import com.kotlinorm.annotations.TableIndex
import com.kotlinorm.interfaces.KPojo

@Table("tb_user")
@TableIndex(name = "idx_user_name", columns = ["name"])
data class User(
    val id: Int? = null,
    val name: String? = null
) : KPojo

Mysql

CREATE INDEX `idx_user_name` ON `tb_user` (`name`)

组合唯一索引

设置type = "UNIQUE"会生成唯一索引。method只在目标数据库支持该索引方法时填写。

unique composite

import com.kotlinorm.annotations.Column
import com.kotlinorm.annotations.Table
import com.kotlinorm.annotations.TableIndex
import com.kotlinorm.interfaces.KPojo

@Table("tb_user")
@TableIndex(
    name = "idx_user_tenant_email",
    columns = ["tenant_id", "email"],
    type = "UNIQUE",
    method = "BTREE"
)
data class UserAccount(
    val id: Int? = null,
    @Column("tenant_id")
    val tenantId: Int? = null,
    val email: String? = null
) : KPojo

Mysql

CREATE UNIQUE INDEX `idx_user_tenant_email` ON `tb_user` (`tenant_id`, `email`) USING BTREE

PostgreSQL

CREATE UNIQUE INDEX "idx_user_tenant_email" ON "public"."tb_user" USING BTREE ("tenant_id", "email")

PostgreSQL 并发索引

concurrently = true会生成CREATE INDEX CONCURRENTLY。Kronos 会把并发索引语句放在事务性 DDL 批次之外执行。

concurrently

import com.kotlinorm.annotations.Column
import com.kotlinorm.annotations.Table
import com.kotlinorm.annotations.TableIndex
import com.kotlinorm.interfaces.KPojo

@Table("tb_event")
@TableIndex(
    name = "idx_event_created_at",
    columns = ["created_at"],
    method = "BTREE",
    concurrently = true
)
data class EventLog(
    val id: Int? = null,
    @Column("created_at")
    val createdAt: String? = null
) : KPojo

PostgreSQL

CREATE INDEX CONCURRENTLY "idx_event_created_at" ON "public"."tb_event" USING BTREE ("created_at")

concurrently面向 PostgreSQL。其他数据库可能拒绝该 DDL 关键字。

运行时KTableIndex

KTableIndex是生成元数据和表结构同步使用的索引元数据对象。普通实体类通常使用@TableIndex;手动组装元数据时可以直接创建KTableIndex。

kotlin

import com.kotlinorm.beans.dsl.KTableIndex

val userNameIndex = KTableIndex(
    name = "idx_user_name",
    columns = arrayOf("name"),
    type = "NORMAL",
    method = "BTREE"
)

挂到表元数据后,DDL 形态如下:

Mysql

CREATE INDEX `idx_user_name` ON `tb_user` (`name`) USING BTREE

字段行为

字段当前行为
name渲染为CREATE INDEX中的索引名。
columns按数组顺序渲染为索引列。
type"UNIQUE"会标记唯一索引。"NORMAL"和空字符串会被省略。其他值会复制到INDEX前,供支持该语法的方言使用,例如 MySQL FULLTEXT、MySQL SPATIAL、SQL Server NONCLUSTERED、Oracle BITMAP。
method空字符串、"UNIQUE"、与type相同的值不会作为 method 渲染。其他值会生成USING <method>。
concurrently创建/删除索引语句会渲染CONCURRENTLY,用于 PostgreSQL。

方言提示

方言常用索引设置
MySQL使用type = "UNIQUE"创建唯一索引。method = "BTREE"或"HASH"会渲染在列列表之后。FULLTEXT和SPATIAL可通过type传入。
PostgreSQL数据库支持时可使用method = "BTREE"、"HASH"、"GIST"、"SPGIST"、"GIN"、"BRIN"。concurrently = true会生成CREATE INDEX CONCURRENTLY。
SQLite使用空type/method或type = "UNIQUE"。SQLite 建表时的索引语句会带CREATE INDEX IF NOT EXISTS。
H2使用空type/method或type = "UNIQUE"。普通索引默认使用BTREE。
SQL Server根据目标表使用type = "CLUSTERED"、"NONCLUSTERED"、"XML"或"SPATIAL"。method = "UNIQUE"也会标记唯一索引。
Oracle需要时使用type = "UNIQUE"或"BITMAP"。Oracle 标识符按 Oracle 方言规则渲染。
DM8唯一索引使用type = "UNIQUE"。其他 DM8 索引选项请使用数据库专用迁移。