删除

本文档介绍了如何删除存储在 Bigtable 表中的数据,讨论了何时应使用每种方法,并提供了示例。在阅读本页内容之前,您应该先熟悉 Bigtable 概览,并了解架构设计所涉及的概念。

为保持一致性,本页面上的说明是指每种请求中使用的 API 方法。不过,我们强烈建议您始终使用其中一个 Bigtable 客户端库来访问 Bigtable API,而不是使用 REST 或 RPC。

本页面上的示例使用示例数据,这些数据类似于您可能存储在 Bigtable 中的数据。

如需了解您每天可以使用此页面上描述的操作的次数,请参阅配额和限制

Bigtable 如何删除数据

发送删除请求时,单元会标记为删除且无法读取。数据会在一周后的压缩过程中移除,此过程会持续优化表。发送删除请求后的几天,删除元数据可能会导致数据略微占用更多空间(每行几 KB),直到下一次压缩为止。

即使您的集群超出存储空间上限并且读写操作被阻止,您也可以始终发送删除请求。

删除一系列行

如果要删除存储在连续行中的大量数据,请使用 dropRowRange。此操作会删除由起始行和结束行或行键前缀标识的一系列行中的所有行。

您在删除一系列行时提供的行键值会被视为服务数据。如需了解服务数据的处理方式,请参阅Google Cloud 隐私权声明

成功删除完成并收到响应后,您可以安全地将数据写入同一行范围。

dropRowRange 操作具有以下限制:

  • 您无法从授权视图中删除一系列行。
  • 您不能异步调用 dropRowRange 方法。如果您在另一个请求正在进行时向某个表发送 dropRowRange 请求,Bigtable 会返回 UNAVAILABLE 错误,并显示消息 A DropRowRange operation is already ongoing。如需解决此错误,请再次发送请求。
  • 对于使用复制功能的实例,请注意,由于复制延迟和 CPU 使用率增加,Bigtable 可能需要很长时间才能完成此操作。如需从使用复制功能的实例中删除数据,请使用 Data API 读取您的数据,然后将其删除

以下代码示例展示了如何丢弃以行键前缀 phone#5c10102 开头的一系列行:

Go

如需了解如何安装和使用 Bigtable 的客户端库,请参阅 Bigtable 客户端库

如需向 Bigtable 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为客户端库设置身份验证


import (
	"context"
	"fmt"
	"io"

	"cloud.google.com/go/bigtable"
)

func dropRowRange(w io.Writer, projectID, instanceID, tableName string) error {
	ctx := context.Background()
	adminClient, err := bigtable.NewAdminClient(ctx, projectID, instanceID)
	if err != nil {
		return fmt.Errorf("bigtable.NewAdminClient: %w", err)
	}
	defer adminClient.Close()

	// Use a specific row key prefix to drop.
	prefix := "phone#4c410523"
	if err := adminClient.DropRowRange(ctx, tableName, prefix); err != nil {
		return fmt.Errorf("adminClient.DropRowRange: %w", err)
	}

	fmt.Fprintf(w, "Successfully dropped row range with prefix: %s\n", prefix)
	return nil
}

Java

如需了解如何安装和使用 Bigtable 的客户端库,请参阅 Bigtable 客户端库

如需向 Bigtable 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为客户端库设置身份验证

import com.google.bigtable.admin.v2.DropRowRangeRequest;
import com.google.cloud.bigtable.admin.v2.BigtableTableAdminClientV2;
import com.google.protobuf.ByteString;
import java.io.IOException;

public class DropRowRangeExample {
  public void dropRowRange(String projectId, String instanceId, String tableId) throws IOException {
    try (BigtableTableAdminClientV2 tableAdminClient = BigtableTableAdminClientV2.create()) {
      DropRowRangeRequest request =
          DropRowRangeRequest.newBuilder()
              .setName("projects/" + projectId + "/instances/" + instanceId + "/tables/" + tableId)
              .setRowKeyPrefix(ByteString.copyFromUtf8("phone#4c410523"))
              .build();
      tableAdminClient.dropRowRange(request);
    }
  }
}

Python

如需了解如何安装和使用 Bigtable 的客户端库,请参阅 Bigtable 客户端库

如需向 Bigtable 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为客户端库设置身份验证

