Facebook 開源 Golang 實體框架 Ent 支援分散式資料庫 TiDB

LZZ發表於2022-03-25

近日,Facebook 開源的 Golang 實體框架 Ent 完成了對 TiDB 資料庫的支援。

Ent 是一款易於構建和維護應用程式與大資料模型的框架。具有以下特點:

  • Schema 即程式碼:能將任何資料庫表建模為 Go 物件;
  • 輕鬆地遍歷任何圖形 :可以輕鬆地執行查詢、聚合和遍歷任何圖形結構;
  • 靜態型別和顯式 API:使用程式碼生成靜態型別和顯式 API,查詢資料更加便捷;
  • 多儲存驅動程式:支援 MySQL、PostgreSQL、SQLite、Gremlin,現在也已經支援了 TiDB;
  • 可擴充套件:易於擴充套件和使用 Go 模板自定義。

TiDBPingCAP 公司自主設計、研發的開源分散式關係型資料庫,是一款同時支援線上事務處理與線上分析處理 (Hybrid Transactional and Analytical Processing, HTAP) 的融合型分散式資料庫產品,具備水平擴容或者縮容、金融級高可用、實時 HTAP、雲原生的分散式資料庫、相容 MySQL 5.7 協議和 MySQL 生態等重要特性。目標是為使用者提供一站式 OLTP (Online Transactional Processing)、OLAP (Online Analytical Processing)、HTAP 解決方案。TiDB 適合高可用、強一致要求較高、資料規模較大等各種應用場景。

下面透過一個 Hello World 的應用示例,來看下如何快速實現一個基於 Ent + TiDB 的應用。

Hello World 應用示例

  1. 用 Docker 在本地啟動一個 TiDB Server
    docker run -p 4000:4000 pingcap/tidb

現在你已經有一個執行的 TiDB 例項,開放了 4000 埠監聽。

  1. 在本地複製 hello world 的示例 repo
    git clone https://github.com/hedwigz/tidb-hello-world.git

在這個示例 repo 中我們定義了一個簡單的 User schema

go title="ent/schema/user.go"
 func (User) Fields() []ent.Field {
           return []ent.Field{
                  field.Time("created_at").
                          Default(time.Now),
                  field.String("name"),
                  field.Int("age"),
          }
 }

然後,連線 Ent 和 TiDB:

go title="main.go"
client, err := ent.Open("mysql", "root@tcp(localhost:4000)/test?parseTime=true")
 if err != nil {
         log.Fatalf("failed opening connection to TiDB: %v", err)
 }
 defer client.Close()
 // Run the auto migration tool, with Atlas.
 if err := client.Schema.Create(context.Background(), schema.WithAtlas(true)); err != nil {
         log.Fatalf("failed printing schema changes: %v", err)
 }

可以看到,在第一行我們透過一個 MySQL 語句去連線 TiDB Server,因為 TiDB 是相容 MySQL 的,所以不需要其他特殊的 driver。
話雖如此,TiDB 和 MySQL 還是有很多不同,尤其是與 Schema 遷移相關的操作,比如 SQL 診斷和遷移規劃。所以,Atlas 可以自動監測出是連線到 TiDB,做相應的遷移處理。
此外,第七行我們使用 schema.WithAtlas(true),表示 Ent 是使用“Atlas”作為遷移引擎。Atlas 是 Ent 剛剛釋出的遷移引擎,得益於 Atlas 的最新設計,對新資料庫的支援也變得前所未有的簡單。

最後,我們新建一條 user 資料,並儲存到 TiDB 中,以用於後需的資料讀取和輸出。

go title="main.go"
 client.User.Create().
                SetAge(30).
                SetName("hedwigz").
                SaveX(context.Background())
 user := client.User.Query().FirstX(context.Background())
 fmt.Printf("the user: %s is %d years old\n", user.Name, user.Age)
  1. 執行這個示例程式:
    $ go run main.go
    the user: hedwigz is 30 years old

在這次快速演練中,我們成功實現了:

  • 啟動一個本地的 TiDB 例項;
  • 連線 Ent 和 TiDB 資料庫;
  • 使用 Atlas 遷移 Ent Schema;
  • 使用 Ent 從 TiDB 中插入和讀取資料;

版本說明

目前,這個示例應用在 Ent v0.10 和 TiDB v5.4.0 中可以正常執行,Ent 也計劃在未來繼續擴充對 TiDB 的支援。如果你使用其他版本的 TiDB 或者需要幫助,歡迎加入 asktug.com 來交流。如果你也有專案希望與 TiDB 適配,歡迎來 GitHub 提交 issue

除了 Ent,TiDB 此前已經新增了對 GORM 和 go-sql-driver/mysql 的支援,詳情可檢視文件:docs.pingcap.com/appdev/dev

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章