单店金属/singlestoredb-laravel

SingleStoreDB数据库驱动程序,适用于Laravel。

v1.5.6 2024-07-02 10:57 UTC

README

Latest Stable Version Total Downloads License PHP Version Require Github Actions status image

此仓库包含官方SingleStoreDB驱动程序,用于Laravel。此驱动程序将Laravel官方MySQL支持包装起来,以便更好地与SingleStoreDB协同工作。具体来说,此驱动程序相较于Laravel原生MySQL支持具有以下优点:

  • 通过Eloquent扩展,允许通过Eloquent API指定特定的SingleStoreDB功能。有关支持的功能,请参阅迁移
  • 针对SingleStoreDB及其PHP和Laravel版本矩阵进行集成测试。
  • JSON列支持
  • 查询生成中的其他兼容性修复

目录

安装

您可以通过composer安装此包

composer require singlestoredb/singlestoredb-laravel

此包需要已安装pdo_mysql。如果您不确定,请在运行php -i时检查是否列出了pdo_mysql

使用

要启用驱动程序,请转到您的config/database.php文件,并在connections中为SingleStore创建一个新条目,并将您的default更新为指向该新连接。

[
    'default' => env('DB_CONNECTION', 'singlestore'),

    'connections' => [
        'singlestore' => [
            'driver' => 'singlestore',
            'url' => env('DATABASE_URL'),
            'host' => env('DB_HOST'),
            'port' => env('DB_PORT'),
            'database' => env('DB_DATABASE'),
            'username' => env('DB_USERNAME'),
            'password' => env('DB_PASSWORD'),
            'unix_socket' => env('DB_SOCKET'),
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',
            'prefix' => '',
            'prefix_indexes' => true,
            'strict' => true,
            'engine' => null,
            'options' => extension_loaded('pdo_mysql') ? array_filter([
                PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
                PDO::ATTR_EMULATE_PREPARES => true,
            ]) : [],
        ],
    ]
]

SingleStore驱动程序是MySQL驱动程序的扩展,因此您也可以直接将drivermysql更改为singlestore

如果您想在SingleStore中存储失败的作业,请确保您也在config/queue.php文件中将它设置为数据库。在这种情况下,您可能更愿意在环境变量中将DB_CONNECTION='singlestore'设置为。

'failed' => [
    'driver' => env('QUEUE_FAILED_DRIVER', 'database-uuids'),
    'database' => env('DB_CONNECTION', 'singlestore'),
    'table' => 'failed_jobs',
],

连接到SingleStore托管服务的问题

如果您遇到连接到SingleStore托管服务的问题,可能是因为您的环境无法验证用于保护连接的SSL证书。您可以通过下载并手动指定SingleStore证书文件来修复此问题。

  • 在此处下载文件
  • 在Laravel SingleStore连接配置中,将变量PDO::MYSQL_ATTR_SSL_CA指向singlestore_bundle.pem
'options' => extension_loaded('pdo_mysql') ? array_filter([
    PDO::MYSQL_ATTR_SSL_CA => 'path/to/singlestore_bundle.pem',
    PDO::ATTR_EMULATE_PREPARES => true,
]) : [],

持久连接(性能优化)

通常,我们建议在连接到SingleStoreDB时启用PDO::ATTR_PERSISTENT。这是因为与运行许多事务性查询相比,打开新的SingleStoreDB连接非常昂贵。通过使用PDO::ATTR_PERSISTENT,您可以显著提高事务性工作负载的性能。

使用持久连接的唯一缺点是需要确保事务被正确清理,并且在更改会话变量或上下文数据库时要小心。您可以在php.net的官方文档中了解更多有关此功能的信息

此外,请注意,SingleStoreDB 在默认配置下可以处理大量的空闲连接而不会影响性能。默认情况下,每个聚合器大约可以处理 100,000 个空闲连接,但根据您的服务器能力,这个数值可以设置得更高。

要启用此功能,只需更新您的选项以包括 PDO::ATTR_PERSISTENT => true

'options' => extension_loaded('pdo_mysql') ? array_filter([
    PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
    PDO::ATTR_EMULATE_PREPARES => true,
    PDO::ATTR_PERSISTENT => true,
]) : [],

PHP 8.1之前的版本

在 PHP 8.1 之前的版本中,标志 PDO::ATTR_EMULATE_PREPARES 会导致一个 bug,即 MySQL(和 SingleStoreDB)返回的所有属性都被作为字符串返回。

例如,一个名为 user_id 且类型为 int(10) 的列,如果行值为 5423,在 PHP 中我们得到的结果将是字符串 "5423"

