Primeiros passos com o Cloud Spanner em PHP

Objetivos

Este tutorial orienta você nas etapas a seguir usando a biblioteca de cliente do Cloud Spanner para PHP:

  • Criar uma instância e um banco de dados do Cloud Spanner.
  • Gravar, ler e executar consultas SQL em dados contidos no banco de dados.
  • Atualizar o esquema do banco de dados.
  • Atualizar dados usando uma transação de leitura e gravação.
  • Adicionar um índice secundário ao banco de dados.
  • Usar o índice para ler e executar consultas SQL nos dados.
  • Recuperar dados usando uma transação somente leitura.

Custos

Neste tutorial, usamos o Cloud Spanner, que é um componente faturável do Google Cloud Platform. Para informações sobre o custo de utilização do Cloud Spanner, consulte Preços.

Antes de começar

  1. Conclua as etapas descritas em Configuração, que abordam a criação e configuração de um projeto padrão do Google Cloud Platform, a ativação do faturamento, a ativação da API Cloud Spanner e a configuração do OAuth 2.0 para receber credenciais de autenticação e usar a API Cloud Spanner.
    Em especial, execute gcloud auth application-default login para configurar o ambiente local de desenvolvimento com as credenciais de autenticação.

  2. Siga as etapas descritas em Contas de serviço para configurar uma conta de serviço como suas Application Default Credentials. Siga essas etapas para ter um arquivo de chave da conta de serviço (em JSON) e uma variável de ambiente GOOGLE_APPLICATION_CREDENTIALS que permitirão a autenticação na API Cloud Spanner.

  3. Instale os seguintes itens na sua máquina de desenvolvimento se ainda não estiverem instalados:

  4. Clone o repositório do aplicativo de amostra na máquina local:

    git clone https://github.com/GoogleCloudPlatform/php-docs-samples.git
    

    Outra alternativa é fazer download da amostra como um arquivo zip e extraí-la.

  5. Altere para o diretório que contém o código de amostra do Cloud Spanner:

    cd php-docs-samples/spanner
    
  6. Instale as dependências:

    composer install
    

    Isso instalará a biblioteca de cliente do Cloud Spanner para PHP, que pode ser adicionada a qualquer projeto executando a instrução composer require google/cloud-spanner.

Criar uma instância

Ao usar o Cloud Spanner pela primeira vez, é necessário criar uma instância, que é uma alocação de recursos usados pelos bancos de dados do Cloud Spanner. Ao criar uma instância, escolha uma configuração para ela que determine onde os dados serão armazenados e também o número de nós a serem usados. Com isso, é definida a quantidade de recursos de serviço e de armazenamento na instância.

Execute o seguinte comando para criar uma instância do Cloud Spanner na região us-central1 com um nó:

gcloud spanner instances create test-instance --config=regional-us-central1 \
  --description="Test Instance" --nodes=1

A instância criada tem as seguintes características:

  • O ID dela é test-instance.
  • O nome de exibição é Test Instance.
  • A configuração da instância é regional-us-central1. Com as configurações regionais, os dados são armazenados em uma região. Já com as configurações multirregionais, os dados são distribuídos em diversas regiões. Saiba mais em Instâncias.
  • Ela tem um nó. node_count corresponde à quantidade de recursos de serviço e de armazenamento disponíveis para os bancos de dados na instância. Saiba mais em Contagem de nós.

Você verá:

Creating instance...done.

Analisar os arquivos de amostra

O repositório de amostras contém uma amostra que demonstra como usar o Cloud Spanner com PHP.

Dê uma olhada nas funções em src/create_database.php e src/add_column.php, que mostram como criar um banco de dados e modificar um esquema de banco de dados. Os dados usam o esquema de exemplo mostrado na página Modelo de dados e esquema.

Criar um banco de dados

Para criar um banco de dados chamado example-db na instância chamada test-instance, execute o seguinte código na linha de comando:

php spanner.php create-database test-instance example-db

Você verá:

Created database example-db on instance test-instance

Você acabou de criar um banco de dados do Cloud Spanner. Veja a seguir o código que criou o banco de dados.

use Google\Cloud\Spanner\SpannerClient;

/**
 * Creates a database and tables for sample data.
 * Example:
 * ```
 * create_database($instanceId, $databaseId);
 * ```
 *
 * @param string $instanceId The Spanner instance ID.
 * @param string $databaseId The Spanner database ID.
 */
function create_database($instanceId, $databaseId)
{
    $spanner = new SpannerClient();
    $instance = $spanner->instance($instanceId);

    if (!$instance->exists()) {
        throw new \LogicException("Instance $instanceId does not exist");
    }

    $operation = $instance->createDatabase($databaseId, ['statements' => [
        "CREATE TABLE Singers (
            SingerId     INT64 NOT NULL,
            FirstName    STRING(1024),
            LastName     STRING(1024),
            SingerInfo   BYTES(MAX)
        ) PRIMARY KEY (SingerId)",
        "CREATE TABLE Albums (
            SingerId     INT64 NOT NULL,
            AlbumId      INT64 NOT NULL,
            AlbumTitle   STRING(MAX)
        ) PRIMARY KEY (SingerId, AlbumId),
        INTERLEAVE IN PARENT Singers ON DELETE CASCADE"
    ]]);

    print('Waiting for operation to complete...' . PHP_EOL);
    $operation->pollUntilComplete();

    printf('Created database %s on instance %s' . PHP_EOL,
        $databaseId, $instanceId);
}

