背景
因为需要bitfinex抓取各种历史交易信息。为了实现可扩展与便于数据管理,在数据架构设计方面满足下面的需求:
- 不同的交易对的交易数据放到不同的表上。
方案
方案1
编写sql,通过多条sql语句创建多个不同名字的表。
优点:
- 理解简单,最容易的方案
缺点:
-
如果修改表名称、调整表结构、调整索引,需要重新写sql,如果在线上部署,需要到多台机器上部署与执行,加大出错的概率
-
需要额外维护表名称
-
不利于docker部署,部署业务sql建立相应表
总之,最容易的方案,确实最难维护的方案。
方案2
方案1种种不足,让我这个懒人实在不感兴趣。要追求优雅的实现方案。所以就发现下面的方案。
1
2
3
4
5
6
7
8
9
10
|
type User struct {
Name string
Pwd string
tableName string
}
func (u *User) TableName() string {
return u.tableName
}
|
看完上面的代码,大家应该会立即明白:原来只需要对表结构对应的结构体定义一种方法
TableName(),就可以实现。
一个十分简单示例代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
package main
import (
"fmt"
_ "github.com/go-sql-driver/mysql"
"github.com/jinzhu/gorm"
)
type User struct {
Name string
Pwd string
tableName string
}
func (u *User) TableName() string {
// custom table name, this is default
return u.tableName
}
func main() {
db, err := gorm.Open("mysql", "root:@/wallet_development?charset=utf8&parseTime=True&loc=Local")
if err != nil {
fmt.Println(err)
return
}
defer db.Close()
db.AutoMigrate(&User{tableName: "user1"})
db.AutoMigrate(&User{tableName: "user2"})
db.Create(&User{tableName: "user1", Name: "n1", Pwd: "p1"})
db.Create(&User{tableName: "user2", Name: "n2", Pwd: "p2"})
}
|
优点:
-
不需要写sql语句
-
docker部署不依赖sql先执行
-
调整表相关信息,只需要修改代表,重新部署即可
缺点:
- 暂时没有发现,你若发现请告诉我。
gorm实现代码
gorm中定义了针对表结构定义了接口TableName(),具体可以看gorm源码
1
2
3
4
5
6
7
|
type tabler interface {
TableName() string
}
type dbTabler interface {
TableName(*DB) string
}
|
接口TableName()应用代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
// TableName get model's table name
func (s *ModelStruct) TableName(db *DB) string {
if s.defaultTableName == "" && db != nil && s.ModelType != nil {
// Set default table name
if tabler, ok := reflect.New(s.ModelType).Interface().(tabler); ok {
s.defaultTableName = tabler.TableName()
} else {
tableName := ToDBName(s.ModelType.Name())
if db == nil || !db.parent.singularTable {
tableName = inflection.Plural(tableName)
}
s.defaultTableName = tableName
}
}
return DefaultTableNameHandler(db, s.defaultTableName)
}
|
说明
上面方案二,大概看一下,发现没有分享,所以写了下来,希望能够大家能够用上(小发现,还是太有用途)。
(end)