{"id":15041210,"url":"https://github.com/brick/db","last_synced_at":"2025-04-13T02:20:00.967Z","repository":{"id":62497039,"uuid":"101649524","full_name":"brick/db","owner":"brick","description":"Helper tools for interacting with databases","archived":false,"fork":false,"pushed_at":"2025-02-05T11:11:50.000Z","size":129,"stargazers_count":69,"open_issues_count":0,"forks_count":12,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-04-04T04:12:35.628Z","etag":null,"topics":["bulk-inserts","database","php"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/brick.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"BenMorel"}},"created_at":"2017-08-28T14:06:32.000Z","updated_at":"2025-02-05T11:11:53.000Z","dependencies_parsed_at":"2023-12-26T14:25:00.488Z","dependency_job_id":"e258168a-e0b7-4da0-87d0-8a4bd01852cb","html_url":"https://github.com/brick/db","commit_stats":{"total_commits":55,"total_committers":2,"mean_commits":27.5,"dds":"0.018181818181818188","last_synced_commit":"fc38f8f436adb93fa829501eb6b7efca14a8eb0e"},"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brick%2Fdb","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brick%2Fdb/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brick%2Fdb/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brick%2Fdb/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/brick","download_url":"https://codeload.github.com/brick/db/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248654544,"owners_count":21140319,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bulk-inserts","database","php"],"created_at":"2024-09-24T20:45:45.843Z","updated_at":"2025-04-13T02:20:00.943Z","avatar_url":"https://github.com/brick.png","language":"PHP","funding_links":["https://github.com/sponsors/BenMorel"],"categories":[],"sub_categories":[],"readme":"Brick\\Db\n========\n\n\u003cimg src=\"https://raw.githubusercontent.com/brick/brick/master/logo.png\" alt=\"\" align=\"left\" height=\"64\"\u003e\n\nA collection of helper tools for interacting with databases.\n\n[![Build Status](https://github.com/brick/db/workflows/CI/badge.svg)](https://github.com/brick/db/actions)\n[![Coverage Status](https://coveralls.io/repos/github/brick/db/badge.svg?branch=master)](https://coveralls.io/github/brick/db?branch=master)\n[![Latest Stable Version](https://poser.pugx.org/brick/db/v/stable)](https://packagist.org/packages/brick/db)\n[![Total Downloads](https://poser.pugx.org/brick/db/downloads)](https://packagist.org/packages/brick/db)\n[![License](https://img.shields.io/badge/license-MIT-blue.svg)](http://opensource.org/licenses/MIT)\n\nInstallation\n------------\n\nThis library is installable via [Composer](https://getcomposer.org/):\n\n```bash\ncomposer require brick/db\n```\n\nRequirements\n------------\n\nThis library requires PHP 8.1 or later. \n\nFor PHP 7.4 and 8.0 compatibility, you can use version `0.2`. PHP 7.1, 7.2 \u0026 7.3, you can use version `0.1`. Note that [these PHP versions are EOL](http://php.net/supported-versions.php) and not supported anymore. If you're still using one of these PHP versions, you should consider upgrading as soon as possible.\n\nPackage overview\n----------------\n\nThis package contains two helpers: `BulkInserter` and `BulkDeleter`. These classes, built on top of `PDO`, allow you to speed up database\nrows insertion \u0026 deletion by performing multiple operations per query, with a clean OO API.\n\n### BulkInserter\n\nThis class takes advantage of the extended insert / multirow syntax available in MySQL, PostgreSQL and SQLite.\n\nIt basically replaces the need to send a batch of queries:\n\n```sql\nINSERT INTO user (id, name, age) VALUES (1, 'Bob', 20);\nINSERT INTO user (id, name, age) VALUES (2, 'John', 22);\nINSERT INTO user (id, name, age) VALUES (3, 'Alice', 24);\n```\n\nwith a single, faster query:\n\n```sql\nINSERT INTO user (id, name, age) VALUES (1, 'Bob', 20), (2, 'John', 22), (3, 'Alice', 24);\n```\n\nTo use it, create a `BulkInserter` instance with:\n\n- your `PDO` connection object\n- the name of your table\n- the name of the columns to insert\n- the number of inserts to perform per query (optional, defaults to 100)\n\n#### Example\n\n```php\nuse Brick\\Db\\Bulk\\BulkInserter;\n\n$pdo = new PDO(...);\n$inserter = new BulkInserter($pdo, 'user', ['id', 'name', 'age'], 100);\n\n$inserter-\u003equeue(1, 'Bob', 20);\n$inserter-\u003equeue(2, 'John', 22);\n$inserter-\u003equeue(3, 'Alice', 24);\n\n$inserter-\u003eflush();\n```\n\nThe `queue()` method does not do anything until either `flush()` is called, or the number of inserts per query is reached.\n\n*Note: `queue()` returns `false` when the insert has been queued only, and `true` when the number of inserts per query has been reached and the batch has therefore been flushed to the database. This can be useful to monitor the progress of the batch.*\n\n**Do not forget to call `flush()` after all your inserts have been queued. Failure to do so would result in records not being inserted.**\n\n\n### BulkDeleter\n\nThis class allows you to delete multiple records at a time.\n\nIt basically replaces the need for these queries:\n\n```sql\nDELETE FROM user WHERE id = 1;\nDELETE FROM user WHERE id = 2;\nDELETE FROM user WHERE id = 3;\n```\n\nwith a single, faster query:\n\n```sql\nDELETE FROM user WHERE (id = 1) OR (id = 2) OR (id = 3);\n```\n\nThe constructor parameters are the same as `BulkInserter`.\n\nFor obvious performance reasons, the list of columns used to identify a record should match the primary key or a unique index of the table.\n\n\n#### Example\n\nWith a single column primary key / unique index:\n\n```php\nuse Brick\\Db\\Bulk\\BulkDeleter;\n\n$pdo = new PDO(...);\n$deleter = new BulkDeleter($pdo, 'user', ['id']);\n\n$deleter-\u003equeue(1);\n$deleter-\u003equeue(2);\n$deleter-\u003equeue(3);\n\n$deleter-\u003eflush();\n```\n\nWith a composite key:\n\n```php\nuse Brick\\Db\\Bulk\\BulkDeleter;\n\n$pdo = new PDO(...);\n$deleter = new BulkDeleter($pdo, 'user_product', ['user_id', 'product_id]);\n\n$deleter-\u003equeue(1, 123);\n$deleter-\u003equeue(2, 456);\n$deleter-\u003equeue(3, 789);\n\n$deleter-\u003eflush();\n```\n\n**Do not forget to call `flush()` after all your deletes have been queued. Failure to do so would result in records not being deleted.**\n\n### Performance tips\n\nTo get the maximum performance out of this library, you should:\n\n- wrap your operations in a transaction\n- disable emulation of prepared statements (`PDO::ATTR_EMULATE_PREPARES=false`)\n\nThese two tips combined can get you **up to 50% more throughput** in terms of inserts per second. Sample code:\n\n```php\n$pdo = new PDO(...);\n$pdo-\u003esetAttribute(PDO::ATTR_EMULATE_PREPARES, false);\n\n$inserter = new BulkInserter($pdo, 'user', ['id', 'name', 'age']);\n$pdo-\u003ebeginTransaction();\n\n$inserter-\u003equeue(...);\n// more queue() calls...\n\n$inserter-\u003eflush();\n$pdo-\u003ecommit();\n\n```\n\nThe library could do this automatically, but doesn't for the following reasons:\n\n- your PDO object's configuration should not be modified by a third-party library\n- you should have full control over your transactions, when to start them and when to commit them\n\n### Respecting the limits\n\nBe careful when raising the number of operations per query, as you might hit these limits:\n\n- PHP's [memory_limit](http://php.net/manual/en/ini.core.php#ini.memory-limit)\n- MySQL's [max_allowed_packet](https://dev.mysql.com/doc/refman/5.7/en/packet-too-large.html)\n\nYou can tweak these settings if you have access to your server's configuration, however it's important to benchmark with different batch sizes, to determine the optimal size and see if increasing the server limits is worth the effort.\nIn most cases, 100 inserts per query should give you at least 80% of the maximum throughput:\n\n![Extended inserts benchmark](https://cdn-images-1.medium.com/max/800/1*k_QS1qtgN5-UyrDkjSRg_w.png)\n\nSee [this article](https://medium.com/@benmorel/high-speed-inserts-with-mysql-9d3dcd76f723) for a more in-depth analysis.\n\nMySQL also has a limit of 65535 placeholders per statement, effectively limiting the number of operations per query to `floor(65535 / number of columns)`. This does not apply if PDO emulates prepared statements.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbrick%2Fdb","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbrick%2Fdb","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbrick%2Fdb/lists"}