O código também define duas tabelas, Singers e Albums, para um aplicativo básico de música. Essas tabelas são usadas em toda esta página. Caso ainda não tenha feito isso, confira o exemplo de esquema.

A próxima etapa é gravar dados no seu banco de dados.

Criar um cliente de banco de dados

Para fazer leituras e gravações, é preciso ter uma instância do Google\Cloud\Spanner\Database.

# Includes the autoloader for libraries installed with composer
require __DIR__ . '/vendor/autoload.php';

# Imports the Google Cloud client library
use Google\Cloud\Spanner\SpannerClient;

# Your Google Cloud Platform project ID
$projectId = 'YOUR_PROJECT_ID';

# Instantiates a client
$spanner = new SpannerClient([
    'projectId' => $projectId
]);

# Your Cloud Spanner instance ID.
$instanceId = 'your-instance-id';

# Get a Cloud Spanner instance by ID.
$instance = $spanner->instance($instanceId);

# Your Cloud Spanner database ID.
$databaseId = 'your-database-id';

# Get a Cloud Spanner database by ID.
$database = $instance->database($databaseId);

# Execute a simple SQL statement.
$results = $database->execute('SELECT "Hello World" as test');

foreach ($results as $row) {
    print($row['test'] . PHP_EOL);
}

É possível pensar em um Database como uma conexão de banco de dados: todas as suas interações com o Cloud Spanner precisam passar por um Database. Normalmente, você cria um Database quando seu aplicativo é iniciado, e depois reutiliza esse Database para ler, gravar e executar transações.

Como cada cliente usa recursos no Cloud Spanner, chame Database::close para limpá-los, incluindo as conexões de rede.

Saiba mais na referência do Database.

Gravar dados com DML

É possível inserir dados usando a linguagem de manipulação de dados (DML, na sigla em inglês) em uma transação de leitura/gravação.

Use o método executeUpdate() para executar uma instrução DML.

use Google\Cloud\Spanner\SpannerClient;
use Google\Cloud\Spanner\Transaction;

/**
 * Inserts sample data into the given database with a DML statement.
 *
 * The database and table must already exist and can be created using
 * `create_database`.
 * Example:
 * ```
 * insert_data($instanceId, $databaseId);
 * ```
 *
 * @param string $instanceId The Spanner instance ID.
 * @param string $databaseId The Spanner database ID.
 */
function write_data_with_dml($instanceId, $databaseId)
{
    $spanner = new SpannerClient();
    $instance = $spanner->instance($instanceId);
    $database = $instance->database($databaseId);

    $database->runTransaction(function (Transaction $t) use ($spanner) {
        $rowCount = $t->executeUpdate(
            "INSERT Singers (SingerId, FirstName, LastName) VALUES "
            . "(12, 'Melissa', 'Garcia'), "
            . "(13, 'Russell', 'Morales'), "
            . "(14, 'Jacqueline', 'Long'), "
            . "(15, 'Dylan', 'Shaw')");
        $t->commit();
        printf('Inserted %d row(s).' . PHP_EOL, $rowCount);
    });
}

Execute a amostra usando o comando write-data-with-dml.

php spanner.php write-data-with-dml test-instance example-db

Você verá:

Inserted 4 row(s).

Gravar dados com mutações

Também é possível inserir dados usando mutações.

Grave dados usando o método Database::insertBatch. insertBatch adiciona novas linhas a uma tabela. Todas as inserções em um único lote são aplicadas atomicamente.

Este código mostra como gravar os dados usando mutações:

use Google\Cloud\Spanner\SpannerClient;

/**
 * Inserts sample data into the given database.
 *
 * The database and table must already exist and can be created using
 * `create_database`.
 * Example:
 * ```
 * insert_data($instanceId, $databaseId);
 * ```
 *
 * @param string $instanceId The Spanner instance ID.
 * @param string $databaseId The Spanner database ID.
 */
function insert_data($instanceId, $databaseId)
{
    $spanner = new SpannerClient();
    $instance = $spanner->instance($instanceId);
    $database = $instance->database($databaseId);

    $operation = $database->transaction(['singleUse' => true])
        ->insertBatch('Singers', [
            ['SingerId' => 1, 'FirstName' => 'Marc', 'LastName' => 'Richards'],
            ['SingerId' => 2, 'FirstName' => 'Catalina', 'LastName' => 'Smith'],
            ['SingerId' => 3, 'FirstName' => 'Alice', 'LastName' => 'Trentor'],
            ['SingerId' => 4, 'FirstName' => 'Lea', 'LastName' => 'Martin'],
            ['SingerId' => 5, 'FirstName' => 'David', 'LastName' => 'Lomond'],
        ])
        ->insertBatch('Albums', [
            ['SingerId' => 1, 'AlbumId' => 1, 'AlbumTitle' => 'Total Junk'],
            ['SingerId' => 1, 'AlbumId' => 2, 'AlbumTitle' => 'Go, Go, Go'],
            ['SingerId' => 2, 'AlbumId' => 1, 'AlbumTitle' => 'Green'],
            ['SingerId' => 2, 'AlbumId' => 2, 'AlbumTitle' => 'Forever Hold Your Peace'],
            ['SingerId' => 2, 'AlbumId' => 3, 'AlbumTitle' => 'Terrified']
        ])
        ->commit();

    print('Inserted data.' . PHP_EOL);
}

