千家信息网

Go 语言如何操作常见的数据库

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,使用MySQL数据库目前 Internet 上流行的网站构架方式是 LAMP/LNMP,其中的 M 即 MySQL, 作为数据库,MySQL 以免费、开源、使用方便为优势成为了很多Web开发的后端数据
千家信息网最后更新 2026年11月02日Go 语言如何操作常见的数据库

使用MySQL数据库

目前 Internet 上流行的网站构架方式是 LAMP/LNMP,其中的 M 即 MySQL, 作为数据库,MySQL 以免费、开源、使用方便为优势成为了很多Web开发的后端数据库存储引擎。

Go中支持MySQL的驱动目前比较多,有如下几种,有些是支持database/sql标准,而有些是采用了自己的实现接口,常用的有如下几种:

  • https://github.com/go-sql-driver/mysql 支持database/sql,全部采用go写。

  • https://github.com/ziutek/mymysql 支持database/sql,也支持自定义的接口,全部采用go写。

  • https://github.com/Philio/GoMySQL 不支持database/sql,自定义接口,全部采用go写。

接下来的例子主要以第一个驱动为例,推荐主要理由是:

  • 这个驱动比较新,维护的比较好;

  • 完全支持database/sql接口;

  • 支持keepalive,保持长连接。

接下来的几个小节里面我们都将采用同一个数据库表结构:数据库test,用户表userinfo,关联用户信息表userdetail。

 1CREATE TABLE `userinfo` (
2 `uid` INT(10) NOT NULL AUTO_INCREMENT,
3 `username` VARCHAR(64) NULL DEFAULT NULL,
4 `departname` VARCHAR(64) NULL DEFAULT NULL,
5 `created` DATE NULL DEFAULT NULL,
6 PRIMARY KEY (`uid`)
7);
8
9CREATE TABLE `userdetail` (
10 `uid` INT(10) NOT NULL DEFAULT '0',
11 `intro` TEXT NULL,
12 `profile` TEXT NULL,
13 PRIMARY KEY (`uid`)
14)

如下示例将示范如何使用database/sql接口对数据库表进行增删改查操作:

 1// 示例代码11-15
2package main
3
4import (
5 "database/sql"
6 "fmt"
7 //"time"
8
9 _ "github.com/go-sql-driver/mysql"
10)
11
12func main() {
13 db, err := sql.Open("mysql", "zuolan:zuolan@/test?charset=utf8")
14 checkErr(err)
15
16 //插入数据
17 stmt, err := db.Prepare("INSERT userinfo SET username=?,departname=?,created=?")
18 checkErr(err)
19
20 res, err := stmt.Exec("张三", "研发部门", "2017-09-09")
21 checkErr(err)
22
23 id, err := res.LastInsertId()
24 checkErr(err)
25
26 fmt.Println(id)
27 //更新数据
28 stmt, err = db.Prepare("update userinfo set username=? where uid=?")
29 checkErr(err)
30
31 res, err = stmt.Exec("zuolanupdate", id)
32 checkErr(err)
33
34 affect, err := res.RowsAffected()
35 checkErr(err)
36
37 fmt.Println(affect)
38
39 //查询数据
40 rows, err := db.Query("SELECT * FROM userinfo")
41 checkErr(err)
42
43 for rows.Next() {
44 var uid int
45 var username string
46 var department string
47 var created string
48 err = rows.Scan(&uid, &username, &department, &created)
49 checkErr(err)
50 fmt.Println(uid)
51 fmt.Println(username)
52 fmt.Println(department)
53 fmt.Println(created)
54 }
55
56 //删除数据
57 stmt, err = db.Prepare("delete from userinfo where uid=?")
58 checkErr(err)
59
60 res, err = stmt.Exec(id)
61 checkErr(err)
62
63 affect, err = res.RowsAffected()
64 checkErr(err)
65
66 fmt.Println(affect)
67
68 db.Close()
69
70}
71
72func checkErr(err error) {
73 if err != nil {
74 panic(err)
75 }
76}

