golang分布式SQL数据库插件库tidb的使用

Golang分布式SQL数据库插件库TiDB的使用

TiDB简介

TiDB (/’taɪdiːbi:/, "Ti"代表钛) 是一个开源的云原生分布式SQL数据库,设计用于高可用性、水平和垂直可扩展性、强一致性和高性能。

TiDB, a distributed SQL database

主要特性

  • 分布式事务:TiDB使用两阶段提交协议确保ACID合规性,提供强一致性。
  • 水平和垂直扩展:TiDB可以通过添加更多节点水平扩展,或通过增加现有节点资源垂直扩展,无需停机。
  • 高可用性:内置Raft共识协议确保可靠性和自动故障转移。
  • 混合事务/分析处理(HTAP):提供TiKV(行存储引擎)和TiFlash(列存储引擎)两种存储引擎。
  • 云原生:可在公有云、本地或Kubernetes中原生部署。
  • MySQL兼容:兼容MySQL 8.0,可以使用熟悉的协议、框架和工具。
  • 开源承诺:所有源代码在Apache 2.0许可下在GitHub上可用。

快速开始

1. 启动TiDB集群

本地测试集群

参考TiDB快速入门指南部署本地测试集群。

Kubernetes部署

使用TiDB Operator可以轻松在自管理的Kubernetes环境或公有云上的Kubernetes服务中部署TiDB。

使用TiDB Cloud(推荐)

TiDB Cloud提供完全托管的TiDB版本,包含免费层级,无需信用卡即可在几秒钟内获得免费集群。

2. 使用Golang连接TiDB

下面是一个使用Golang连接TiDB的完整示例:

package main

import (
	"database/sql"
	"fmt"
	"log"

	_ "github.com/go-sql-driver/mysql" // MySQL驱动
)

func main() {
	// 连接TiDB数据库
	// 格式: "用户名:密码@tcp(主机:端口)/数据库名"
	db, err := sql.Open("mysql", "root:@tcp(127.0.0.1:4000)/test")
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()

	// 测试连接
	err = db.Ping()
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("成功连接到TiDB数据库!")

	// 创建表
	_, err = db.Exec(`
		CREATE TABLE IF NOT EXISTS users (
			id INT AUTO_INCREMENT PRIMARY KEY,
			name VARCHAR(100) NOT NULL,
			email VARCHAR(100) NOT NULL UNIQUE,
			created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
		)
	`)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("表创建成功!")

	// 插入数据
	res, err := db.Exec("INSERT INTO users (name, email) VALUES (?, ?)", "张三", "zhangsan@example.com")
	if err != nil {
		log.Fatal(err)
	}
	id, _ := res.LastInsertId()
	fmt.Printf("插入成功,ID: %d\n", id)

	// 查询数据
	rows, err := db.Query("SELECT id, name, email FROM users")
	if err != nil {
		log.Fatal(err)
	}
	defer rows.Close()

	fmt.Println("查询结果:")
	for rows.Next() {
		var id int
		var name, email string
		err = rows.Scan(&id, &name, &email)
		if err != nil {
			log.Fatal(err)
		}
		fmt.Printf("ID: %d, Name: %s, Email: %s\n", id, name, email)
	}

	// 更新数据
	_, err = db.Exec("UPDATE users SET name = ? WHERE id = ?", "张三Updated", id)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("更新成功!")

	// 删除数据
	_, err = db.Exec("DELETE FROM users WHERE id = ?", id)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("删除成功!")
}

3. 使用ORM连接TiDB

你也可以使用Golang的ORM框架如GORM来连接TiDB:

package main

