Go语言在Linux中的数据库操作指南
导读:Go语言在Linux中的数据库操作指南 一 环境准备与驱动选择 安装数据库:在 Debian/Ubuntu 使用 sudo apt install mysql-server 或 CentOS/RHEL 使用 sudo yum instal...
Go语言在Linux中的数据库操作指南
一 环境准备与驱动选择
- 安装数据库:在 Debian/Ubuntu 使用
sudo apt install mysql-server或 CentOS/RHEL 使用sudo yum install mysql-server安装 MySQL;PostgreSQL 可用系统包管理器安装并启动服务。完成后用mysql -u root -p或psql验证。 - 安装 Go 驱动:
- MySQL:
go get -u github.com/go-sql-driver/mysql - PostgreSQL:常用
github.com/lib/pq(database/sql 接口)或高性能的 pgx v5:go get github.com/jackc/pgx/v5
- MySQL:
- 核心依赖:Go 标准库 database/sql 提供统一接口,配合具体驱动即可操作多种关系型数据库。
二 连接与初始化
- 使用标准库
database/sql打开连接,注意sql.Open并不会立即建立物理连接,需db.Ping()验证;通过 DSN(数据源名称)配置连接参数。 - 示例(MySQL):
- DSN 建议:
"user:pass@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4& parseTime=True& loc=Local" - 连接池常用参数:
SetMaxOpenConns、SetMaxIdleConns、SetConnMaxLifetime
- DSN 建议:
- 示例(PostgreSQL):
- lib/pq DSN:
"user=postgres dbname=test sslmode=disable" - pgx 连接:
pgx.Connect(context.Background(), "postgres://user:pass@localhost/db")
- lib/pq DSN:
- 建议用环境变量管理敏感信息(如 DB_USER、DB_PASS、DB_HOST、DB_NAME)。
三 常见数据库快速上手
- MySQL 最小可用示例(含连接池与查询)
package main import ( "database/sql" "fmt" "log" "time" _ "github.com/go-sql-driver/mysql" ) func main() { dsn := "root:password@tcp(127.0.0.1:3306)/go_demo?charset=utf8mb4& parseTime=True& loc=Local" db, err := sql.Open("mysql", dsn) if err != nil { log.Fatal(err) } defer db.Close() if err = db.Ping(); err != nil { log.Fatal(err) } fmt.Println("Connected to MySQL") // 连接池 db.SetMaxOpenConns(25) db.SetMaxIdleConns(25) db.SetConnMaxLifetime(5 * time.Minute) var id int var name string err = db.QueryRow("SELECT id, name FROM users WHERE id = ?", 1).Scan(& id, & name) if err != nil { if err == sql.ErrNoRows { log.Println("No rows") } else { log.Fatal(err) } return } fmt.Printf("User: %d, %s\n", id, name) } - PostgreSQL 最小可用示例(lib/pq)
package main import ( "database/sql" "fmt" "log" _ "github.com/lib/pq" ) func main() { dsn := "postgres://postgres:12345678@localhost/mydb?sslmode=disable" db, err := sql.Open("postgres", dsn) if err != nil { log.Fatal(err) } defer db.Close() if err = db.Ping(); err != nil { log.Fatal(err) } fmt.Println("Connected to PostgreSQL") var version string err = db.QueryRow("SELECT version()").Scan(& version) if err != nil { log.Fatal(err) } fmt.Println("PG version:", version) } - 要点:使用参数化查询(
?或$1)防止 SQL 注入;QueryRow().Scan()处理单行;rows.Next()流式遍历结果集并在最后检查rows.Err()。
四 CRUD 与事务
- 插入、更新、删除:使用
db.Exec();通过LastInsertId()获取自增主键,通过RowsAffected()获取影响行数。 - 查询:单行用
QueryRow(),多行用Query()配合rows.Scan();务必在循环后检查rows.Err()。 - 事务:使用
db.Begin()获取事务对象tx,在错误时tx.Rollback(),成功时tx.Commit();复杂场景可用保存点(Savepoint)实现细粒度回滚。 - 示例(事务转账)
tx, err := db.Begin() if err != nil { log.Fatal(err) } defer func() { if p := recover(); p != nil { tx.Rollback(); panic(p) } } () _, err = tx.Exec("UPDATE accounts SET balance = balance - ? WHERE id = ?", 100, 1) if err != nil { tx.Rollback(); return } _, err = tx.Exec("UPDATE accounts SET balance = balance + ? WHERE id = ?", 100, 2) if err != nil { tx.Rollback(); return } if err = tx.Commit(); err != nil { log.Fatal(err) } - 建议:对高频重复语句使用
Prepare提升性能与安全性;对批量写入使用事务减少提交开销。
五 生产实践与排错要点
- 连接池与性能:根据 QPS/并发 调整
MaxOpenConns(如 CPU 核数的 2–3 倍)、MaxIdleConns(约为 MaxOpenConns 的 50%)、ConnMaxLifetime(如 30 分钟–2 小时);通过db.Stats()监控连接状态。 - 配置与安全:
- MySQL DSN 使用 utf8mb4 与
parseTime=True& loc=Local正确处理字符与时区; - 凭证使用环境变量或配置中心管理,避免硬编码;
- 远程访问 PostgreSQL 时,修改
postgresql.conf的listen_addresses与pg_hba.conf并重启服务。
- MySQL DSN 使用 utf8mb4 与
- 错误处理:区分
sql.ErrNoRows与数据库特定错误(如 MySQL 错误码 1062 唯一键冲突);必要时实现指数退避重试。 - 迁移与可维护性:使用 golang-migrate 管理版本化迁移;为关键路径 SQL 建立索引、用
EXPLAIN分析执行计划;分页优先 键集分页 提升大表性能。 - 监控与日志:集成 Prometheus 指标(如查询耗时直方图)与慢查询日志,便于定位瓶颈。
声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!
若转载请注明出处: Go语言在Linux中的数据库操作指南
本文地址: https://pptw.com/jishu/773042.html