通过上面的代码我们可以看出,Go操作MySQL数据库是很方便的。

sql.Open()函数用来打开一个注册过的数据库驱动,go-sql-driver中注册了mysql这个数据库驱动,第二个参数是DSN(Data Source Name),它是go-sql-driver定义的一些数据库链接和配置信息。它支持如下格式:

1user@unix(/path/to/socket)/dbname?charset=utf8
2user:password@tcp(localhost:5555)/dbname?charset=utf8
3user:password@/dbname
4user:password@tcp([de:ad:be:ef::ca:fe]:80)/dbname

db.Prepare()函数用来返回准备要执行的sql操作,然后返回准备完毕的执行状态。

db.Query()函数用来直接执行Sql返回Rows结果。

stmt.Exec()函数用来执行stmt准备好的SQL语句

我们可以看到我们传入的参数都是=?对应的数据,这样做的方式可以一定程度上防止SQL注入。

使用SQLite数据库

SQLite是一个开源的嵌入式关系数据库,实现自包容、零配置、支持事务的SQL数据库引擎。其特点是高度便携、使用方便、结构紧凑、高效、可靠。与其他数据库管理系统不同,SQLite的安装和运行非常简单,在大多数情况下,只要确保SQLite的二进制文件存在即可开始创建、连接和使用数据库。

如果您正在寻找一个嵌入式数据库项目或解决方案,SQLite是绝对值得考虑。SQLite可以是说开源的Access。

Go支持sqlite的驱动也比较多,但是很多都不支持database/sql接口:

  • https://github.com/mattn/go-sqlite3 支持database/sql接口,基于cgo(关于cgo的知识请参看官方文档)。

  • https://github.com/feyeleanor/gosqlite3 不支持database/sql接口,基于cgo。

  • https://github.com/phf/go-sqlite3 不支持database/sql接口,基于cgo。

目前支持database/sql的SQLite数据库驱动比较少,采用标准接口有利于以后出现更好的驱动的时候做迁移,因此本节后面都采用第一个驱动。

示例的数据库表结构如下所示,相应的建表SQL:

 1CREATE TABLE `userinfo` (
2 `uid` INTEGER PRIMARY KEY AUTOINCREMENT,
3 `username` VARCHAR(64) NULL,
4 `departname` VARCHAR(64) NULL,
5 `created` DATE NULL
6);
7
8CREATE TABLE `userdeatail` (
9 `uid` INT(10) NULL,
10 `intro` TEXT NULL,
11 `profile` TEXT NULL,
12 PRIMARY KEY (`uid`)
13);

看下面Go程序是如何操作数据库表,进行数据增删改查的:

 1// 示例代码11-16
2package main
3
4import (
5 "database/sql"
6 "fmt"
7 "time"
8
9 _ "github.com/mattn/go-sqlite3"
10)
11
12func main() {
13 db, err := sql.Open("sqlite3", "./demo.db")
14 checkErr(err)
15
16 //插入数据
17 stmt, err := db.Prepare("INSERT INTO userinfo(username, departname, created) values(?,?,?)")
18 checkErr(err)
19
20 res, err := stmt.Exec("张三", "研发部门", "2017-09-09")
21 checkErr(err)
22
23 id, err := res.LastInsertId()
24 checkErr(err)
25
26 fmt.Println(id)
27 //更新数据
28 stmt, err = db.Prepare("update userinfo set username=? where uid=?")
29 checkErr(err)
30
31 res, err = stmt.Exec("zuolanupdate", id)
32 checkErr(err)
33
34 affect, err := res.RowsAffected()
35 checkErr(err)
36
37 fmt.Println(affect)
38
39 //查询数据
40 rows, err := db.Query("SELECT * FROM userinfo")
41 checkErr(err)
42
43 for rows.Next() {
44 var uid int
45 var username string
46 var department string
47 var created time.Time
48 err = rows.Scan(&uid, &username, &department, &created)
49 checkErr(err)
50 fmt.Println(uid)
51 fmt.Println(username)
52 fmt.Println(department)
53 fmt.Println(created)
54 }
55
56 //删除数据
57 stmt, err = db.Prepare("delete from userinfo where uid=?")
58 checkErr(err)
59
60 res, err = stmt.Exec(id)
61 checkErr(err)
62
63 affect, err = res.RowsAffected()
64 checkErr(err)
65
66 fmt.Println(affect)
67
68 db.Close()
69
70}
71
72func checkErr(err error) {
73 if err != nil {
74 panic(err)
75 }
76}