Execute a amostra usando o comando insert-data.

php spanner.php insert-data test-instance example-db

Você verá:

Inserted data.

Consultar dados usando SQL

O Cloud Spanner é compatível com uma interface SQL nativa para leitura de dados, acessível na linha de comando com a ferramenta gcloud ou programaticamente com a biblioteca de cliente do Cloud Spanner para PHP.

Na linha de comando

Execute a instrução SQL a seguir para ler os valores de todas as colunas da tabela Albums:

gcloud spanner databases execute-sql example-db --instance=test-instance --sql='SELECT SingerId, AlbumId, AlbumTitle FROM Albums'

O resultado será:

SingerId AlbumId AlbumTitle
1        1       Total Junk
1        2       Go, Go, Go
2        1       Green
2        2       Forever Hold Your Peace
2        3       Terrified

Como usar a biblioteca de cliente do Cloud Spanner para PHP

Além de executar uma instrução SQL na linha de comando, você pode emitir a mesma instrução SQL de maneira programática usando a biblioteca de cliente do Cloud Spanner para PHP.

Use Database::execute() para executar a consulta SQL.

Veja como emitir a consulta e acessar os dados:

use Google\Cloud\Spanner\SpannerClient;

/**
 * Queries sample data from the database using SQL.
 * Example:
 * ```
 * query_data($instanceId, $databaseId);
 * ```
 *
 * @param string $instanceId The Spanner instance ID.
 * @param string $databaseId The Spanner database ID.
 */
function query_data($instanceId, $databaseId)
{
    $spanner = new SpannerClient();
    $instance = $spanner->instance($instanceId);
    $database = $instance->database($databaseId);

    $results = $database->execute(
        'SELECT SingerId, AlbumId, AlbumTitle FROM Albums'
    );

    foreach ($results as $row) {
        printf('SingerId: %s, AlbumId: %s, AlbumTitle: %s' . PHP_EOL,
            $row['SingerId'], $row['AlbumId'], $row['AlbumTitle']);
    }
}

Execute a amostra usando o comando query-data.

php spanner.php query-data test-instance example-db

Você verá o resultado a seguir:

SingerId: 2, AlbumId: 2, AlbumTitle: Forever Hold Your Peace
SingerId: 1, AlbumId: 2, AlbumTitle: Go, Go, Go
SingerId: 2, AlbumId: 1, AlbumTitle: Green
SingerId: 2, AlbumId: 3, AlbumTitle: Terrified
SingerId: 1, AlbumId: 1, AlbumTitle: Total Junk

Seus resultados não serão exibidos necessariamente nessa ordem. Se precisar manter a ordem dos resultados, use uma cláusula ORDER BY, conforme descrito em Práticas recomendadas de SQL.

Consulta usando um parâmetro SQL

É possível usar parâmetros para incluir valores personalizados em instruções SQL. Aqui está um exemplo de como usar @lastName como parâmetro na cláusula WHERE para consultar registros que contêm um valor específico para LastName.

use Google\Cloud\Spanner\SpannerClient;

/**
 * Queries sample data from the database using SQL with a parameter.
 * Example:
 * ```
 * query_data_with_parameter($instanceId, $databaseId);
 * ```
 *
 * @param string $instanceId The Spanner instance ID.
 * @param string $databaseId The Spanner database ID.
 */
function query_data_with_parameter($instanceId, $databaseId)
{
    $spanner = new SpannerClient();
    $instance = $spanner->instance($instanceId);
    $database = $instance->database($databaseId);

    $results = $database->execute(
        'SELECT SingerId, FirstName, LastName FROM Singers ' .
        'WHERE LastName = @lastName',
        ['parameters' => ['lastName' => 'Garcia']]
    );

    foreach ($results as $row) {
        printf('SingerId: %s, FirstName: %s, LastName: %s' . PHP_EOL,
            $row['SingerId'], $row['FirstName'], $row['LastName']);
    }
}

Execute a amostra usando o comando query-data-with-parameter.

php spanner.php query-data-with-parameter test-instance example-db

Você verá o resultado a seguir:

SingerId: 12, FirstName: Melissa, LastName: Garcia

Ler dados usando a API de leitura

Além da interface SQL do Cloud Spanner, o Cloud Spanner também é compatível com uma interface de leitura.

Use Database::read() para ler as linhas do banco de dados. Use um objeto KeySet para definir uma coleção de chaves e intervalos de chaves para leitura.

Veja como ler os dados:

use Google\Cloud\Spanner\SpannerClient;

/**
 * Reads sample data from the database.
 * Example:
 * ```
 * read_data($instanceId, $databaseId);
 * ```
 *
 * @param string $instanceId The Spanner instance ID.
 * @param string $databaseId The Spanner database ID.
 */
