データベース
データ管理の限界
これまで作成してきたアプリケーションでは、次のように、データを全て Node.js アプリケーション上の変数に記録していました。しかし、このような方法では、サーバーが終了するたびにデータが消えてしまいます。
const messages = [];
app.post((request, response) => {
messages.push(request.body.message);
// 省略
});
データをファイルに記録することはできますが、後述するような複数の問題があります。
import { writeFileSync } from "node:fs";
app.post((request, response) => {
writeFileSync("messages.txt", request.body.message);
// 省略
});
ひとつは、複数のサーバー間でデータの共有ができないことです。Web アプリケーションの利用者が増えてくると、1 台のサーバーではリクエストを処理しきれなくなります。このような場合、リクエストを複数のサーバーに分散させます。このとき、サーバー内に保存されているファイルは共有されないため、データに不整合が生じてしまいます。
また、データのサイズが大きくなってくると、データをファイルに保存することが難しくなってきます。これは、ファイルの読み書きは、変数の読み書きと比べ大幅に時間がかかるためです。高速なデータの読み書きを実現するためには、ファ イルの読み書きが最小限になるよう、データの配置を工夫する必要があります。
データベースは、このようなデータに関する諸問題を解決するためのシステムです。
データベースが動作する仕組み
データベースは、通常サーバーとして動作します。つまり、データベースサーバーは、保持しているデータに対する参照や更新のためのリクエスト (クエリ) を受け、その結果をレスポンスとしてクライアントに返します。
データベースサーバーのクライアントは、通常 Web サービスの使用者ではなく、皆さんが Node.js などで開発するサーバーです。これまで開発してきたようなサーバーを、データベースサーバーと対比してアプリケーションサーバーと呼びます。
データベースの中でも、リレーショナルデータベースは、データベースの中でも最も多く使われる種類のもので、データを Excel のような表形式でとらえます。次の図は、リレーショナルデータベースの基 本的な概念である、テーブル、カラム、レコードについて整理した図です。リレーショナルデータベースを用いる一般的なアプリケーションでは、アプリケーション開発時にテーブルとカラムを作成しておき、ユーザーの操作に応じてレコードを追加・編集・削除していきます。
リレーショナルデータベースに対するクエリは、通常 SQL と呼ばれる言語を用いて記述します。データベースクライアントとして用いるライブラリによっては、SQL を直接用いることなく、そのライブラリが提供する専用の関数等を用いてデータベースに対してクエリを発行できることがあります。
データベースを用いるアプリケーション
ここでは、Node.js のアプリケーションサーバーで、Prisma と呼ばれるライブラリを用い、リレーショナルデータベースの一つである PostgreSQL サーバーに保存されているデータを取得します。
使用する技術・サービス
PostgreSQL
現在最もよく用いられるリレーショナルデータベースのひとつです。豊富な機能を持ちます。
DBeaver
多くのデータベースを直感的に操作できるソフトウェアです。PostgreSQL にも対応しています。
Prisma
主にリレーショナルデータベースを操作するための Node.js のライブラリです。複数の構成要素からなります。
@prisma/client
パッケージ: アプリケーションサーバーから用いる npm のパッケージ。JavaScript プログラムから使用する。prisma
パッケージ: 開発時にコマンドとして用いる npm のパッケージ。npx
コマンドを通して実行する。.prisma
ファイル: データベースのテーブル構造を記述するファイル。prisma
パッケージのコマンドを用いて実際のデータベースサーバーに反映させる。Prisma
拡張機能: VS Code の拡張機能。.prisma
ファイルに対する補完やフォーマットの機能を提供する。
ElephantSQL
PostgreSQL サーバーを提供するサービスです。PostgreSQL サーバーは皆さんのコンピューター上にも構築できますが、ここではその手間を省くため、外部のサービスを利用します。
ElephantSQL で PostgreSQL サーバーを構築する
ElephantSQL のアカウントを作成しましょう。Create New Instance
ボタンを押して必要な情報を入力し、新しい PostgreSQL サーバーを起動させてください。入力が必要な情報は次の通りです。
- Name: 起動するサーバーにつける 名前です。適当に設定して構いません。
- Plan: 起動するサーバーの性能です。最も低い
Tiny Turtle (Free)
を選択すれば無料で使用できます。 - Data center: 起動するサーバーの地理的な場所です。ここでは
AP-NorthEast-1 (Tokyo)
を選択しています。
DBeaver で PostgreSQL サーバーに接続する
DBeaver をインストールしましょう。続いて、ElephantSQL の管理画面で接続情報を表示し、その情報を DBeaver に入力して前項で起動した PostgreSQL サーバーに接続しましょう。
この時点では、まだデータベース上にテーブルが作成されていません。DBeaver 上で作成することもできますが、今回は Prisma を使用して作成することにします。
Prisma でテーブル構造を作成する
VS Code 向けの Prisma 拡張機能をインストールしましょう。
新しいフォルダを VS Code で開き、npm init
コマンドを使用して package.json
ファイルを作成した後、
npx prisma init
コマンドを実行します。パッケージを実行しても良いか尋ねられる場合は、y
を入力して許可しましょう。
npx
コマンドnpx
コマンドは、npm
のパッケージを、プログラムからではなく直接実行するためのコマンドです。npm には
prisma
パッケージのように、直接実行専用のパッケージも存在します。
続いて、ElephantSQL からデータベースへの接続情報を .env
ファイルにコピーします。これにより、Prisma は ElephantSQL 上の PostgreSQL サーバーと接続できるようになります。
prisma/schema.prisma
ファイルを、次のように編集し、データベースのテーブルとカラムを定義します。
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model Todo {
id Int @id @default(autoincrement())
name String
}
完了したら、
npx prisma db push
コマンドを実行しましょう。すると、データベースに schema.prisma
に書かれた通りのテーブルとカラムが作成されるので、DBeaver で確認してみてください。接続を一旦切断し、再接続する必要があります。また、このとき、後述する @prisma/client
パッケージが自動的にインストールされます。