Loading Context

よみこみちゅう...

Blog

論理設計⑦ ビュー

2025.01.09

本記事の目的

ビューの仕組みとメリット・デメリットを理解する。 実務(Laravel)に活かすタイミングを考える。

ビューとは?

ビューは、SQLクエリの結果を仮想テーブルとして定義したものです。物理的にデータを保存せず、元のテーブルに基づいて動的にデータを取得します。 以下のような特徴があります。

  • 実際のデータを持たない(仮想的なテーブル)
  • テーブルを元に定義され、常に最新のデータを反映
  • セキュリティや利便性向上に役立つ

メリット① クエリの簡略化

複雑なSQLクエリをビューにまとめておくことで、再利用可能な簡潔なクエリを実現できます。 例: 売上データから月ごとの集計を行うビューを作成すると、都度クエリを書く手間が省けます。

CREATE VIEW MonthlySalesSummary AS
SELECT 
    DATE_FORMAT(sale_date, '%Y-%m') AS sale_month, -- 年月のフォーマットに変換
    SUM(amount) AS total_sales -- 月ごとの売上合計
FROM 
    sales
GROUP BY 
    DATE_FORMAT(sale_date, '%Y-%m');
SELECT * FROM MonthlySalesSummary;

結果例

sale_monthtotal_sales
2024-01120,000
2024-02150,000
2024-03170,000

毎回 SUM や GROUP BY を記述する必要がなくなるため、クエリが簡潔になります。 ※sales テーブルが更新されても、ビューを通じて常に最新のデータが取得可能です。

メリット② セキュリティの向上

特定の列や条件のみを含むビューを作成することで、元のテーブルに直接アクセスさせることなく、必要なデータだけをユーザーに公開できます。

メリット③ データの一貫性

ビューを使用することで、同じクエリロジックを使い回し、アプリケーション全体でデータの一貫性を保つことができます。

デメリット① パフォーマンスの低下

ビューは実行時に動的に評価されるため、複雑なビューや多段ビューを使用すると、クエリ実行時間が長くなる場合があります。 ※ 多段ビューとは、複数のビューを段階的に組み合わせて利用する手法を指します。 1つのビューの上にさらに別のビューを重ねることで、複雑なデータ構造や集計処理をシンプルかつ再利用可能な形で実現できます。

デメリット② 依存関係の複雑化

ビュー間で依存関係が増えると、1つのビューを変更した際に他のビューやシステム全体に影響を与える可能性があります。 例)ビューが削除または変更されると、それを利用する他のビューやクエリがエラーになる。

デメリット③ 更新操作の制約

ビューを使用した更新操作(INSERT、UPDATE、DELETE)には、以下のような制約があります。これらの条件を満たさない場合、ビューを介したデータ操作はできません。

  • ビューが単一の基になるテーブルに依存していること
    • ビューが複数のテーブルを結合している場合、データの整合性を保つために更新操作が許可されません。
  • 集計や計算列が含まれていないこと
  • DISTINCT が使用されていないこと
  • GROUP BY または HAVING が含まれていないこと
  • UNION、UNION ALL、INTERSECT、EXCEPT を使用していないこと
  • サブクエリや相関サブクエリが含まれていないこと

Laravelでビューって見たことない気がします

私はLaravelの案件にアサインすることが多いですが、いままでビューを活用された例を見たことがありませんでした。 調べてみたところ、Laravelではビューを直接操作する専用の機能は用意されていないようです。 なので、LaravelのクエリビルダやEloquentモデルを活用することでビューを扱うことができるようです。

① マイグレーションでビューを作成

use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;

class CreateSalesView extends Migration
{
    public function up()
    {
        DB::statement("
            CREATE VIEW monthly_sales AS
            SELECT 
                DATE_FORMAT(created_at, '%Y-%m') AS month,
                SUM(amount) AS total_sales
            FROM sales
            GROUP BY DATE_FORMAT(created_at, '%Y-%m')
        ");
    }

    public function down()
    {
        DB::statement("DROP VIEW IF EXISTS monthly_sales");
    }

② モデルの作成

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class MonthlySales extends Model
{
    protected $table = 'monthly_sales'; // ビューの名前を指定
}

③ 利用シーン

use Illuminate\Support\Facades\DB;

$sales = DB::table('monthly_sales')
    ->where('month', '2024-12')
    ->first();

こんな感じでしょうか。。 結構手間だと感じました笑 管理も複雑になりそうです。

終わり

ビューについてのメリット・デメリットについて学びました。 以前、C#の案件でビューを使った際には非常に便利に感じましたが、Laravelではあまり事例が少なく、管理も少し複雑な印象を受けました。 リポジトリパターンを使ってアーキテクチャを丁寧に組めば、ビューを使う必要はないのではないかとも思います。

そのため、個人的な見解としては以下のようになります。 「基本的にはベーステーブル」 「非常に複雑なクエリになるときはビューを持ちいる」 という形です。

以前、「このSQL超複雑だな。。」と苦労した経験もあるので、是非ともそういう機会にまたであったらチャレンジしてみたいです。

CONTACT

「これって頼める?」みたいなざっくりしたご相談もOKです!
気になることがあれば、いつでもお気軽にご連絡ください。

SNS