function read_data($instanceId, $databaseId)
{
    $spanner = new SpannerClient();
    $instance = $spanner->instance($instanceId);
    $database = $instance->database($databaseId);

    $keySet = $spanner->keySet(['all' => true]);
    $results = $database->read(
        'Albums',
        $keySet,
        ['SingerId', 'AlbumId', 'AlbumTitle']
    );

    foreach ($results->rows() as $row) {
        printf('SingerId: %s, AlbumId: %s, AlbumTitle: %s' . PHP_EOL,
            $row['SingerId'], $row['AlbumId'], $row['AlbumTitle']);
    }
}

Execute a amostra usando o comando read-data.

php spanner.php read-data test-instance example-db

Você verá uma saída similar a:

SingerId: 1, AlbumId: 1, AlbumTitle: Go, Go, Go
SingerId: 1, AlbumId: 2, AlbumTitle: Total Junk
SingerId: 2, AlbumId: 1, AlbumTitle: Green
SingerId: 2, AlbumId: 2, AlbumTitle: Forever Hold your Peace
SingerId: 2, AlbumId: 3, AlbumTitle: Terrified

Atualizar o esquema do banco de dados

Imagine que você precise adicionar uma nova coluna chamada MarketingBudget à tabela Albums. Para isso, é necessário atualizar seu esquema de banco de dados. O Cloud Spanner é compatível com atualizações de esquema em um banco de dados enquanto esse banco continua a disponibilizar o tráfego. Para fazer atualizações no esquema, não é necessário desconectar o banco de dados, nem bloquear tabelas ou colunas inteiras. É possível continuar gravando dados no banco de dados durante a atualização do esquema. Leia mais sobre as atualizações de esquemas compatíveis e o desempenho das alterações de esquemas em Atualizações de esquema.

Adicionar uma coluna

Para adicionar uma coluna na linha de comando, use a ferramenta gcloud ou, de maneira programática, use a biblioteca de cliente do Cloud Spanner para PHP.

Na linha de comando

Use o comando ALTER TABLE a seguir para adicionar a nova coluna à tabela:

gcloud spanner databases ddl update example-db --instance=test-instance \
  --ddl='ALTER TABLE Albums ADD COLUMN MarketingBudget INT64'

Você verá:

Schema updating...done.

Como usar a biblioteca de cliente do Cloud Spanner para PHP

Use Database::updateDdl para modificar o esquema:

use Google\Cloud\Spanner\SpannerClient;

/**
 * Adds a new column to the Albums table in the example database.
 * Example:
 * ```
 * add_column($instanceId, $databaseId);
 * ```
 *
 * @param string $instanceId The Spanner instance ID.
 * @param string $databaseId The Spanner database ID.
 */
function add_column($instanceId, $databaseId)
{
    $spanner = new SpannerClient();
    $instance = $spanner->instance($instanceId);
    $database = $instance->database($databaseId);

    $operation = $database->updateDdl(
        'ALTER TABLE Albums ADD COLUMN MarketingBudget INT64'
    );

    print('Waiting for operation to complete...' . PHP_EOL);
    $operation->pollUntilComplete();

    printf('Added the MarketingBudget column.' . PHP_EOL);
}

Execute a amostra usando o comando add-column.

php spanner.php add-column test-instance example-db

Você verá:

Added the MarketingBudget column.

Gravar dados na nova coluna

O código a seguir grava dados na nova coluna. Ele define MarketingBudget para 100000 na linha indexada por Albums(1, 1) e 500000 na linha indexada por Albums(2, 2).

use Google\Cloud\Spanner\SpannerClient;

/**
 * Updates sample data in the database.
 *
 * This updates the `MarketingBudget` column which must be created before
 * running this sample. You can add the column by running the `add_column`
 * sample or by running this DDL statement against your database:
 *
 *     ALTER TABLE Albums ADD COLUMN MarketingBudget INT64
 *
 * Example:
 * ```
 * update_data($instanceId, $databaseId);
 * ```
 *
 * @param string $instanceId The Spanner instance ID.
 * @param string $databaseId The Spanner database ID.
 */
function update_data($instanceId, $databaseId)
{
    $spanner = new SpannerClient();
    $instance = $spanner->instance($instanceId);
    $database = $instance->database($databaseId);

    $operation = $database->transaction(['singleUse' => true])
        ->updateBatch('Albums', [
            ['SingerId' => 1, 'AlbumId' => 1, 'MarketingBudget' => 100000],
            ['SingerId' => 2, 'AlbumId' => 2, 'MarketingBudget' => 500000],
        ])
        ->commit();

    print('Updated data.' . PHP_EOL);
}

Execute a amostra usando o comando update-data.

php spanner.php update-data test-instance example-db

Você verá:

Updated data.

Também é possível executar uma consulta SQL ou uma chamada de leitura para coletar os valores que você acabou de gravar.

Veja a seguir o código para executar a consulta:

use Google\Cloud\Spanner\SpannerClient;