这是一个历史性和已知的 bug

解决此问题的最佳方法是升级到 PHP 8.1 或更高版本。如果不可行,Eloquent 的属性转换是次优解决方案。

迁移

此驱动程序提供了许多针对创建或修改表的单店特定方法。以下列出了一些。有关更多信息,请参阅 SingleStore 的创建表文档。

通用存储表(列存储)

默认情况下,由该驱动程序创建的表将使用 SingleStoreDB 通用存储。通用存储利用列和行数据结构自动优化事务和分析工作负载的存储。通常,除非您分析了工作负载并确定另一种表类型更好,否则您应该使用此表类型。

要创建表,您可以使用 Schema::create

Schema::create('table', function (Blueprint $table) {
    // ... column definitions, indexes, table options
});

行存储表

要创建行存储表,请使用 rowstore 方法。行存储表针对低延迟事务工作负载和高并发进行了优化,但以内存为代价。通常,我们建议使用通用存储(见上文)并在使用行存储表之前对工作负载进行基准测试。

Schema::create('table', function (Blueprint $table) {
    $table->rowstore();

    // ...
});

参考表

要创建引用表,您可以使用 reference 方法。引用表被完全复制到集群中的每个节点。这意味着如果您在引用表中存储 1000 行,这 1000 行将被多次复制。因此,您应该在引用表中仅存储少量数据,并且只有在您需要通过与其他表的非同位数据连接引用这些数据时才这样做。引用表的插入和更新操作也会因为高复制开销而运行得更慢。

Schema::create('table', function (Blueprint $table) {
    $table->reference();

    // ...
});

全局临时表

要创建全局临时表,您可以在表上使用 global 方法。

Schema::create('table', function (Blueprint $table) {
    $table->rowstore();
    $table->temporary();
    $table->global();

    // ...
});

您还可以使用以下两种方法中的任何一种

// Fluent
$table->rowstore()->temporary()->global();

// As an argument to `temporary`.
$table->temporary($global = true);

稀疏列

您可以通过在列定义后附加 sparse 来流畅地将特定列标记为 稀疏。这仅适用于行存储表。

Schema::create('table', function (Blueprint $table) {
    $table->rowstore();

    $table->string('name')->nullable()->sparse();
});

稀疏表

您可以通过在列定义后附加 sparse 来流畅地将整个表标记为 稀疏。这仅适用于行存储表。

Schema::create('table', function (Blueprint $table) {
    $table->rowstore();

    $table->string('name');

    $table->sparse();
});

分片键

您可以使用独立的 shardKey 方法或在列定义中附加 shardKey 来向您的表添加 分片键

Schema::create('table', function (Blueprint $table) {
    $table->string('name');

    $table->shardKey('name');
});

Schema::create('table', function (Blueprint $table) {
    $table->string('name')->shardKey();
});

Schema::create('table', function (Blueprint $table) {
    $table->string('f_name');
    $table->string('l_name');

    $table->shardKey(['f_name', 'l_name']);
});

排序键

您可以使用独立的 sortKey 方法或在列定义中附加 sortKey 来向您的表添加 排序键

Schema::create('table', function (Blueprint $table) {
    $table->string('name');

    $table->sortKey('name');
});

Schema::create('table', function (Blueprint $table) {
    $table->string('name')->sortKey();
});

Schema::create('table', function (Blueprint $table) {
    $table->string('f_name');
    $table->string('l_name');

    $table->sortKey(['f_name', 'l_name']);
});

默认情况下,排序键按升序排序。如果您想创建一个按降序排序的排序键,可以将键方向设置为 desc

Schema::create('table', function (Blueprint $table) {
    $table->string('name');

    $table->sortKey('name', 'desc');
});

Schema::create('table', function (Blueprint $table) {
    $table->string('name')->sortKey('desc');
});

您可以使用以下语法按列定义排序键方向

Schema::create('table', function (Blueprint $table) {
    $table->string('f_name');
    $table->string('l_name');

    $table->sortKey([['f_name', 'asc'], ['l_name', 'desc']]);
});

有时您可能想要针对每个表调整 列存储。您可以通过在 sortKey 定义中流畅地附加 with 来完成此操作。

Schema::create('table', function (Blueprint $table) {
    $table->string('name');

    $table->sortKey('name')->with(['columnstore_segment_rows' => 100000]);
});

Schema::create('table', function (Blueprint $table) {
    $table->string('name')->sortKey()->with(['columnstore_segment_rows' => 100000]);
});