def drop_row_range(project_id, instance_id, table_id):
    from google.cloud.bigtable import Client

    client = Client(project=project_id, admin=True)
    instance = client.instance(instance_id)
    table = instance.table(table_id)
    row_key_prefix = "phone#4c410523"
    table.drop_by_prefix(row_key_prefix, timeout=200)

Node.js

如需了解如何安装和使用 Bigtable 的客户端库,请参阅 Bigtable 客户端库

如需向 Bigtable 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为客户端库设置身份验证

await table.deleteRows('phone#5c10102');
await printRows();

使用 Data API 方法删除数据

如果您需要删除少量非连续数据,则最好使用调用 Cloud Bigtable API(Data API)的方法来删除数据。如果您要在请求中删除 MB(而不是 GB)数据,请使用这些方法。使用 Data API 是从列(而不是列族)中删除数据的唯一方法。

Data API 方法使用以下三种变更类型之一调用 MutateRows

  • DeleteFromColumn
  • DeleteFromFamily
  • DeleteFromRow

使用 Data API 的删除请求是原子化请求:请求成功并且所有数据都会被删除,或者请求失败且未移除任何数据。

在大多数情况下,请避免使用 CheckAndMutate 方法删除数据。在极少数情况下,如果您需要强一致性,可能需要使用此方法,但请注意,这会占用大量资源,且性能可能会受到影响。

如需使用 MutateRows 删除数据,您需要发送包含过滤条件的 readRows 请求以确定要删除的内容,然后发送删除请求。如需查看可用的过滤条件列表,请参阅过滤条件

本部分中的示例假设您已经确定要删除的数据

从列中删除

以下代码示例演示了如何删除某一行中某一列的所有单元:

Go

如需了解如何安装和使用 Bigtable 的客户端库,请参阅 Bigtable 客户端库

如需向 Bigtable 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为客户端库设置身份验证


import (
	"context"
	"fmt"
	"io"

	"cloud.google.com/go/bigtable"
)

func deleteFromColumn(w io.Writer, projectID, instanceID, tableName string) error {
	ctx := context.Background()
	client, err := bigtable.NewClient(ctx, projectID, instanceID)
	if err != nil {
		return fmt.Errorf("bigtable.NewClient: %w", err)
	}
	defer client.Close()
	tbl := client.Open(tableName)

	// Use a specific row key, column family, and column name that exists in your table.
	// This sample assumes a schema with a "cell_plan" column family.
	rowKey := "phone#4c410523#20190501"
	columnFamilyName := "cell_plan"
	columnName := "data_plan_01gb"
	mut := bigtable.NewMutation()
	mut.DeleteCellsInColumn(columnFamilyName, columnName)

	if err := tbl.Apply(ctx, rowKey, mut); err != nil {
		return fmt.Errorf("tbl.Apply: %w", err)
	}

	fmt.Fprintf(w, "Successfully deleted cells from column %s:%s for row: %s\n", columnFamilyName, columnName, rowKey)
	return nil
}

Java

如需了解如何安装和使用 Bigtable 的客户端库,请参阅 Bigtable 客户端库

如需向 Bigtable 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为客户端库设置身份验证

import com.google.cloud.bigtable.data.v2.BigtableDataClient;
import com.google.cloud.bigtable.data.v2.models.Mutation;
import com.google.cloud.bigtable.data.v2.models.RowMutation;
import com.google.cloud.bigtable.data.v2.models.TableId;
import java.io.IOException;

public class DeleteFromColumnExample {
  public void deleteFromColumnCells(String projectId, String instanceId, String tableId)
      throws IOException {
    try (BigtableDataClient dataClient = BigtableDataClient.create(projectId, instanceId)) {
      Mutation mutation = Mutation.create().deleteCells("cell_plan", "data_plan_01gb");
      dataClient.mutateRow(
          RowMutation.create(TableId.of(tableId), "phone#4c410523#20190501", mutation));
    }
  }
}

Python

如需了解如何安装和使用 Bigtable 的客户端库,请参阅 Bigtable 客户端库

如需向 Bigtable 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为客户端库设置身份验证

def delete_from_column(project_id, instance_id, table_id):
    from google.cloud.bigtable import Client

    client = Client(project=project_id, admin