/**
 * Queries sample data from the database using SQL.
 * This sample uses the `MarketingBudget` column. You can add the column
 * by running the `add_column` sample or by running this DDL statement against
 * your database:
 *
 *      ALTER TABLE Albums ADD COLUMN MarketingBudget INT64
 *
 * Example:
 * ```
 * query_data_with_new_column($instanceId, $databaseId);
 * ```
 *
 * @param string $instanceId The Spanner instance ID.
 * @param string $databaseId The Spanner database ID.
 */
function query_data_with_new_column($instanceId, $databaseId)
{
    $spanner = new SpannerClient();
    $instance = $spanner->instance($instanceId);
    $database = $instance->database($databaseId);

    $results = $database->execute(
        'SELECT SingerId, AlbumId, MarketingBudget FROM Albums'
    );

    foreach ($results as $row) {
        printf('SingerId: %s, AlbumId: %s, MarketingBudget: %d' . PHP_EOL,
            $row['SingerId'], $row['AlbumId'], $row['MarketingBudget']);
    }
}

Para executar essa consulta, execute a amostra usando o argumento query-data-with-new-column.

php spanner.php query-data-with-new-column test-instance example-db

Você verá:

SingerId: 1, AlbumId: 1, MarketingBudget: 100000
SingerId: 1, AlbumId: 2, MarketingBudget: 0
SingerId: 2, AlbumId: 1, MarketingBudget: 0
SingerId: 2, AlbumId: 2, MarketingBudget: 500000
SingerId: 2, AlbumId: 3, MarketingBudget: 0

Atualizar dados

É possível atualizar dados usando DML em uma transação de leitura/gravação.

Use o método executeUpdate() para executar uma instrução DML.

use Google\Cloud\Spanner\SpannerClient;
use Google\Cloud\Spanner\Transaction;

/**
 * Performs a read-write transaction to update two sample records in the
 * database.
 *
 * This will transfer 200,000 from the `MarketingBudget` field for the second
 * Album to the first Album. If the `MarketingBudget` for the second Album is
 * too low, it will raise an exception.
 *
 * Before running this sample, you will need to run the `update_data` sample
 * to populate the fields.
 * Example:
 * ```
 * write_data_with_dml_transaction($instanceId, $databaseId);
 * ```
 *
 * @param string $instanceId The Spanner instance ID.
 * @param string $databaseId The Spanner database ID.
 */
function write_data_with_dml_transaction($instanceId, $databaseId)
{
    $spanner = new SpannerClient();
    $instance = $spanner->instance($instanceId);
    $database = $instance->database($databaseId);

    $database->runTransaction(function (Transaction $t) use ($spanner) {
        // Transfer marketing budget from one album to another. We do it in a transaction to
        // ensure that the transfer is atomic.
        $transferAmount = 200000;

        $results = $t->execute(
            "SELECT MarketingBudget from Albums WHERE SingerId = 2 and AlbumId = 2"
        );
        $resultsRow = $results->rows()->current();
        $album2budget = $resultsRow['MarketingBudget'];

        // Transaction will only be committed if this condition still holds at the time of
        // commit. Otherwise it will be aborted and the callable will be rerun by the
        // client library.
        if ($album2budget >= $transferAmount) {
            $results = $t->execute(
                "SELECT MarketingBudget from Albums WHERE SingerId = 1 and AlbumId = 1"
            );
            $resultsRow = $results->rows()->current();
            $album1budget = $resultsRow['MarketingBudget'];

            $album2budget -= $transferAmount;
            $album1budget += $transferAmount;

            // Update the albums
            $t->executeUpdate(
                "UPDATE Albums "
                . "SET MarketingBudget = @AlbumBudget "
                . "WHERE SingerId = 1 and AlbumId = 1",
                [
                    'parameters' => [
                        'AlbumBudget' => $album1budget
                    ]
                ]
            );
            $t->executeUpdate(
                "UPDATE Albums "
                . "SET MarketingBudget = @AlbumBudget "
                . "WHERE SingerId = 2 and AlbumId = 2",
                [
                    'parameters' => [
                        'AlbumBudget' => $album2budget
                    ]
                ]
            );

            $t->commit();

            print('Transaction complete.' . PHP_EOL);
        }
    });
}

Execute a amostra usando o comando write-data-with-dml-transaction.

php spanner.php write-data-with-dml-transaction test-instance example-db

Você verá:

Transaction complete.

Usar um índice secundário

Suponha que você queira buscar todas as linhas de Albums que tenham valores de AlbumTitle em um determinado intervalo. É possível ler todos os valores da coluna AlbumTitle usando uma instrução SQL ou uma chamada de leitura e, em seguida, descartar as linhas que não atendam aos critérios. Porém, fazer essa varredura em uma tabela completa é um processo caro, especialmente em tabelas com muitas linhas. Em vez disso, acelere a recuperação de linhas ao pesquisar por colunas de chaves não primárias por meio da criação de um índice secundário na tabela.

Adicionar um índice secundário a uma tabela requer uma atualização de esquema. Como outras atualizações de esquema, o Cloud Spanner é compatível com a adição de um índice enquanto o banco de dados continua a disponibilizar o tráfego. O Cloud Spanner preenche o índice com dados (processo conhecido como "preenchimento") em segundo plano. Pode levar alguns minutos para que os preenchimentos sejam concluídos, mas não é necessário deixar o banco de dados off-line ou evitar a gravação em determinadas tabelas ou colunas durante esse processo. Para mais detalhes, consulte o preenchimento de índices.

