0%

gorm index setting

緣由

因為工作需求使用 golang + gin + gorm 了差不多一年的時間,最近剛好遇到一些語法問題,針對 gorm index setting 的部分做了一些測試,在這邊留一些記錄給自己也分享給可能遇到一樣問題的人

文獻

其實根據官網給的範例如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
type User struct {
Name string `gorm:"index"`
Name2 string `gorm:"index:idx_name,unique"`
Name3 string `gorm:"index:,sort:desc,collate:utf8,type:btree,length:10,where:name3 != 'jinzhu'"`
Name4 string `gorm:"uniqueIndex"`
Age int64 `gorm:"index:,class:FULLTEXT,comment:hello \\, world,where:age > 10"`
Age2 int64 `gorm:"index:,expression:ABS(age)"`
}

// MySQL option
type User struct {
Name string `gorm:"index:,class:FULLTEXT,option:WITH PARSER ngram INVISIBLE"`
}

// PostgreSQL option
type User struct {
Name string `gorm:"index:,option:CONCURRENTLY"`
}

範例中可以看到能夠自己設定的項目其實非常多(從 Name3 就可以看到),但在這邊想要測試的主要是 unique index 的預設為主
官網的 gorm v2.0 範例中其實只提供兩種語法來設定 unique index

tag uniqueIndex works similar like index, it equals to index:,unique

1
2
3
4
type User struct {
Name1 string `gorm:"uniqueIndex"`
Name2 string `gorm:"uniqueIndex:idx_name,sort:desc"`
}

實際操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
type Class struct {
// 名稱為 name_idx 有 unique 演算法為 hash
Name0 string `gorm:"column:name_0;not null;uniqueIndex:name_idx"`
// 名稱為 name_1 / unique = true / btree
Name1 string `gorm:"column:name_1;not null;unique:name_idx"`
// index 沒有成功
Name2 string `gorm:"column:name_2;not null;idx:name_idx"`
// 名稱為 name_3 / unique = true / btree
Name3 string `gorm:"column:name_3;not null;idx:name_idx;unique"`
// 名稱為 name_idx / unique = true / hash
Name4 string `gorm:"column:name_4;not null;index:name_idx,unique"`
// 名稱為 name_5 / unique = true / btree
// 同時產生 名稱 name_idx / unique = true / hash
Name5 string `gorm:"column:name_5;not null;index:name_idx;unique"`
// 名稱為 name_idx / unique = true / hash
// 同時產生 名稱 idx_profiles_user / unique = true / btree
Name6 string `gorm:"column:name_6;not null;index:name_idx;uniqueIndex"`
// 名稱為 idx_profiles_name7 / unique = true / hash
Name7 string `gorm:"column:name_6;not null;uniqueIndex"`
UserID int64 `gorm:"column:user_id"`
User User `gorm:"foreignKey:UserID"`
}

分析

Name0 大致沒有什麼特別,可以了解到 uniqueIndex 也是可以給予命名,且會使用 hash 作為演算法
Name1 unique 是舊的語法,暫時還可以使用且會使用 btree 作為演算法

因此以上兩組會產生演算法的不同要特別注意

Name2 沒有成功,可以了解 idx 並不能產生作用
Name3 看起來和 Name2 相同但卻能作用,實際上是因為分號分開,有作用的原因是分號後面的 unique,原理如同 Name1

Name4 可以和 Name7 一起看,都是官方給的標準語法實際上效果是一模一樣

Name5, Name6 因為在分號間有兩組合法語法,所以都產生了兩個合法 index

大致上可以讓我們理解了 gorm 作用的方式,如果有興趣想要更清楚實際作用方式,可能必須去讀 gorm 的 source code

最後附上我用來測試這串的原始碼供參考使用 gorm-index-test

測試版本是
gorm 1.23.5
mysql driver 1.3.3
mariadb 10.7.3