我们可以看到上面的代码和MySQL例子里面的代码几乎是一模一样的,唯一改变的就是导入的驱动改变了,然后调用sql.Open是采用了SQLite的方式打开。

使用PostgreSQL数据库

PostgreSQL是一个自由的对象-关系数据库服务器(数据库管理系统),它在灵活的BSD风格许可证下发行。它提供了相对其他开放源代码数据库系统(比如MySQL和Firebird),和对专有系统比如Oracle、Sybase、IBM的DB2和Microsoft SQL Server的一种选择。

PostgreSQL和MySQL比较,它更加庞大一点,因为它是用来替代Oracle而设计的。所以在企业应用中采用PostgreSQL是一个明智的选择。

MySQL被Oracle收购之后正在逐步的封闭(自MySQL 5.5.31以后的所有版本将不再遵循GPL协议),鉴于此,将来我们也许会选择PostgreSQL而不是MySQL作为项目的后端数据库。

Go实现的支持PostgreSQL的驱动也很多,因为国外很多人在开发中使用了这个数据库。

  • https://github.com/lib/pq 支持database/sql驱动,纯Go写的;

  • https://github.com/jbarham/gopgsqldriver 支持database/sql驱动,纯Go写的;

  • https://github.com/lxn/go-pgsql 支持database/sql驱动,纯Go写的。

在下面的示例中采用第一个驱动,因为它目前使用的人最多,在Github上也比较活跃。

数据库建表语句:

 1CREATE TABLE userinfo
2(
3 uid serial NOT NULL,
4 username character varying(100) NOT NULL,
5 departname character varying(500) NOT NULL,
6 Created date,
7 CONSTRAINT userinfo_pkey PRIMARY KEY (uid)
8)
9WITH (OIDS=FALSE);
10
11CREATE TABLE userdeatail
12(
13 uid integer,
14 intro character varying(100),
15 profile character varying(100)
16)
17WITH(OIDS=FALSE);

看下面这个Go如何操作数据库表,进行数据的增删改查:

 1// 示例代码11-17
2package main
3
4import (
5 "database/sql"
6 "fmt"
7
8 _ "github.com/lib/pq"
9)
10
11func main() {
12 db, err := sql.Open("postgres", "user=zuolan password=zuolan dbname=test sslmode=disable")
13 checkErr(err)
14
15 //插入数据
16 stmt, err := db.Prepare("INSERT INTO userinfo(username,departname,created) VALUES($1,$2,$3) RETURNING uid")
17 checkErr(err)
18
19 res, err := stmt.Exec("张三", "研发部门", "2017-09-09")
20 checkErr(err)
21
22 // pg不支持这个函数,因为他没有类似MySQL的自增ID
23 // id, err := res.LastInsertId()
24 // checkErr(err)
25 // fmt.Println(id)
26
27 var lastInsertId int
28 err = db.QueryRow("INSERT INTO userinfo(username,departname,created) VALUES($1,$2,$3) returning uid;", "zuolan", "研发部门", "2017-09-09").Scan(&lastInsertId)
29 checkErr(err)
30 fmt.Println("最后插入id =", lastInsertId)
31
32
33 //更新数据
34 stmt, err = db.Prepare("update userinfo set username=$1 where uid=$2")
35 checkErr(err)
36
37 res, err = stmt.Exec("zuolanupdate", 1)
38 checkErr(err)
39
40 affect, err := res.RowsAffected()
41 checkErr(err)
42
43 fmt.Println(affect)
44
45 //查询数据
46 rows, err := db.Query("SELECT * FROM userinfo")
47 checkErr(err)
48
49 for rows.Next() {
50 var uid int
51 var username string
52 var department string
53 var created string
54 err = rows.Scan(&uid, &username, &department, &created)
55 checkErr(err)
56 fmt.Println(uid)
57 fmt.Println(username)
58 fmt.Println(department)
59 fmt.Println(created)
60 }
61
62 //删除数据
63 stmt, err = db.Prepare("delete from userinfo where uid=$1")
64 checkErr(err)
65
66 res, err = stmt.Exec(1)
67 checkErr(err)
68
69 affect, err = res.RowsAffected()
70 checkErr(err)
71
72 fmt.Println(affect)
73
74 db.Close()
75
76}
77
78func checkErr(err error) {
79 if err != nil {
80 panic(err)
81 }
82}