Adicionar um índice secundário

Para adicionar um índice na linha de comando, use a ferramenta gcloud ou, de maneira programática, a biblioteca de cliente do Cloud Spanner para PHP.

Na linha de comando

Use o comando CREATE INDEX a seguir para adicionar um índice ao banco de dados:

gcloud spanner databases ddl update example-db --instance=test-instance \
  --ddl='CREATE INDEX AlbumsByAlbumTitle ON Albums(AlbumTitle)'

Você verá:

Schema updating...done.

Como usar a biblioteca de cliente do Cloud Spanner para PHP

Use Database::updateDdl para adicionar um índice:

use Google\Cloud\Spanner\SpannerClient;

/**
 * Adds a simple index to the example database.
 * Example:
 * ```
 * create_index($instanceId, $databaseId);
 * ```
 *
 * @param string $instanceId The Spanner instance ID.
 * @param string $databaseId The Spanner database ID.
 */
function create_index($instanceId, $databaseId)
{
    $spanner = new SpannerClient();
    $instance = $spanner->instance($instanceId);
    $database = $instance->database($databaseId);

    $operation = $database->updateDdl(
        'CREATE INDEX AlbumsByAlbumTitle ON Albums(AlbumTitle)'
    );

    print('Waiting for operation to complete...' . PHP_EOL);
    $operation->pollUntilComplete();

    printf('Added the AlbumsByAlbumTitle index.' . PHP_EOL);
}

Execute a amostra usando o comando create-index.

php spanner.php create-index test-instance example-db

A adição do índice pode levar alguns minutos. Depois da adição, você verá:

Added the AlbumsByAlbumTitle index.

Consultar usando o índice

Faça uma consulta usando o novo índice na linha de comando ou na biblioteca de cliente.

Na linha de comando

Execute uma instrução SQL usando a ferramenta de linha de comando gcloud para buscar AlbumId, AlbumTitle e MarketingBudget em Albums usando o índice AlbumsByAlbumTitle para o intervalo de AlbumsTitle em ["Aardvark", "Goo").

gcloud spanner databases execute-sql example-db --instance=test-instance --sql='SELECT AlbumId, AlbumTitle, MarketingBudget FROM Albums@{FORCE_INDEX=AlbumsByAlbumTitle} WHERE AlbumTitle >= "Aardvark" AND AlbumTitle < "Goo"'

O resultado será:

AlbumId  AlbumTitle               MarketingBudget
2        Go, Go, Go
2        Forever Hold Your Peace  300000

Como usar a biblioteca de cliente do Cloud Spanner para PHP

O código para usar o índice de maneira programática é semelhante ao código de consulta usado anteriormente.

use Google\Cloud\Spanner\SpannerClient;

/**
 * Queries sample data from the database using SQL and an index.
 *
 * The index must exist before running this sample. You can add the index
 * by running the `add_index` sample or by running this DDL statement against
 * your database:
 *
 *     CREATE INDEX AlbumsByAlbumTitle ON Albums(AlbumTitle)
 *
 * Example:
 * ```
 * query_data_with_index($instanceId, $databaseId);
 * ```
 *
 * @param string $instanceId The Spanner instance ID.
 * @param string $databaseId The Spanner database ID.
 * @param string $startTitle The start of the title index.
 * @param string $endTitle   The end of the title index.
 */
function query_data_with_index($instanceId, $databaseId, $startTitle, $endTitle)
{
    $spanner = new SpannerClient();
    $instance = $spanner->instance($instanceId);
    $database = $instance->database($databaseId);

    $parameters = [
        'startTitle' => $startTitle,
        'endTitle' => $endTitle
    ];

    $results = $database->execute(
        'SELECT AlbumId, AlbumTitle, MarketingBudget ' .
        'FROM Albums@{FORCE_INDEX=AlbumsByAlbumTitle} ' .
        'WHERE AlbumTitle >= @startTitle AND AlbumTitle < @endTitle',
        ['parameters' => $parameters]
    );

    foreach ($results as $row) {
        printf('AlbumId: %s, AlbumTitle: %s, MarketingBudget: %d' . PHP_EOL,
            $row['AlbumId'], $row['AlbumTitle'], $row['MarketingBudget']);
    }
}

Execute a amostra usando o comando query-data-with-index.

php spanner.php query-data-with-index test-instance example-db

Você verá uma saída similar a:

AlbumId: 2, AlbumTitle: Go, Go, Go, MarketingBudget: 0
AlbumId: 2, AlbumTitle: Forever Hold your Peace, MarketingBudget: 300000

Para mais detalhes, consulte estas referências:

Ler usando o índice

Para fazer uma leitura usando o índice, use o método Database::read.

use Google\Cloud\Spanner\SpannerClient;

