删除

本文档介绍了如何删除存储在 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 开头的一系列行:

Java

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

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

import com.google.cloud.bigtable.admin.v2.BigtableTableAdminClient;
import java.io.IOException;

public class DropRowRangeExample {
  public void dropRowRange(String projectId, String instanceId, String tableId) throws IOException {
    try (BigtableTableAdminClient tableAdminClient =
        BigtableTableAdminClient.create(projectId, instanceId)) {
      tableAdminClient.dropRowRange(tableId, "phone#4c410523");
    }
  }
}

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 请求以确定要删除的内容,然后发送删除请求。如需查看可用的过滤条件列表,请参阅过滤条件

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

从列中删除

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

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=True)
    instance = client.instance(instance_id)
    table = instance.table(table_id)
    row = table.row("phone#4c410523#20190501")
    row.delete_cell(column_family_id="cell_plan", column="data_plan_01gb")
    row.commit()

Python asyncio

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

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

async def delete_from_column(project_id, instance_id, table_id):
    from google.cloud.bigtable.data import BigtableDataClientAsync
    from google.cloud.bigtable.data import DeleteRangeFromColumn

    client = BigtableDataClientAsync(project=project_id)
    table = client.get_table(instance_id, table_id)

    await table.mutate_row(
        "phone#4c410523#20190501",
        DeleteRangeFromColumn(family="cell_plan", qualifier=b"data_plan_01gb"),
    )

    await table.close()
    await client.close()

Node.js

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

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

await table.mutate({
  key: 'phone#4c410523#20190501',
  method: 'delete',
  data: {
    column: 'cell_plan:data_plan_05gb',
  },
});
await printRows();

从列族中删除

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

Java

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

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

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

public class DeleteFromColumnFamilyExample {
  public void deleteFromColumnFamily(String projectId, String instanceId, String tableId)
      throws IOException {
    try (BigtableDataClient dataClient = BigtableDataClient.create(projectId, instanceId)) {
      dataClient.mutateRow(
          RowMutation.create(TableId.of(tableId), "phone#5c10102#20190501")
              .deleteFamily("stats_summary"));
    }
  }
}

Python

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

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