但是,您可能希望在未设置列作为排序键的情况下进行调整。您可以通过创建一个空的 sortKey 定义来完成此操作。

Schema::create('table', function (Blueprint $table) {
    $table->string('name');

    $table->sortKey()->with(['columnstore_segment_rows' => 100000]);
});

唯一键

您可以使用独立的 unique 方法或在列定义中附加 unique 来向您的表添加 unique key

注意 SingleStore 要求分片键包含在唯一键中。这意味着在大多数情况下,您不能使用流畅的 API,因为您可能需要指定多个列。此限制不适用于参考表。

Schema::create('table', function (Blueprint $table) {
    $table->string('key');
    $table->string('val');

    $table->shardKey('key');
    $table->unique(['key', 'val']);
});

Schema::create('table', function (Blueprint $table) {
    $table->reference();
    $table->string('name')->unique();
});

哈希键

您可以使用 index 函数的第三个参数向您的表添加 hash key。请注意,默认情况下,在通用存储表(列存储)上的索引始终是哈希索引,因此简单的 .index(foo) 通常就足够了。在行存储表上,此语法需要创建哈希索引。

Schema::create('table', function (Blueprint $table) {
    $table->string('name');
    $table->index('name', 'name_idx', 'hash');
});

序列时间戳

要表示一列作为时间戳系列,请使用 seriesTimestamp 列修饰符。

Schema::create('table', function (Blueprint $table) {
    $table->datetime('created_at')->seriesTimestamp();

    // Or make it sparse
    $table->datetime('deleted_at')->nullable()->seriesTimestamp()->sparse();
});

计算列

SingleStore 不支持虚拟计算列。您必须使用 Laravel 的 storedAs 方法来创建 持久计算列

Schema::create('test', function (Blueprint $table) {
    $table->integer('a');
    $table->integer('b');
    $table->integer('c')->storedAs('a + b');
});

没有主键的递增列

有时您可能想要设置一个自定义主键。但是,如果您的表中有一个 int increment 列,Laravel 默认会始终将该列设置为主键。即使您手动设置另一个。可以通过使用 withoutPrimaryKey 方法禁用此行为。

Schema::create('test', function (Blueprint $table) {
    $table->id()->withoutPrimaryKey();
    $table->uuid('uuid');
    
    $table->primary(['id',  'uuid']);
});

使用FULLTEXT索引进行全文搜索

SingleStoreDB 支持使用 FULLTEXT 索引类型在列存储表中的文本列上进行全文搜索。

请注意,FULLTEXT 仅在使用 utf8_unicode_ci 排序规则时受支持。如果您尝试将索引添加到不支持排序规则的列,将抛出异常。

Schema::create('test', function (Blueprint $table) {
    $table->id();
    $table->text('first_name')->collation('utf8_unicode_ci');

    $table->fullText(['first_name']);
});

测试

使用 PHPUnit 执行测试

./vendor/bin/phpunit

要针对活动 SingleStore 数据库进行测试,创建一个 .env 文件并填写以下变量

DB_DATABASE=
DB_USERNAME=
DB_PASSWORD=
DB_HOST=

现在,当执行您的测试时,通过运行以下命令启用集成测试

HYBRID_INTEGRATION=1 ./vendor/bin/phpunit

兼容性矩阵

许可证

此库根据 Apache 2.0 许可证授权。

资源

用户协议

单店科技有限公司(“单店”)同意仅在你和你的公司(A)代表并保证,你代表你的公司有法律上约束公司的权利,并且(B)你代表你的公司接受并同意受以下规定的所有开源软件条款和条件的约束(本“协议”),该协议将通过以下任何一种方式得到明确的证据:你代表你的公司点击“下载”、“接受”或“继续”按钮,或者公司的安装、访问或使用开源连接器,并且自下载、访问、复制或安装连接器或使用单店提供的任何服务(包括任何更新或升级)的较早日期起生效。

客户理解并同意,其被授予访问SingleStore开源软件连接器(“测试版软件连接器”)的权限仅限于对这种测试版软件连接器的非生产测试和评估。客户承认SingleStore没有义务发布此类测试版软件连接器的通用版本,也没有义务为任何生产或非评估用途提供支持或保修。

无论任何文件、协议或订单文件中的任何相反内容,单店对此测试版软件连接器(包括工具和实用程序)将没有任何保证、赔偿、支持或服务水平义务。

适用的开源许可:Apache 2.0

如果你或你的公司不同意这些条款和条件,请不要勾选接受框,并且不要下载、访问、复制、安装或使用软件或服务。