/**
 * Reads sample data from the database using an index.
 *
 * The index must exist before running this sample. You can add the index
 * by running the `add_index` sample or by running this DDL statement against
 * your database:
 *
 *     CREATE INDEX AlbumsByAlbumTitle ON Albums(AlbumTitle)
 *
 * Example:
 * ```
 * read_data_with_index($instanceId, $databaseId);
 * ```
 *
 * @param string $instanceId The Spanner instance ID.
 * @param string $databaseId The Spanner database ID.
 */
function read_data_with_index($instanceId, $databaseId)
{
    $spanner = new SpannerClient();
    $instance = $spanner->instance($instanceId);
    $database = $instance->database($databaseId);

    $keySet = $spanner->keySet(['all' => true]);
    $results = $database->read(
        'Albums',
        $keySet,
        ['AlbumId', 'AlbumTitle'],
        ['index' => 'AlbumsByAlbumTitle']
    );

    foreach ($results->rows() as $row) {
        printf('AlbumId: %s, AlbumTitle: %s' . PHP_EOL,
            $row['AlbumId'], $row['AlbumTitle']);
    }
}

Execute a amostra usando o comando read-data-with-index.

php spanner.php read-data-with-index test-instance example-db

Você verá:

AlbumId: 2, AlbumTitle: Forever Hold your Peace
AlbumId: 1, AlbumTitle: Go, Go, Go
AlbumId: 1, AlbumTitle: Green
AlbumId: 3, AlbumTitle: Terrified
AlbumId: 2, AlbumTitle: Total Junk

Adicionar um índice com uma cláusula STORING

Talvez você tenha percebido que o exemplo de leitura acima não inclui a leitura da coluna MarketingBudget. Isso ocorre porque a interface de leitura do Cloud Spanner não é compatível com a capacidade de fazer a junção de um índice a uma tabela de dados para pesquisar valores que não estão armazenados no índice.

Crie uma definição alternativa de AlbumsByAlbumTitle que armazene uma cópia de MarketingBudget no índice.

Na linha de comando

gcloud spanner databases ddl update example-db --instance=test-instance \
  --ddl='CREATE INDEX AlbumsByAlbumTitle2 ON Albums(AlbumTitle) STORING (MarketingBudget)'

A adição do índice pode levar alguns minutos. Depois da adição, você verá:

Schema updating...done.

Como usar a biblioteca de cliente do Cloud Spanner para PHP

Use Database::updateDdl para adicionar um índice por meio de uma cláusula STORING:

use Google\Cloud\Spanner\SpannerClient;

/**
 * Adds an storing index to the example database.
 *
 * This sample uses the `MarketingBudget` column. You can add the column
 * by running the `add_column` sample or by running this DDL statement against
 * your database:
 *
 *     ALTER TABLE Albums ADD COLUMN MarketingBudget INT64
 *
 * Example:
 * ```
 * create_storing_index($instanceId, $databaseId);
 * ```
 *
 * @param string $instanceId The Spanner instance ID.
 * @param string $databaseId The Spanner database ID.
 */
function create_storing_index($instanceId, $databaseId)
{
    $spanner = new SpannerClient();
    $instance = $spanner->instance($instanceId);
    $database = $instance->database($databaseId);

    $operation = $database->updateDdl(
        'CREATE INDEX AlbumsByAlbumTitle2 ON Albums(AlbumTitle) ' .
        'STORING (MarketingBudget)'
    );

    print('Waiting for operation to complete...' . PHP_EOL);
    $operation->pollUntilComplete();

    printf('Added the AlbumsByAlbumTitle2 index.' . PHP_EOL);
}

Execute a amostra usando o comando create-storing-index.

php spanner.php create-storing-index test-instance example-db

Você verá:

Added the AlbumsByAlbumTitle2 index.

Agora você pode executar uma leitura que busque todas as colunas AlbumId, AlbumTitle e MarketingBudget do índice AlbumsByAlbumTitle2:

use Google\Cloud\Spanner\SpannerClient;

/**
 * Reads sample data from the database using an index with a storing
 * clause.
 *
 * The index must exist before running this sample. You can add the index
 * by running the `add_storing_index` sample or by running this DDL statement
 * against your database:
 *
 *     CREATE INDEX AlbumsByAlbumTitle2 ON Albums(AlbumTitle)
 *     STORING (MarketingBudget)
 *
 * Example:
 * ```
 * read_data_with_storing_index($instanceId, $databaseId);
 * ```
 *
 * @param string $instanceId The Spanner instance ID.
 * @param string $databaseId The Spanner database ID.
 */
function read_data_with_storing_index($instanceId, $databaseId)
{
    $spanner = new SpannerClient();
    $instance = $spanner->instance($instanceId);
    $database = $instance->database($databaseId);

    $keySet = $spanner->keySet(['all' => true]);
    $results = $database->read(
        'Albums',
        $keySet,
        ['AlbumId', 'AlbumTitle', 'MarketingBudget'],
        ['index' => 'AlbumsByAlbumTitle2']
    );

    foreach ($results->rows() as $row) {
        printf('AlbumId: %s, AlbumTitle: %s, MarketingBudget: %d' . PHP_EOL,
            $row['AlbumId'], $row['AlbumTitle'], $row['MarketingBudget']);
    }
}

Execute a amostra usando o comando read-data-with-storing-index.