def delete_from_column_family(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 = table.row("phone#4c410523#20190501")
    row.delete_cells(column_family_id="cell_plan", columns=row.ALL_COLUMNS)
    row.commit()

Python asyncio

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

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

async def delete_from_column_family(project_id, instance_id, table_id):
    from google.cloud.bigtable.data import BigtableDataClientAsync
    from google.cloud.bigtable.data import DeleteAllFromFamily

    client = BigtableDataClientAsync(project=project_id)
    table = client.get_table(instance_id, table_id)

    await table.mutate_row("phone#4c410523#20190501", DeleteAllFromFamily("cell_plan"))

    await table.close()
    await client.close()

Node.js

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

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

await table.mutate({
  key: 'phone#4c410523#20190501',
  method: 'delete',
  data: {
    column: 'cell_plan',
  },
});
await printRows();

从行中删除

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

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 DeleteFromRowExample {
  public void deleteFromRow(String projectId, String instanceId, String tableId)
      throws IOException {
    try (BigtableDataClient dataClient = BigtableDataClient.create(projectId, instanceId)) {
      Mutation mutation = Mutation.create().deleteRow();
      dataClient.mutateRow(
          RowMutation.create(TableId.of(tableId), "phone#4c410523#20190501", mutation));
    }
  }
}

Python

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

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

def delete_from_row(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 = table.row("phone#4c410523#20190501")
    row.delete()
    row.commit()

Python asyncio

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

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

async def delete_from_row(project_id, instance_id, table_id):
    from google.cloud.bigtable.data import BigtableDataClientAsync
    from google.cloud.bigtable.data import DeleteAllFromRow

    client = BigtableDataClientAsync(project=project_id)
    table = client.get_table(instance_id, table_id)

    await table.mutate_row("phone#4c410523#20190501", DeleteAllFromRow())

    await table.close()
    await client.close()

Node.js

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

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

const row = table.row('phone#4c410523#20190501');
await row.delete();
await printRows();

通过流式处理和批量删除

流式处理和批量删除请求通常是删除大量数据的最佳方式。如果您拥有比垃圾回收政策更精细的数据保留要求,则此策略非常有用。

如果您的应用是用 Java 编写的,那么在向 Bigtable 发送批量删除时,您可以启用批量写入流控制。如需了解详情,请参阅批量写入流控制。如需了解如何启用该功能,请参阅启用批量写入流控制

以下代码段会启动数据流(读取行),对其进行批量处理,然后对其进行批量处理并删除 cell_plan 列族中 data_plan_01gb1 列的所有单元:

Java

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

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

import com.google.api.gax.batching.Batcher;
import com.google.api.gax.rpc.ServerStream;
import com.google.cloud.bigtable.data.v2.BigtableDataClient;
import com.google.cloud.bigtable.data.v2.models.Query;
import com.google.cloud.bigtable.data.v2.models.Row;
import com.google.cloud.bigtable.data.v2.models.RowMutationEntry;
import com.google.cloud.bigtable.data.v2.models.TableId;
import java.io.IOException;

public class BatchDeleteExample {
  public void batchDelete(String projectId, String instanceId, String tableId)
      throws InterruptedException, IOException {
    try (BigtableDataClient dataClient = BigtableDataClient.create(projectId, instanceId)) {
      try (Batcher<RowMutationEntry, Void> batcher =
          dataClient.newBulkMutationBatcher(TableId.of(tableId))) {
        ServerStream<Row> rows = dataClient.readRows(Query.create(TableId.of(tableId)));
        for (Row row : rows) {
          batcher.add(
              RowMutationEntry.create(row.getKey()).deleteCells("cell_plan", "data_plan_05gb"));
        }
        // Blocks until mutations are applied on all submitted row entries.
        batcher.flush();
      }
    }
  }
}

Python

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

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

def streaming_and_batching(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)
    batcher = table.mutations_batcher(flush_count=2)
    rows = table.read_rows()
    for row in rows:
        row = table.row(row.row_key)
        row.delete_cell(column_family_id="cell_plan", column="data_plan_01gb")

    batcher.mutate_rows(rows)

Python asyncio

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

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

async def streaming_and_batching(project_id, instance_id, table_id):
    from google.cloud.bigtable.data import BigtableDataClientAsync
    from google.cloud.bigtable.data import DeleteRangeFromColumn
    from google.cloud.bigtable.data import RowMutationEntry
    from google.cloud.bigtable.data import ReadRowsQuery

    client = BigtableDataClientAsync(project=project_id)
    table = client.get_table(instance_id, table_id)

    async with table.mutations_batcher() as batcher:
        async for row in await table.read_rows_stream(ReadRowsQuery(limit=10)):
            await batcher.append(
                RowMutationEntry(
                    row.row_key,
                    DeleteRangeFromColumn(
                        family="cell_plan", qualifier=b"data_plan_01gb"
                    ),
                )
            )

    await table.close()
    await client.close()

Node.js

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

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

const rows = (await table.getRows({limit: 2}))[0];
const entries = rows.map(row => {
  return {
    key: row.id,
    method: 'delete',
    data: {
      column: 'cell_plan:data_plan_05gb',
    },
  };
});
await table.mutate(entries);
await printRows();

删除已获授权的视图中的数据

您可以向已获授权的视图发送删除请求,以删除表数据。您必须使用以下其中一项:

  • gcloud CLI
  • Java 版 Bigtable 客户端

从授权视图中删除数据时,您需要提供授权视图 ID 以及表 ID。

您可以从授权视图中删除的数据受授权视图定义的限制。您只能删除授权视图中包含的数据。如果您尝试删除不在授权视图定义范围内或受以下规则约束的数据,系统会返回 PERMISSION_DENIED 错误:

  • 不支持在 Admin API 中使用 DropRowRange 从已获授权的数据视图中删除一组行。
  • 不支持从行中删除。
  • 系统支持从列中删除数据,前提是删除的数据位于已获授权的视图中。
  • 只有在指定列族配置为允许在已获授权的视图中使用所有列限定符前缀 (qualifier_prefixes="") 时,才允许从列族中删除数据。

例如,如果您尝试从指定行中删除数据,而该行包含底层表中不属于您已获授权视图的列,则请求会失败。

后续步骤