从上面的代码我们可以看到,PostgreSQL是通过 1, 2这种方式来指定要传递的参数,而不是MySQL中的?,另外在sql.Open中的dsn信息的格式也与MySQL的驱动中的dsn格式不一样,所以在使用时请注意它们的差异。

还有pg不支持LastInsertId函数,因为PostgreSQL内部没有实现类似MySQL的自增ID返回,其他的代码几乎是一模一样。

NoSQL数据库操作

NoSQL(Not Only SQL),指的是非关系型的数据库。随着Web2.0的兴起,传统的关系数据库在应付Web2.0网站,特别是超大规模和高并发的SNS类型的Web2.0纯动态网站已经显得力不从心,暴露了很多难以克服的问题,而非关系型的数据库则由于其本身的特点得到了非常迅速的发展。

而Go语言作为21世纪的C语言,对NOSQL的支持也是很好,目前流行的NOSQL主要有redis、mongoDB、Cassandra和Membase等。这些数据库都有高性能、高并发读写等特点,目前已经广泛应用于各种应用中。

1. Redis

redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)和zset(有序集合)。

目前应用redis最广泛的应该是新浪微博平台,其次还有Facebook收购的图片社交网站instagram。Go目前支持redis的驱动有如下:

  • https://github.com/garyburd/redigo

  • https://github.com/go-redis/redis

  • https://github.com/hoisie/redis

  • https://github.com/alphazero/Go-Redis

  • https://github.com/simonz05/godis

推荐使用第一个,用法上和上面驱动没有太大区别,限于篇幅不再展开。

2. mongoDB

MongoDB是一个高性能,开源,无模式的文档型数据库,是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。他支持的数据结构非常松散,采用的是类似json的bjson格式来存储数据,因此可以存储比较复杂的数据类型。Mongo最大的特点是他支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。

目前Go支持mongoDB最好的驱动就是mgo(http://labix.org/mgo),这个驱动目前最有可能成为官方的pkg。安装mgo的命令为:

1go get gopkg.in/mgo.v2


数据 数据库 支持 驱动 接口 代码 函数 示例 查询 系统 存储 语言 方式 格式 特点 结构 网站 部门 面的 应用 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网科技名片 深圳市人人互联网科技有限公司 南京欣网互联网络科技有限公司 善班互联网科技 碳银互联网科技 互联网金融科技创新 互联网科技有限公司 翻译 四个字互联网科技公司取名 山东吉时兔互联网科技有限公司 智腾互联网科技有限公司 国大互联网教育科技有限公司工作 中科明德北京互联网科技 互联网安防科技感 广州有谷有贝互联网科技有限公司 广州梦谷互联网科技有限公司领导 保山互联网科技靠谱吗 青岛易易互联网科技 山东蛋芒互联网科技有限公司 黑龙江互联网科技公司 宁波允成互联网科技有限公司 重生之互联网科技帝国 科技赋能下的互联网金融 涨乐互联网科技 金融科技创新监管互联网金融 奇酷互联网络科技公司 北京三清互联网科技 广州慧亚互联网科技怎么样 小米互联网科技园设置 陕西彩京云互联网科技有限公司 互联网科技快速发展优美句子
0