php spanner.php read-data-with-storing-index test-instance example-db

Você verá uma saída similar a:

AlbumId: 2, AlbumTitle: Forever Hold your Peace, MarketingBudget: 300000
AlbumId: 1, AlbumTitle: Go, Go, Go, MarketingBudget: 300000
AlbumId: 1, AlbumTitle: Green, MarketingBudget: 0
AlbumId: 3, AlbumTitle: Terrified, MarketingBudget: 0
AlbumId: 2, AlbumTitle: Total Junk, MarketingBudget: 0

Recuperar dados usando transações somente leitura

Suponha que você queira executar mais de uma leitura no mesmo carimbo de data/hora. As transações somente leitura estão de acordo com um prefixo consistente do histórico de confirmações da transação. Portanto o aplicativo sempre recebe dados consistentes. Use um objeto Snapshot para executar transações somente leitura. Use o método Database::snapshot para conseguir um objeto Snapshot.

Veja a seguir como executar uma consulta e fazer uma leitura na mesma transação somente leitura.

use Google\Cloud\Spanner\SpannerClient;

/**
 * Reads data inside of a read-only transaction.
 *
 * Within the read-only transaction, or "snapshot", the application sees
 * consistent view of the database at a particular timestamp.
 * Example:
 * ```
 * read_only_transaction($instanceId, $databaseId);
 * ```
 *
 * @param string $instanceId The Spanner instance ID.
 * @param string $databaseId The Spanner database ID.
 */
function read_only_transaction($instanceId, $databaseId)
{
    $spanner = new SpannerClient();
    $instance = $spanner->instance($instanceId);
    $database = $instance->database($databaseId);

    $snapshot = $database->snapshot();
    $results = $snapshot->execute(
        'SELECT SingerId, AlbumId, AlbumTitle FROM Albums'
    );
    print('Results from the first read:' . PHP_EOL);
    foreach ($results as $row) {
        printf('SingerId: %s, AlbumId: %s, AlbumTitle: %s' . PHP_EOL,
            $row['SingerId'], $row['AlbumId'], $row['AlbumTitle']);
    }

    // Perform another read using the `read` method. Even if the data
    // is updated in-between the reads, the snapshot ensures that both
    // return the same data.
    $keySet = $spanner->keySet(['all' => true]);
    $results = $database->read(
        'Albums',
        $keySet,
        ['SingerId', 'AlbumId', 'AlbumTitle']
    );

    print('Results from the second read:' . PHP_EOL);
    foreach ($results->rows() as $row) {
        printf('SingerId: %s, AlbumId: %s, AlbumTitle: %s' . PHP_EOL,
            $row['SingerId'], $row['AlbumId'], $row['AlbumTitle']);
    }
}

Execute a amostra usando o comando read-only-transaction.

php spanner.php read-only-transaction test-instance example-db

Você verá uma saída similar a:

Results from first read:
SingerId: 2, AlbumId: 2, AlbumTitle: Forever Hold Your Peace
SingerId: 1, AlbumId: 2, AlbumTitle: Go, Go, Go
SingerId: 2, AlbumId: 1, AlbumTitle: Green
SingerId: 2, AlbumId: 3, AlbumTitle: Terrified
SingerId: 1, AlbumId: 1, AlbumTitle: Total Junk
Results from second read:
SingerId: 1, AlbumId: 1, AlbumTitle: Total Junk
SingerId: 1, AlbumId: 2, AlbumTitle: Go, Go, Go
SingerId: 2, AlbumId: 1, AlbumTitle: Green
SingerId: 2, AlbumId: 2, AlbumTitle: Forever Hold Your Peace
SingerId: 2, AlbumId: 3, AlbumTitle: Terrified

Limpeza

Para evitar cobranças adicionais na sua conta do Google Cloud Platform pelos recursos utilizados neste tutorial, descarte o banco de dados e exclua a instância que você criou.

Excluir o banco de dados

Se você excluir uma instância, todos os bancos de dados nela serão excluídos automaticamente. Nesta etapa, mostramos como excluir um banco de dados sem remover a instância. Ainda pode haver cobrança em relação à instância.

Na linha de comando

gcloud spanner databases delete example-db --instance=test-instance

No Console do GCP

  1. Acesse a página Instâncias do Cloud Spanner no Console do Google Cloud Platform.
    Ir para a página "Instâncias" do Cloud Spanner
  2. Clique na instância.
  3. Clique no banco de dados que você quer excluir.
  4. Na página Detalhes do banco de dados, clique em Excluir.
  5. Confirme se quer excluir o banco de dados e clique em Excluir.

Excluir a instância

A exclusão de uma instância descarta automaticamente todos os bancos de dados criados nela.

Na linha de comando

gcloud spanner instances delete test-instance

No Console do GCP

  1. Acesse a página Instâncias do Cloud Spanner no Console do Google Cloud Platform.
    Ir para a página "Instâncias" do Cloud Spanner
  2. Clique na sua instância.
  3. Clique em Excluir.
  4. Confirme se quer excluir a instância e clique em Excluir.

A seguir

Esta página foi útil? Conte sua opinião sobre:

Enviar comentários sobre…

Documentação do Cloud Spanner