開発ブログ

株式会社Nextatのスタッフがお送りする技術コラムメインのブログ。

電話でのお問合わせ 075-744-6842 ([月]-[金] 10:00〜17:00)

  1. top >
  2. 開発ブログ >
  3. PHP >
  4. Laravel >
  5. 【Laravel】LaravelのstoredAsとvirtualAsの活用方法と違い
no-image

【Laravel】LaravelのstoredAsとvirtualAsの活用方法と違い

お久しぶりです、たけちゃんです。
最近業務で生成列(Generated Column)を使うケースがあり、PostgreSQLでは格納生成列のみを実装しており、仮想生成列はサポートしていないことを知りました。

Laravelでは格納生成列、仮想生成列を作成する際に使うメソッドとしてそれぞれ
\Illuminate\Database\Schema\ColumnDefinitionのメソッドであるColumnDefinition::storedAs()メソッドとColumnDefinition::virtualAs()メソッドがありますが、
そもそもこの二つの違いをよく理解していなかったので、今回はこれらのメソッドの違いや使い分けるケースについて解説していこうと思います。
尚、PostgreSQLでは仮想生成列をサポートしていませんので、ColumnDefinition::virtualAs()メソッドについてはLaravel側で\Illuminate\Database\Schema\Grammars\PostgresGrammer::modifyVirtualAs()
においてColumnDefinition::storedAs()と同じコンパイル結果になるよう処理されているようです。

環境

Laravel 10.x


本題

`ColumnDefinition::storedAs()`: 格納生成列を追加


`ColumnDefinition::storedAs()`は、データベーステーブルに実際のデータを永続的に保存するカラムを追加するための機能です。具体例を通して説明します。

 

具体例


例えば、ユーザーテーブルがあり、ユーザーの名前を大文字で保存したい場合を考えましょう。
 
Schema::table('users', function (Blueprint $table) {
    $table->string('name_upper')->storedAs('UPPER(name)');
});
このコードは、データベース内に`name_upper`というカラムを作成し、その値を元の`name`カラムの値の大文字に変換して保持します。

 

メリット

  • データの永続的な変換: `ColumnDefinition::storedAs()`を使用すると、データを変換してストレージに保存します。
  • パフォーマンス向上: データベースからデータを取得する際、必要な変換がすでに行われているため、クエリのパフォーマンスが向上します。
 

デメリット

  • ストレージ使用量: `ColumnDefinition::storedAs()`で生成されたカラムはストレージを使用します。余分なストレージを必要とするため、大規模なテーブルでは注意が必要になってきます。
 

`ColumnDefinition::virtualAs()`: 仮想生成列の追加


`ColumnDefinition::virtualAs()`は、仮想的なカラムをデータベーステーブルに追加するための機能です。このカラムはデータベースに保存されず、クエリの実行時に動的に生成されます。

 

具体例


引き続きユーザーテーブルの例を使用し、大文字の名前を仮想カラムとして追加します。
 
Schema::table('users', function (Blueprint $table) {
    $table->virtualAs('UPPER(name)', 'name_upper');
});
 

メリット

  • ストレージ節約: 仮想生成列はデータベースに保存されないため、ストレージを節約できます。
  • 動的な生成: クエリの実行時に動的に生成されるため、データの変更に対応する柔軟性があります。
 

デメリット

  • パフォーマンス: 仮想生成列はクエリ実行時に毎回計算されるため、大規模なテーブルでのパフォーマンスに影響を与える可能性があります。
 

まとめ


`ColumnDefinition::storedAs()`はデータベースにデータを永続的に保存し、パフォーマンス向上を提供しますが、ストレージ使用量が増加します。
一方、`ColumnDefinition::virtualAs()`はストレージを節約し、柔軟性を提供しますが、パフォーマンスに影響を与える可能性があります。
生成列はDBの整合性を保ちつつカラムから変換された値を扱うことができる非常に強力な手段ですが、上記の違いを理解した上で活用していくことが肝要かと思います!
 

参考文献

TOPに戻る