在Grails中,GORM提供了DSL在Domain中定义数据库索引,以提升查询性能,如官方示例:
class Person {
String firstName
String address
static mapping = {
table 'people'
version false
id column: 'person_id'
firstName column: 'First_Name', index: 'Name_Idx'
address column: 'Address', index: 'Name_Idx,Address_Index'
}
}
启动时将创建两个索引:
create index address_idx on people (first_name, address);
create index name_idx on people (first_name);
但是,如果只希望创建一个first_name和address的联合索引,却无从下手。
基于此,BroToolkit对索引的DSL进行了增强,提供更简单的方式来创建联合索引,如下面的Domain示例:
class Foobar {
String name
String status
String type
static mapping = {
table "foobar"
}
}
创建联合索引,在 mapping 中添加:
- 在status、type上创建索引 idx1
status index:[name:"idx1", combined:"type"] - 在status、name、type上创建索引 idx2
status index:[name:"idx2", combined:["name","type"]] - 在status、type上创建索引 idx3,以及在status、name、type上创建索引 idx4
status index:[[name: "idx3", combined:"type"], [name:"idx4", combined:["name","type"]]]
此外,SQL Server中,如果 domain 的 constrains 定义了 unique 属性,Grail会自动生成一个唯一性索引,但是,如果插入两行 null 数据,则会认为违反 unique 约束,该行为与Oracle、MySQL等数据库不一致。
因此,BroToolkit针对本情况,生成 NotNullUnique 的索引(create unique index uk_x on x(str) where str is not null),以避免该问题。