singlestore/singlestore-laravel

此包已被废弃且不再维护。作者建议使用singlestoredb/singlestoredb-laravel包。

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

v1.5.6 2024-07-26 14:30 UTC

README

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

此存储库包含官方SingleStoreDB驱动程序。该驱动程序封装了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,
]) : [],

DELETEUPDATE 查询中的 ORDER BY 子句

SingleStore不支持在DELETEUPDATE查询中使用ORDER BY子句。发出类似于以下查询的查询将返回错误。

DB::table('test')->orderBy('id', 'asc')->update(['id' => 1, 'a' => 'b']);
DB::table('test')->orderBy('id', 'asc')->delete();

您可以通过在连接配置中启用ignore_order_by_in_deletesignore_order_by_in_updates来配置驱动程序忽略delete()update()请求中的orderBy。例如

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

    'connections' => [
        'singlestore' => [
            'driver' => 'singlestore',
            'ignore_order_by_in_deletes' => true,
            'ignore_order_by_in_updates' => true,
            ...
        ],
    ]
]

请注意,当忽略orderBy时,如果查询包含LIMITOFFSET,可能会删除/更新不同的行。

示例

DB::table('user')->orderBy('score', 'asc')->limit(5)->delete();

在以下查询中忽略ORDER BY时 - 将删除5个随机用户而不是5个得分最低的用户。

8.1之前的PHP版本

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

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

这是一个历史性和已知的错误

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

迁移

此驱动程序提供许多用于创建或修改表的SingleStore特定方法。下面列出了它们。有关更多信息,请参阅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来流畅地将特定列标记为稀疏,这仅适用于Rowstore表。

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

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

稀疏表

您可以通过在列的定义中追加sparse来流畅地将整个表标记为稀疏,这仅适用于Rowstore表。

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']]);
});

有时您可能想针对每个表调整列存储。您可以通过将with流畅地追加到sortKey定义中来实现。

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来为您的表添加一个唯一键

注意 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键。请注意,默认情况下,Universal Storage Tables(Columnstore)上的索引始终是哈希索引,因此简单的.index(foo)通常就足够了。在Rowstore表上,此语法是创建哈希索引所需的。

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)您代表您的公司接受并同意受以下开源条款和条件的约束(本“协议”),该协议将通过以下任一方式确定:您代表您的公司点击“下载”、“接受”或“继续”按钮,适用的情况下或公司安装、访问或使用开源连接器,并自以下较早的日期起生效:下载、访问、复制或安装连接器或使用单店提供的任何服务(包括任何更新或升级)。Beta软件连接器

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

无论任何文件、协议或订单文件中的任何相反规定,单店对Beta软件连接器(包括工具和实用工具)不提供任何保证、赔偿、支持或服务水平义务。

适用开源许可证:Apache 2.0

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