コンテンツにスキップ
Nibiru docsv0.9.2

データベースとマイグレーション

マルチドライバーのデータベースアダプター、スキーマ駆動型モデル生成、および番号付けされたSQLマイグレーション。

Stable Reading time ~ 2 min Edit on GitHub

Nibiru は、統一された Db アダプターの背後で 5つのデータベースドライバー を搭載しており、CLI によって駆動される番号付き SQL マイグレーションランナーも含まれています。

INI の [DATABASE] driver でアクティブなドライバーを設定します。

ドライバーバックエンド備考
mysqlNative MySQL/MariaDB (mysqli)最速で、PDO のオーバーヘッドがありません。
pdoPDO MySQL推奨されるデフォルトです。準備されたステートメント、ドライバーが広く使用されています。
postgresPostgreSQL via ODBCサーバーにのみ ODBC しか利用できない場合です。
psqlPostgreSQL via libpq (pg_*)Native PostgreSQL です。
postgresqlランタイム時に最適な PostgreSQL トランスポートを選択するラッパーです。
[DATABASE]
driver = "pdo"
hostname = "localhost"
port = 3306
username = "nibiru"
password = "secret"
basename = "nibiru_dev"
encoding = "utf8mb4"
is.active = true

ディスパッチャーはブート時にドライバーを初期化します。ドライバーの切り替えには、構成の変更と再起動のみが必要です。

生成されたすべてのモデルは、ドライバー固有の Db アダプター(Adapter\MySQL\Db, Adapter\PostgreSQL\Db, Adapter\Odbc\Db)を拡張します。すべてのアダプターは同じインターフェースを持っています:

use Nibiru\Pdo;
// Read a single row by primary-key columns
$row = Pdo::fetchRowInArrayById('users', ['user_id' => 42]);
// Run a parameterised query
$rows = Pdo::fetchAll(
'SELECT * FROM products WHERE category = :cat',
[':cat' => 'gold-plating']
);
// Insert
Pdo::insert('products', [
'name' => 'Marduk Gold Plating',
'price' => 99.0,
]);
// Update
Pdo::update('products',
['price' => 89.0],
['id' => 1]);
// Delete
Pdo::delete('products', ['id' => 1]);
// Last insert id
Pdo::lastInsertId();

ドライバ固有のヘルパーは、アダプタークラス自体に存在します(\Nibiru\Mysql::query()\Nibiru\Postgresql::pgQuery()、…)。生のアクセスが必要な場合です。

[GENERATOR] database = true の場合、ディスパッチャは毎回リクエストごとに1つのPHPクラスをテーブルごとに再生成します。詳細については Models を参照してください。

本番環境で:

[GENERATOR]
database = false
database.overwrite = false

スキーマを移行するときのみ再生成してください。

マイグレーションは application/settings/config/database/ に配置され、実行順序用に番号が付けられた プレーンなSQLファイル です。

application/settings/config/database/
├── 001-acl.sql
├── 002-account.sql
├── 003-api_registry.sql
├── 004-timeanddate.sql
├── 005-user.sql
├── 006-user_to_account.sql
├── 011-acl-data.sql
├── 012-add-unique-key-user.sql
└── 013-add-account-email.sql

CLI はそれらを適用します:

Terminal window
./nibiru -mi local
APPLICATION_ENV=staging ./nibiru -mi staging
APPLICATION_ENV=production ./nibiru -mi production

実行者は(ドライバ名ごとに)_migrations テーブルを作成し、既に適用済みのファイルはスキップします。各ファイルは単一のバッチとして実行され、途中でステートメントがエラーになる場合は、SQL を修正して再実行してください。

  • 3桁ゼロ埋めの数値プレフィックス: NNN-<slug>.sql
  • スラッグは変更を説明します(-add-account-email-drop-wrong-constraints)。
  • 1ファイルにつき1つの論理的な変更を行います。圧縮しないでください。
  • データのみのシードの場合、-data.sqlサフィックスを使用してください(011-acl-data.sql)。

IF NOT EXISTSIF EXISTS を使用して、ファイルを安全に再実行できるようにします:

CREATE TABLE IF NOT EXISTS api_registry (
api_registry_id INT(11) NOT NULL AUTO_INCREMENT,
api_registry_name VARCHAR(255) NOT NULL,
api_registry_token VARCHAR(64) NOT NULL,
PRIMARY KEY (api_registry_id),
UNIQUE KEY api_registry_token_uk (api_registry_token)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4;
``````sql
ALTER TABLE user
ADD UNIQUE KEY user_login_uk (user_login)
/* skip if exists; on MySQL 8 you can wrap with IF NOT EXISTS */;

リセットコマンド(注意して使用してください)

Section titled “リセットコマンド(注意して使用してください)”
Terminal window
./nibiru -mi-reset local # forget all applied migrations
./nibiru -mi-reset-file 005-user.sql local # forget a single file's run record

これらのコマンドはテーブルを削除しません——のみ _migrations 監査テーブルが削除されます。完全に初期化したい場合は、手動で DROP を実行してください。

driver = "psql" または "postgresql" の場合:

  • SERIAL / BIGSERIAL を代わりに使用します。
  • information_schema.tables のテーブルを使用するのではなく、SHOW TABLES を使用します。
  • 引用符:識別子はダブルクォートで囲みます("user" が正しい形式です。なぜなら user が予約語だからです)。
  • CLI の条件付きコンパイルフラグは、libpq がコンパイル時に存在しない場合でも PostgreSQL ビルドが優雅に劣化します — サポートを確認するには ./nibiru -v を実行してください。

組み込みのプールはありません。高トラフィックなアプリケーションでは使用してください:

  • MariaDB / MySQL: プロキシーサーバー(ProxySQL または HAProxy)をデータベースの前に配置します。
  • PostgreSQL: PgBouncer をトランザクションプールモードで使用します。

Nibiru は1リクエストにつき1つの接続を開きますので、通常はプーラーだけが必要です。

  • **is.active = false**は静かに接続を無効にします — クエリがnullを返す場合、これを確認してください。
  • プロダクションでのジェネレータのオン。 [GENERATOR] database = trueで、すべてのリクエストがモデルファイルを再書き込みします。デプロイ後には必ずオフにしてください。
  • 混在するドライバー。 PostgreSQLを実行しているときにmysqlを選択すると、成功したPdo::fetchAll[]を返します — 接続は静かに失敗します。スモークテストで必ずSELECT 1で確認してください。