知识点:
超强大的TiDB
本课内容:
大家好,欢迎来到谷雨课堂
在以前的课程里我们讲过连接MySQL数据库,
以及实现一个MySQL协议的数据库,
今天谷雨老师和大家一起,
实现一个完整的兼容MySQL5.7协议的数据库,
今天的主角是TiDB!
TiDB是一个功能强大的开源数据库,
而且他是一个高并发、分布式的数据库,
更重要的是,
TiDB的大部分模块是用Go来开发的,
所以我们用Go可以很方便的集成TiDB的大部分功能,
以下代码就完整的实现了一台数据库服务器,
启动后可以使用PhpMyadmin或Navicat进行正常连接使用,
同时也可以在代码中进行任何的SQL操作,
以下是全部代码:
package main
import (
"context"
"database/sql"
"fmt"
"log"
"os"
"os/signal"
"syscall"
"github.com/pingcap/errors"
"github.com/pingcap/tidb/session"
"github.com/pingcap/tidb/sessionctx"
"github.com/pingcap/tidb/types"
"github.com/pingcap/tidb/util/chunk"
"github.com/pingcap/tidb/util/sqlexec"
)
var tidbServer1 *TiDBServer
var ses session.Session
// GetRows4Test gets all the rows from a RecordSet, only used for test.
func GetRows4Test(ctx context.Context, sctx sessionctx.Context, rs sqlexec.RecordSet) ([]chunk.Row, error) {
if rs == nil {
return nil, nil
}
var rows []chunk.Row
req := rs.NewChunk()
// Must reuse `req` for imitating server.(*clientConn).writeChunks
for {
err := rs.Next(ctx, req)
if err != nil {
return nil, err
}
if req.NumRows() == 0 {
break
}
iter := chunk.NewIterator4Chunk(req.CopyConstruct())
for row := iter.Begin(); row != iter.End(); row = iter.Next() {
rows = append(rows, row)
}
}
return rows, nil
}
func ResultSetToStringSlice(ctx context.Context, s session.Session, rs sqlexec.RecordSet) ([][]string, error) {
rows, err := GetRows4Test(ctx, s, rs)
if err != nil {
return nil, err
}
err = rs.Close()
if err != nil {
return nil, err
}
sRows := make([][]string, len(rows))
for i := range rows {
row := rows[i]
iRow := make([]string, row.Len())
for j := 0; j < row.Len(); j++ {
if row.IsNull(j) {
iRow[j] = ""
} else {
d := row.GetDatum(j, &rs.Fields()[j].Column.FieldType)
iRow[j], err = d.ToString()
if err != nil {
return nil, err
}
}
}
sRows[i] = iRow
}
return sRows, nil
}
func Exec(sql string, args ...interface{}) (sqlexec.RecordSet, error) {
var err error
if ses == nil {
ses, err = tidbServer1.GetSession()
if err != nil {
return nil, err
}
}
ctx := context.Background()
if len(args) == 0 {
sc := ses.GetSessionVars().StmtCtx
prevWarns := sc.GetWarnings()
rss, err := ses.Execute(ctx, sql)
if err != nil {
return nil, errors.Trace(err)
}
warns := sc.GetWarnings()
parserWarns := warns[len(prevWarns):]
var rs0 sqlexec.RecordSet
for i, rs := range rss {
if i == 0 {
rs0 = rs
}
if err != nil {
ses.GetSessionVars().StmtCtx.AppendError(err)
return nil, errors.Trace(err)
}
}
if len(parserWarns) > 0 {
fmt.Println(parserWarns)
}
return rs0, nil
}
stmtID, _, _, err := ses.PrepareStmt(sql)
if err != nil {
return nil, errors.Trace(err)
}
params := make([]types.Datum, len(args))
for i := 0; i < len(params); i++ {
params[i] = types.NewDatum(args[i])
}
rs, err := ses.ExecutePreparedStmt(ctx, stmtID, params)
if err != nil {
return nil, errors.Trace(err)
}
err = ses.DropPreparedStmt(stmtID)
if err != nil {
return nil, errors.Trace(err)
}
return rs, nil
}
func main() {
str, _ := os.Getwd()
fmt.Println(str)
tidbServer1, _ = NewTiDBServer("d:/ysdb2", 4002)
defer tidbServer1.Close()
fmt.Println(Exec("use guyu"))
a, e := Exec("select * from tbl_guyu where k=? ", "111")
fmt.Println(a, e)
if e == nil {
cntFields := len(a.Fields())
fmt.Println("字段数:", cntFields)
for idx, colInfo := range a.Fields() {
fmt.Println(idx,
colInfo.Column.FieldType.Tp,
colInfo.Column.Name.String())
}
r, e := ResultSetToStringSlice(context.TODO(), ses, a)
if e == nil {
fmt.Println("结果:", r)
}
}
dbConn, _ := tidbServer1.CreateConn()
result, _ := dbConn.Query("SELECT now()")
defer result.Close()
var version sql.NullString
for result.Next() {
result.Scan(&version)
break
}
fmt.Println("-->", version)
signalCh := make(chan os.Signal, 1)
signal.Notify(signalCh, os.Interrupt, syscall.SIGTERM)
sigQuit := <-signalCh
log.Println(sigQuit)
log.Println("Server Quit")
tidbServer1.Close()
}
扩展阅读:
TiDB 是 PingCAP 公司自主设计、研发的
开源分布式关系型数据库,
是一款同时支持在线事务处理与在线分析处理
(Hybrid Transactional and Analytical Processing, HTAP) 的
融合型分布式数据库产品,
具备水平扩容或者缩容、
金融级高可用、实时 HTAP、
云原生的分布式数据库、
兼容 MySQL 5.7 协议和 MySQL 生态等重要特性。
目标是为用户提供一站式 OLTP (Online Transactional Processing)、
OLAP (Online Analytical Processing)、
HTAP 解决方案。
TiDB 适合高可用、
强一致要求较高、
数据规模较大等各种应用场景。
完整的源代码可以登录【华纳网】下载。
https://www.worldwarner.com/
免责声明:本文仅代表作者个人观点,与华纳网无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。