import (
	"fmt"
	"log"

	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

type User struct {
	ID        uint   `gorm:"primaryKey"`
	Name      string `gorm:"size:100;not null"`
	Email     string `gorm:"size:100;unique;not null"`
	CreatedAt int64  `gorm:"autoCreateTime"`
}

func main() {
	// 连接TiDB
	dsn := "root:@tcp(127.0.0.1:4000)/test?charset=utf8mb4&parseTime=True&loc=Local"
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
	if err != nil {
		log.Fatal(err)
	}

	// 自动迁移
	err = db.AutoMigrate(&User{})
	if err != nil {
		log.Fatal(err)
	}

	// 创建记录
	user := User{Name: "李四", Email: "lisi@example.com"}
	result := db.Create(&user)
	if result.Error != nil {
		log.Fatal(result.Error)
	}
	fmt.Printf("创建成功,ID: %d\n", user.ID)

	// 查询记录
	var foundUser User
	db.First(&foundUser, user.ID)
	fmt.Printf("查询结果: %+v\n", foundUser)

	// 更新记录
	db.Model(&foundUser).Update("Name", "李四Updated")
	fmt.Println("更新成功!")

	// 删除记录
	db.Delete(&foundUser)
	fmt.Println("删除成功!")
}

TiDB架构

TiDB architecture

获取帮助

  • 可以通过Discord、Slack、Stack Overflow、TiDB论坛等社区平台与TiDB用户联系
  • 如需报告bug、建议改进或请求新功能,请使用Github Issues
  • 故障排除请参考故障排除文档

许可证

TiDB采用Apache 2.0许可证。


更多关于golang分布式SQL数据库插件库tidb的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang分布式SQL数据库插件库tidb的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


TiDB 分布式 SQL 数据库的 Golang 使用指南

TiDB 是一个开源的分布式 SQL 数据库,兼容 MySQL 协议,具有水平扩展、强一致性和高可用性等特点。下面我将介绍如何在 Golang 中使用 TiDB。

1. 安装驱动

首先需要安装 MySQL 驱动,因为 TiDB 兼容 MySQL 协议:

go get -u github.com/go-sql-driver/mysql

2. 基本连接示例

package main

import (
	"database/sql"
	"fmt"
	"log"

	_ "github.com/go-sql-driver/mysql"
)

func main() {
	// 连接TiDB
	// 格式: "用户名:密码@tcp(主机:端口)/数据库名?参数"
	db, err := sql.Open("mysql", "root:@tcp(127.0.0.1:4000)/test?charset=utf8mb4")
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()

	// 测试连接
	err = db.Ping()
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("成功连接到TiDB!")
}

3. 基本CRUD操作

创建表

func createTable(db *sql.DB) {
	sql := `CREATE TABLE IF NOT EXISTS users (
		id BIGINT PRIMARY KEY AUTO_INCREMENT,
		name VARCHAR(50) NOT NULL,
		age INT,
		created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
	)`
	
	_, err := db.Exec(sql)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("表创建成功")
}

插入数据

func insertData(db *sql.DB) {
	result, err := db.Exec("INSERT INTO users (name, age) VALUES (?, ?)", "张三", 25)
	if err != nil {
		log.Fatal(err)
	}
	
	id, _ := result.LastInsertId()
	fmt.Printf("插入成功,ID: %d\n", id)
}

查询数据

func queryData(db *sql.DB) {
	rows, err := db.Query("SELECT id, name, age FROM users")
	if err != nil {
		log.Fatal(err)
	}
	defer rows.Close()
	
	for rows.Next() {
		var id int64
		var name string
		var age int
		err = rows.Scan(&id, &name, &age)
		if err != nil {
			log.Fatal(err)
		}
		fmt.Printf("ID: %d, Name: %s, Age: %d\n", id, name, age)
	}
}

更新数据

func updateData(db *sql.DB) {
	result, err := db.Exec("UPDATE users SET age = ? WHERE name = ?", 30, "张三")
	if err != nil {
		log.Fatal(err)
	}
	
	rowsAffected, _ := result.RowsAffected()
	fmt.Printf("更新了 %d 行\n", rowsAffected)
}

删除数据

func deleteData(db *sql.DB) {
	result, err := db.Exec("DELETE FROM users WHERE name = ?", "张三")
	if err != nil {
		log.Fatal(err)
	}
	
	rowsAffected, _ := result.RowsAffected()
	fmt.Printf("删除了 %d 行\n", rowsAffected)
}

4. 事务处理

TiDB 支持分布式事务,使用方式与MySQL类似:

func transactionExample(db *sql.DB) {
	tx, err := db.Begin()
	if err != nil {
		log.Fatal(err)
	}
	
	defer func() {
		if err != nil {
			tx.Rollback()
			return
		}
		err = tx.Commit()
		if err != nil {
			log.Fatal(err)
		}
	}()
	
	// 执行事务操作
	_, err = tx.Exec("INSERT INTO users (name, age) VALUES (?, ?)", "李四", 28)
	if err != nil {
		return
	}
	
	_, err = tx.Exec("UPDATE users SET age = age + 1 WHERE name = ?", "王五")
	if err != nil {
		return
	}
	
	fmt.Println("事务执行成功")
}

5. 连接池配置

TiDB 作为分布式数据库,合理的连接池配置很重要:

func setupDB() *sql.DB {
	db, err := sql.Open("mysql", "root:@tcp(127.0.0.1:4000)/test")
	if err != nil {
		log.Fatal(err)
	}
	
	// 设置连接池参数
	db.SetMaxOpenConns(100)          // 最大打开连接数
	db.SetMaxIdleConns(10)           // 最大空闲连接数
	db.SetConnMaxLifetime(time.Hour)  // 连接最大存活时间
	
	return db
}

6. 使用ORM框架

虽然可以直接使用database/sql,但ORM框架可以简化开发:

使用GORM

package main

import (
	"fmt"
	"log"
	
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

type User struct {
	ID        uint   `gorm:"primaryKey"`
	Name      string
	Age       int
	CreatedAt time.Time
}

func main() {
	dsn := "root:@tcp(127.0.0.1:4000)/test?charset=utf8mb4&parseTime=True&loc=Local"
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
	if err != nil {
		log.Fatal(err)
	}
	
	// 自动迁移
	db.AutoMigrate(&User{})
	
	// 创建记录
	user := User{Name: "赵六", Age: 35}
	result := db.Create(&user)
	if result.Error != nil {
		log.Fatal(result.Error)
	}
	fmt.Printf("创建成功,ID: %d\n", user.ID)
	
	// 查询
	var users []User
	db.Find(&users)
	for _, u := range users {
		fmt.Printf("ID: %d, Name: %s, Age: %d\n", u.ID, u.Name, u.Age)
	}
}

7. 性能优化建议

  1. 批量插入:使用批量插入提高性能

    // 批量插入示例
    stmt, err := db.Prepare("INSERT INTO users (name, age) VALUES (?, ?)")
    for i := 0; i < 100; i++ {
        _, err = stmt.Exec(fmt.Sprintf("用户%d", i), 20+i%10)
    }
    
  2. 使用预处理语句:减少SQL解析开销

  3. 合理设计分片键:TiDB会根据主键或唯一索引自动分片

  4. 监控慢查询:通过TiDB Dashboard监控慢查询

  5. 适当使用索引:与MySQL类似,合理使用索引提高查询性能

8. 注意事项

  1. TiDB 兼容MySQL协议,但不是100%兼容所有MySQL特性
  2. 分布式事务性能比单机事务低,设计时应考虑这一点
  3. 大数据量场景下,查询可能需要优化
  4. TiDB的AUTO_INCREMENT与MySQL有细微差别

通过以上示例和说明,你应该能够在Golang项目中开始使用TiDB数据库了。TiDB的分布式特性使其非常适合大规模数据和高并发场景,同时保持了SQL的易用性。

回到顶部