shailesh-matariya/laravel-spanner

Google Cloud Spanner 的 Laravel 数据库驱动程序

v3.5.0 2020-07-22 01:22 UTC

This package is auto-updated.

Last update: 2024-09-06 15:49:54 UTC


README

Google Cloud Spanner 的 Laravel 数据库驱动程序

License Latest Stable Version Minimum PHP Version

CI Status on master

要求

安装

将 JSON 凭证文件路径放入环境变量中:GOOGLE_APPLICATION_CREDENTIALS

export GOOGLE_APPLICATION_CREDENTIALS=/path/to/key.json

通过 composer 安装

composer require colopl/laravel-spanner

将连接配置添加到 config/database.php

[
    'connections' => [
        'spanner' => [
            'driver' => 'spanner',
            'instance' => '<Cloud Spanner instanceId here>',
            'database' => '<Cloud Spanner database name here>',
        ]
    ]
];

这就完成了。你可以像通常一样使用数据库连接。

$conn = DB::connection('spanner');
$conn->...

附加配置

你可以按照以下方式传递 SpannerClient 配置和 CacheSessionPool 选项。更多信息请参阅 Google 客户端库文档

[
    'connections' => [
        'spanner' => [
            'driver' => 'spanner',
            'instance' => '<Cloud Spanner instanceId here>',
            'database' => '<Cloud Spanner database name here>',
            
            // Spanner Client configurations
            'client' => [
                'projectId' => 'xxx',
                ...
            ],
            
            // CacheSessionPool options
            'session_pool' => [
                'minSessions' => 10,
                'maxSessions' => 500,
            ],
        ]
    ]
];

不支持的功能

  • STRUCT 数据类型
  • 显式只读事务(快照)

限制

迁移

大多数 SchemaBuilder 函数(例如,Schema 门面和 Blueprint)都可以使用。但是,由于 Google Cloud Spanner 中不存在 AUTO_INCREMENT,因此 artisan migrate 命令无法使用。

Eloquent

大多数 Eloquent 函数都可以使用。但是,某些功能不可用。例如,belongsToMany 关系不可用。

如果你使用交错键,你必须在 interleaveKeys 属性中定义它们,否则你将无法保存。有关更详细的说明,请参阅 Colopl\Spanner\Tests\Eloquent\ModelTest

附加信息

事务

Google Cloud Spanner 有时需要事务重试(例如,UNAVAILABLEABORTED),即使逻辑是正确的。因此,请不要手动管理事务。

你应该始终使用 transaction 方法,该方法内部处理重试请求。

// BAD: Do not use transactions manually!!
try {
    DB::beginTransaction();
    ...
    DB::commit();
} catch (\Throwable $ex) {
    DB::rollBack();
}

// GOOD: You should always use transaction method
DB::transaction(function() {
    ...
});

Google Cloud Spanner 为所有数据操作创建事务,即使你没有显式创建事务。

特别是,在 SELECT 语句中,事务类型取决于它是显式还是隐式。

// implicit transaction (Read-only transaction)
$conn->select('SELECT ...');

// explicit transaction (Read-write transaction)
$conn->transaction(function() {
    $conn->select('SELECT ...');
});

// implicit transaction (Read-write transaction)
$conn->insert('INSERT ...');

// explicit transaction (Read-write transaction)
$conn->transaction(function() {
    $conn->insert('INSERT ...');
});

有关更多信息,请参阅 关于事务的 Cloud Spanner 文档

陈旧读取

你可以按照以下方式使用 陈旧读取(时间戳界限)

// There are four types of timestamp bounds: ExactStaleness, MaxStaleness, MinReadTimestamp and ReadTimestamp.
$timestampBound = new ExactStaleness(10);

// by Connection
$connection->selectWithTimestampBound('SELECT ...', $bindings, $timestampBound);

// by Query Builder
$queryBuilder
    ->withStaleness($timestampBound)
    ->get();

陈旧读取始终作为具有 singleUse 选项的只读事务运行。因此,你不能作为读写事务运行。

数据类型

Google Cloud Spanner 的某些数据类型没有与 PHP 内置类型对应的类型。你可以使用以下类通过 Google Cloud PHP 客户端

  • DATE: Google\Cloud\Spanner\Date
  • BYTES: Google\Cloud\Spanner\Bytes
  • TIMESTAMP: Google\Cloud\Spanner\Timestamp

Google\Cloud\Spanner\Timestamp 是具有 UTC 时区和纳秒的 DateTime 表示。在 laravel-spanner QueryBuilder 中,将获取的行中的 Timestamp 转换为具有 PHP 默认时区的 Carbon

注意,如果你在没有 QueryBuilder 的情况下执行查询,它将不会转换为 Carbon。

分区 DML

你可以按照以下方式运行分区 DML。

// by Connection
$connection->runPartitionedDml('UPDATE ...');


// by Query Builder
$queryBuilder->partitionedUpdate($values);
$queryBuilder->partitionedDelete($values);

然而,分区DML有一些限制。有关更多信息,请参阅Cloud Spanner分区DML文档

交错

您可以根据以下方式定义交错表

$schemaBuilder->create('user_items', function (Blueprint $table) {
    $table->uuid('user_id');
    $table->uuid('id');
    $table->uuid('item_id');
    $table->integer('count');
    $table->timestamps();

    $table->primary(['user_id', 'id']);
    
    // interleaved table
    $table->interleave('users')->onDelete('cascade');
    
    // interleaved index
    $table->index(['userId', 'created_at'])->interleave('users');
});

变异

您可以使用变异来插入、更新和删除数据,从而通过变异修改数据而不是使用DML以提高性能。

$queryBuilder->insertUsingMutation($values);
$queryBuilder->updateUsingMutation($values);
$queryBuilder->deleteUsingMutation($values);

请注意,变异API与DML的工作方式不同。事务内的所有变异调用都将排队,并在提交时作为批处理发送。这意味着如果您通过上述函数进行任何修改,然后在提交之前尝试选择相同的记录,返回的结果将不包括您在事务中进行的任何修改。

SessionPool和AuthCache

为了提高每个请求的第一个连接的性能,我们使用了AuthCacheCacheSessionPool

默认情况下,laravel-spanner使用文件系统缓存适配器作为缓存池。如果您想使用自己的缓存池,您可以扩展ServiceProvider并将其注入到Colopl\Spanner\Connection的构造函数中。

Laravel Tinker

您可以使用Laravel Tinker,例如使用php artisan tinker命令。但是,当访问Cloud Spanner时,您的会话可能会挂起。这是已知的问题,当PHP派生进程时发生gRPC问题。解决方法是向php.ini中添加以下行。

grpc.enable_fork_support=1

开发

测试

您可以通过以下命令在docker上运行测试。请注意,必须设置一些环境变量。为了设置这些变量,将.env.sample重命名为.env并编辑定义变量的值。

make test

许可证

Apache 2.0 - 有关更多信息,请参阅LICENSE