三生有幸,四季如春 | 言文

PostgreSQL + Go 备忘录

2018.01.18

看到 PostgreSQL 和 Go 这两者选定的动物作为 logo,不由得想起很久以前的一种说法,在斗兽棋中大象是无畏的存在,但是唯独怕老鼠。 PostgreSQL 之前倒是经常接触,但是 Go 就得现学现卖了,于是写个备忘录,记录初学 Go 开发踩过的那些坑。

环境

创建一个基本的数据库

$ sudo pacman -S postgresql
$ sudo systemctl start postgresql
$ sudo -u postgres -i
[postgres]$ initdb --locale $LANG -E UTF8 -D '/var/lib/postgres/data'
[postgres]$ createuser --interactive
$ createdb myDatabaseName
[postgres]$ psql -d myDatabaseName
... # 省略具体创建数据库用户和更改数据库权限等SQL操作

完成安装和创建工作,注意命令使用时所对应的账户和权限,如有需要可将 postgresql.service 添加到开机启动。

连接数据库

const (
	host     = "localhost"
	port     = 5432
	user     = "cantonres"
	password = "resistance"
	dbname   = "cantonres"
)

func main() {
	psqlInfo := fmt.Sprintf("host=%s port=%d user=%s "+
		"password=%s dbname=%s sslmode=disable",
		host, port, user, password, dbname)
	db, err := gorm.Open("postgres", psqlInfo)
	if err != nil {
		panic(err)
	} else {
		fmt.Println("Successfully connected!")
	}
    defer db.Close()
}

将具体信息改成自己的配置后就可以连接到数据库了,连接成功则会输出 Successfully connected!

创建表

这里以创建 users 这个表为例,并定义形式相应的结构体。

type User struct {
	ID        int       `json:"id"`
	Username  string    `json:"username";gorm:"not null"`
	GoogleID  string    `json:"google_id";gorm:"not null;"`
	Faction   int8      `json:"faction";gorm:"not null"`
	IsAdmin   bool      `json:"is_admin";gorm:"not null"`
	Email     string    `json:"email";gorm:"not null;"`
	CreatedAt time.Time `json:"created_at";gorm:"not null;"`
	UpdatedAt time.Time `json:"updated_at"`
}

表单操作

以查询某个 id 的用户个人信息为例,将 db 和用户 id 传入以下函数即可,得到的结果在 users 中返回。

func GetUser(db *gorm.DB, id int) []User {
	var users []User // 创建一个元素为 User 类型的切片
	db.Where("id = ?", id).Find(&users)

	return users
}

func main() {
    // ...之前连接数据库的代码省略了

    id := 1
	users := GetUser(db, id)
	fmt.Println(users)
	fmt.Println(users[0].Username)
}

更多数据库操作可见 gorm 中文文档

小结

实际上写起来还是挺简单的,主要就是之前对静态语言不熟悉,简单用循环做了个查询速度测试,1w条SELECT语句大概需要耗时2.7s,乍一看比之前 python 写的性能还低(1w条 SELECT 大概 798 ms),但是由于 gorm 是 orm,不能这样比的 (gorm 用了连接池,实际上真正并行查询的时候,是可以同时存在多个连接的,循环只是用了一个链接,所以应该之后还有速度加成吧,目前还不怎么会写 go 的并行,等之后姿势水平提高了再尝试一下 Orz<-

comments powered by Disqus