這個範例是一個非常簡單的「hello world」應用程式 (以 Go 語言撰寫),可以協助您瞭解如何進行下列各項操作:
- 連線到 Cloud Bigtable 執行個體。
- 建立新的資料表。
- 將資料寫入資料表。
- 讀取資料。
- 刪除資料表。
執行這個範例
本範例使用 GO 適用的 Google Cloud 用戶端程式庫的 Cloud Bigtable 套件,與 Cloud Bigtable 進行通訊。
若要執行本範例程式,請遵循 GitHub 範例的操作說明。
搭配 Cloud 用戶端程式庫使用 Cloud Bigtable
本範例應用程式連線至 Cloud Bigtable,並示範一些簡易的操作。
匯入用戶端程式庫
本範例使用下列匯入功能:
import (
"context"
"flag"
"fmt"
"log"
"cloud.google.com/go/bigtable"
)
連線到 Cloud Bigtable,以管理資料表
如要管理資料表,請使用 bigtable.NewAdminClient()
連線至 Cloud BigTable。
adminClient, err := bigtable.NewAdminClient(ctx, *project, *instance)
if err != nil {
log.Fatalf("Could not create admin client: %v", err)
}
建立資料表
使用 AdminClient.CreateTable()
建立資料表,並使用 AdminClient.TableInfo()
取得資料表的相關資訊。接著使用 AdminClient.CreateColumnFamily()
建立資料欄系列。
tables, err := adminClient.Tables(ctx)
if err != nil {
log.Fatalf("Could not fetch table list: %v", err)
}
if !sliceContains(tables, tableName) {
log.Printf("Creating table %s", tableName)
if err := adminClient.CreateTable(ctx, tableName); err != nil {
log.Fatalf("Could not create table %s: %v", tableName, err)
}
}
tblInfo, err := adminClient.TableInfo(ctx, tableName)
if err != nil {
log.Fatalf("Could not read info for table %s: %v", tableName, err)
}
if !sliceContains(tblInfo.Families, columnFamilyName) {
if err := adminClient.CreateColumnFamily(ctx, tableName, columnFamilyName); err != nil {
log.Fatalf("Could not create column family %s: %v", columnFamilyName, err)
}
}
連線到 Cloud Bigtable 以管理資料
如要管理資料,請使用 bigtable.NewClient()
連線至 Cloud BigTable。
client, err := bigtable.NewClient(ctx, *project, *instance)
if err != nil {
log.Fatalf("Could not create data operations client: %v", err)
}
將資料列寫入資料表
開啟您想要寫入的資料表。使用 bigtable.NewMutation()
在單一資料列上建立變異作業,接著使用 Mutation.Set()
設定資料列的值。為每一個資料列產生一個不同的列鍵值。重複這些步驟,以建立多筆變異。最後,使用 Table.ApplyBulk()
將所有變異套用到資料表。
tbl := client.Open(tableName)
muts := make([]*bigtable.Mutation, len(greetings))
rowKeys := make([]string, len(greetings))
log.Printf("Writing greeting rows to table")
for i, greeting := range greetings {
muts[i] = bigtable.NewMutation()
muts[i].Set(columnFamilyName, columnName, bigtable.Now(), []byte(greeting))
// Each row has a unique row key.
//
// Note: This example uses sequential numeric IDs for simplicity, but
// this can result in poor performance in a production application.
// Since rows are stored in sorted order by key, sequential keys can
// result in poor distribution of operations across nodes.
//
// For more information about how to design a Bigtable schema for the
// best performance, see the documentation:
//
// https://cloud.google.com/bigtable/docs/schema-design
rowKeys[i] = fmt.Sprintf("%s%d", columnName, i)
}
rowErrs, err := tbl.ApplyBulk(ctx, rowKeys, muts)
if err != nil {
log.Fatalf("Could not apply bulk row mutation: %v", err)
}
if rowErrs != nil {
for _, rowErr := range rowErrs {
log.Printf("Error writing row: %v", rowErr)
}
log.Fatalf("Could not write some rows")
}
依鍵值讀取資料列
透過 Table.ReadRow()
使用資料列的索引鍵直接取得資料列。
log.Printf("Getting a single greeting by row key:")
row, err := tbl.ReadRow(ctx, rowKeys[0], bigtable.RowFilter(bigtable.ColumnFilter(columnName)))
if err != nil {
log.Fatalf("Could not read row with key %s: %v", rowKeys[0], err)
}
log.Printf("\t%s = %s\n", rowKeys[0], string(row[columnFamilyName][0].Value))
掃描所有的資料表列
使用 Table.ReadRows()
掃描資料表中的所有資料列。
使用完畢後,請關閉資料用戶端。
log.Printf("Reading all greeting rows:")
err = tbl.ReadRows(ctx, bigtable.PrefixRange(columnName), func(row bigtable.Row) bool {
item := row[columnFamilyName][0]
log.Printf("\t%s = %s\n", item.Row, string(item.Value))
return true
}, bigtable.RowFilter(bigtable.ColumnFilter(columnName)))
if err = client.Close(); err != nil {
log.Fatalf("Could not close data operations client: %v", err)
}
刪除資料表
使用 AdminClient.DeleteTable()
刪除資料表。使用完畢後,請關閉管理客戶端。
log.Printf("Deleting the table")
if err = adminClient.DeleteTable(ctx, tableName); err != nil {
log.Fatalf("Could not delete table %s: %v", tableName, err)
}
if err = adminClient.Close(); err != nil {
log.Fatalf("Could not close admin client: %v", err)
}
完整的程式碼範例
以下是不含評論的完整範例。
package main
import (
"context"
"flag"
"fmt"
"log"
"cloud.google.com/go/bigtable"
)
const (
tableName = "Hello-Bigtable"
columnFamilyName = "cf1"
columnName = "greeting"
)
var greetings = []string{"Hello World!", "Hello Cloud Bigtable!", "Hello golang!"}
func sliceContains(list []string, target string) bool {
for _, s := range list {
if s == target {
return true
}
}
return false
}
func main() {
project := flag.String("project", "", "The Google Cloud Platform project ID. Required.")
instance := flag.String("instance", "", "The Google Cloud Bigtable instance ID. Required.")
flag.Parse()
for _, f := range []string{"project", "instance"} {
if flag.Lookup(f).Value.String() == "" {
log.Fatalf("The %s flag is required.", f)
}
}
ctx := context.Background()
adminClient, err := bigtable.NewAdminClient(ctx, *project, *instance)
if err != nil {
log.Fatalf("Could not create admin client: %v", err)
}
tables, err := adminClient.Tables(ctx)
if err != nil {
log.Fatalf("Could not fetch table list: %v", err)
}
if !sliceContains(tables, tableName) {
log.Printf("Creating table %s", tableName)
if err := adminClient.CreateTable(ctx, tableName); err != nil {
log.Fatalf("Could not create table %s: %v", tableName, err)
}
}
tblInfo, err := adminClient.TableInfo(ctx, tableName)
if err != nil {
log.Fatalf("Could not read info for table %s: %v", tableName, err)
}
if !sliceContains(tblInfo.Families, columnFamilyName) {
if err := adminClient.CreateColumnFamily(ctx, tableName, columnFamilyName); err != nil {
log.Fatalf("Could not create column family %s: %v", columnFamilyName, err)
}
}
client, err := bigtable.NewClient(ctx, *project, *instance)
if err != nil {
log.Fatalf("Could not create data operations client: %v", err)
}
tbl := client.Open(tableName)
muts := make([]*bigtable.Mutation, len(greetings))
rowKeys := make([]string, len(greetings))
log.Printf("Writing greeting rows to table")
for i, greeting := range greetings {
muts[i] = bigtable.NewMutation()
muts[i].Set(columnFamilyName, columnName, bigtable.Now(), []byte(greeting))
rowKeys[i] = fmt.Sprintf("%s%d", columnName, i)
}
rowErrs, err := tbl.ApplyBulk(ctx, rowKeys, muts)
if err != nil {
log.Fatalf("Could not apply bulk row mutation: %v", err)
}
if rowErrs != nil {
for _, rowErr := range rowErrs {
log.Printf("Error writing row: %v", rowErr)
}
log.Fatalf("Could not write some rows")
}
log.Printf("Getting a single greeting by row key:")
row, err := tbl.ReadRow(ctx, rowKeys[0], bigtable.RowFilter(bigtable.ColumnFilter(columnName)))
if err != nil {
log.Fatalf("Could not read row with key %s: %v", rowKeys[0], err)
}
log.Printf("\t%s = %s\n", rowKeys[0], string(row[columnFamilyName][0].Value))
log.Printf("Reading all greeting rows:")
err = tbl.ReadRows(ctx, bigtable.PrefixRange(columnName), func(row bigtable.Row) bool {
item := row[columnFamilyName][0]
log.Printf("\t%s = %s\n", item.Row, string(item.Value))
return true
}, bigtable.RowFilter(bigtable.ColumnFilter(columnName)))
if err = client.Close(); err != nil {
log.Fatalf("Could not close data operations client: %v", err)
}
log.Printf("Deleting the table")
if err = adminClient.DeleteTable(ctx, tableName); err != nil {
log.Fatalf("Could not delete table %s: %v", tableName, err)
}
if err = adminClient.Close(); err != nil {
log.Fatalf("Could not close admin client: %v", err)
}
}