- データベース
データベースとは|種類・Excelとの違い・SQLの基本を実例で解説
結論
データベースとは、データを決まった形で整理してため、すばやく探して安全に更新できる仕組みです。住所録やネットショップの商品・注文が代表例です。
この記事でわかること
- 身近な例5つと、RDB・NoSQL4種の早見表
- SQLiteとPostgreSQLで作って検索した実物
- 主な製品7種の比較表と、学ぶ順番6段階
アプリや人は、データベースに直接触れるのではなく、DBMS(データベースを管理するソフト)に SQL という言葉で頼みます。DBMS がデータを読み書きし、結果を返します。
flowchart TD
A[アプリ・人<br>ネットショップの画面など] -->|SQLで頼む<br>例 SELECT| D[DBMS<br>PostgreSQL・MySQL など]
D -->|読み書き| F[(データベース<br>テーブルの集まり)]
D -->|結果を返す| A
急いでいる人向けに、よく調べられることの答えを先にまとめます。
| 知りたいこと | 答え | 詳しい節 |
|---|---|---|
| データベースとは | 整理してためたデータの集まり | データベースとは |
| 身近な例 | 住所録・ネット通販・銀行・予約・スマホのアプリ | 身近な例 |
| DBMS とは | データベースを管理するソフト | DBMSとは |
| 主な種類 | リレーショナル(表)と NoSQL(4種) | 種類 |
| SQL とは | データベースに頼むための言葉 | SQLとは |
| Excel との違い | 型・制約・同時更新・大量データの扱い | Excelとの違い |
| 代表的な製品 | MySQL・PostgreSQL・Oracle・SQL Server・SQLite | 製品の比較 |
| 読み方・略し方 | データベース。DB(ディービー)と略す | データベースとは |
確認環境:Ubuntu 24.04.4 LTS。SQLite 3.45.1(sqlite3 コマンド)と Python 3.11.15 の sqlite3 モジュール、apt で入れた PostgreSQL 16.15(psql 16.15)で、表を作ってデータを入れ、検索・更新・エラー・トランザクション・同時更新・インデックスの効果を実際に動かして確かめました。PostgreSQL の試験用データベースは終わったあと削除しています。製品の版・ライセンス・無料版の条件は PostgreSQL・MySQL・SQLite・Oracle・Microsoft・MongoDB・Redis の公式サイト、NoSQL の分類は AWS の解説、SQL の規格は ISO のページで確かめました(確認日 2026年10月23日)。
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「データベースとは|種類・Excelとの違い・SQLの基本を実例で解説」
データベースとは(意味と身近な例)
この節では、データベースという言葉の意味と、毎日使っているサービスのどこにデータベースがあるのかが分かります。
データベース(database)は、あとで探したり使ったりできるように、決まった形で整理してためたデータの集まりです。 英語の data(データ)と base(基地)を合わせた言葉で、「データの置き場」という意味になります。読み方はそのまま「データベース」で、DB(ディービー)と略します。
紙の住所録を思い浮かべると分かりやすくなります。名前・住所・電話番号という「決まった欄」があり、1人を1行に書きます。欄が決まっているので、「東京都の人だけ」「電話番号が空の人」を探せます。コンピューターのデータベースは、これを何百万件でも、何人が同時に使っても、壊さずに扱えるようにしたものです。
1ネットショップ
会員・商品・在庫・注文・配送先。「カートに入れる」「注文する」のたびに読み書きされる。
2銀行のATM・アプリ
口座ごとの残高と入出金の記録。振り込みは「出金」と「入金」を必ずセットで記録する。
3予約サイト
ホテル・飲食店・病院の空き枠。同じ枠を2人が同時に取らないように管理する。
4図書館の貸出
本・利用者・貸出の記録。「誰が何をいつまで借りているか」を本と利用者から引ける。
5スマホのアプリ
連絡先・メッセージ・ブラウザの履歴。SQLite の公式サイトは、すべての Android と iPhone に SQLite が入っていると説明している。
NTT東日本の用語解説も、ネット通販で顧客の名前・住所や商品・在庫をデータベースにためておくことで、2回目からは入力しなくてよくなる例を挙げています。「データベースがある」とは、データが1か所に整理されていて、必要なときに必要な分だけ取り出せる状態のことです。
「データベース」という言葉は、場面によって指すものが少し変わります。
| 言い方 | 指しているもの | 例 |
|---|---|---|
| データベース(狭い意味) | ためたデータそのもの | 会員テーブル・注文テーブル |
| データベース(広い意味) | データと、それを管理するソフトの全体 | 「データベースを入れる」 |
| DBMS | データベースを管理するソフト | PostgreSQL・MySQL・SQLite |
| DB サーバー | DBMS が動いているコンピューター | 「DB サーバーが落ちた」 |
DBMS(データベース管理システム)とは
この節では、DBMS が何をしてくれるソフトなのかと、データベースとの違いが分かります。
DBMS(Database Management System、データベース管理システム)は、データベースを作り、データを出し入れし、壊れないように守るソフトです。 アプリはファイルを直接書きかえるのではなく、DBMS に「この条件のデータをちょうだい」「この行を書きかえて」と頼みます。
| DBMS の役割 | 何をしているか | この記事で確かめた節 |
|---|---|---|
| 定義 | 表の形(列の名前・型・決まりごと)を作る | SQLite で作ってみる |
| 操作 | 追加・検索・更新・削除をする | SQLite で作ってみる |
| 整合性を守る | 決まりに合わないデータを入れない | Excel との違い |
| トランザクション | 一連の処理を「全部やる」か「全部やらない」にする | Excel との違い |
| 同時に使う人の調整 | 2人が同じ行を変えるときに順番を決める | Excel との違い |
| 速く探す | インデックスで目的の行に直接行く | Excel との違い |
| 権限 | 誰がどの表を読める・書けるかを決める | 学ぶ順番(段階5) |
| バックアップと復旧 | 壊れたとき・消したときに戻せるようにする | 学ぶ順番(段階5) |
DBMS には大きく2つの形があります。手元で動かした2つの DBMS で違いを見ると、次のとおりでした。
ファイル型(SQLite)
データベースは1つのファイル。作った住所録は 8,192 バイトの addr.db
アプリの中にライブラリとして組み込んで使う
スマホのアプリ・ブラウザ・小さなツール向き
サーバー型(PostgreSQL など)
DBMS がサーバーとして動き、5432 番ポートで待ち受けていた
アプリはネットワーク越しにつなぐ
多くの人・多くのアプリが同時に書き込む Web サービス向き
$ file addr.db
addr.db: SQLite 3.x database, last written using SQLite version 3045001, ...
$ ss -ltn | grep 5432
LISTEN 0 200 0.0.0.0:5432 0.0.0.0:*
SQLite の公式サイトは「SQLite はクライアント/サーバー型のデータベースと競合しない。競合するのは fopen()(ファイルを開く関数)だ」と説明しています。ネットワーク越しに多くのプログラムが同じデータベースへ SQL を送る場合や、書き込む人が多い場合は、クライアント/サーバー型を選ぶようにとも書かれています。
データベースの種類(リレーショナルとNoSQL)
この節では、データベースの種類と、それぞれがどんなデータに向いているのかが早見表で分かります。
いま使われているデータベースは、表で管理する「リレーショナルデータベース(RDB)」と、表以外の形で管理する「NoSQL」に大きく分かれます。 AWS の解説では、NoSQL の型としてキーバリュー・ドキュメント・グラフ・ワイドカラムなどが紹介されています。
flowchart LR
N[NoSQL<br>表以外の形] --> KV[キーバリュー型<br>Redis・DynamoDB]
N --> DOC[ドキュメント型<br>MongoDB]
N --> WC[ワイドカラム型<br>Cassandra]
N --> G[グラフ型<br>Amazon Neptune]
R[RDB リレーショナル<br>表とSQL]
| 種類 | データの形 | 向いている用途 | 代表的な製品 |
|---|---|---|---|
| リレーショナル(RDB) | 行と列の表。表どうしを ID でつなぐ | 会員・注文・在庫・会計など、正しさが大事な業務 | PostgreSQL・MySQL・Oracle・SQL Server・SQLite |
| キーバリュー型 | キー(名前)と値の組 | セッション・キャッシュ・ランキング | Redis・Amazon DynamoDB |
| ドキュメント型 | JSON のような入れ子の文書 | 商品カタログ・ユーザーのプロフィール | MongoDB |
| ワイドカラム型 | パーティションキーで多数のサーバーに分けて置く表 | サーバーを足して容量と処理量を伸ばす大規模なデータ | Apache Cassandra |
| グラフ型 | 点(ノード)と線(エッジ) | SNS のつながり・おすすめ・不正の検知 | Amazon Neptune |
AWS の比較表では、リレーショナルは「テーブル・行・列で構成され、スキーマで厳密に定義され、強い一貫性を持つ」、NoSQL は「柔軟性と水平方向の拡張のために ACID(後の節で説明)の一部をゆるめることが多い」とされています。迷ったら、まずリレーショナルを学ぶのが一般的な順番です。 業務システムの多くが RDB を中心に作られていて、SQL の考え方はほかの種類を学ぶときにも役立ちます。
昔の方式も、試験や教科書には出てきます。
| 方式 | 形 | いまの扱い |
|---|---|---|
| 階層型 | 木の形の親子関係 | NTT東日本の解説では、現在はほとんど使われない |
| ネットワーク型 | 網の目のように親子を結ぶ | 同上 |
| リレーショナル型 | 表。1970年に IBM の E.F. Codd が論文で提案 | 現在の主流 |
テーブル・行・列・主キーとは(リレーショナルデータベースのしくみ)
この節では、リレーショナルデータベースの中身がどうなっているのかを、ネットショップの例で図と表で確かめられます。
リレーショナルデータベースは、データを「テーブル(表)」に入れ、テーブルどうしを ID でつないで使います。 1件のデータが1行、項目が1列です。
products(商品)テーブルを例にします。
| product_id(主キー) | name | price | stock |
|---|---|---|---|
| 101 | USBケーブル | 980 | 50 |
| 102 | マウス | 2480 | 10 |
| 103 | キーボード | 6980 | 1 |
| 用語 | 別の呼び方 | 意味 | 上の表では |
|---|---|---|---|
| テーブル | 表・リレーション | 同じ種類のデータの集まり | products |
| 行 | レコード・タプル | 1件分のデータ | 「102・マウス・2480・10」 |
| 列 | カラム・フィールド・属性 | 項目。型(数値・文字など)が決まる | price |
| 主キー | プライマリキー・PK | 行を1つに決める列。重複と空を許さない | product_id |
| 外部キー | FK | ほかの表の主キーを指す列 | orders の customer_id |
| スキーマ | ― | 表・列・型・決まりごとの設計図 | CREATE TABLE の中身 |
| インデックス | 索引 | 速く探すための目次 | 後の節で実測 |
| 正規化 | ― | 同じデータを何か所にも書かないように表を分けること | 顧客と注文を別の表にする |
ネットショップでは、顧客・商品・注文・注文明細の4つのテーブルを作り、外部キー(FK)で主キー(PK)を指してつなぎました。
flowchart TD
C[customers 顧客<br>PK customer_id<br>name・email] -->|1人が何回も注文| O[orders 注文<br>PK order_id<br>FK customer_id]
O -->|1注文に何行も| I[order_items 注文明細<br>FK order_id・product_id<br>qty]
P[products 商品<br>PK product_id<br>name・price・stock] -->|1商品が何回も| I
表を分けるのは、同じことを何か所にも書かないためです。 注文の表に顧客の名前やメールを毎回書くと、メールが変わったときに全部の注文を直す必要があり、直し漏れで食い違います。顧客の情報は customers に1回だけ書き、注文には customer_id だけを書きます。この分け方を正規化と呼び、関連記事「データベースの正規化をわかりやすく|第1〜第3正規形の例」で扱っています。ER 図の記号の読み方と、図から表を作る手順は、関連記事「ER図の書き方|記号の読み方からCREATE TABLEまで実行して確認」で扱っています。
SQLとは(データベースに頼む言葉)
この節では、SQL の基本の命令と、それぞれが何をするのかが早見表で分かります。
SQL(エスキューエル)は、リレーショナルデータベースに「表を作る」「データを入れる・探す・変える・消す」を頼むための言葉です。 ISO/IEC 9075 という国際規格で決められていて、2026年10月23日時点の ISO のページでは 2023年版が最新です。IBM の解説によると、IBM の Don Chamberlin と Ray Boyce が作り、はじめは SEQUEL という名前でした。
| 分類 | 命令 | すること | 例 |
|---|---|---|---|
| データを探す | SELECT | 条件に合う行を取り出す | SELECT * FROM contacts WHERE pref = '東京都'; |
| データを入れる | INSERT | 行を追加する | INSERT INTO contacts VALUES (...); |
| データを変える | UPDATE | 行の値を変える | UPDATE contacts SET phone = '...' WHERE id = 3; |
| データを消す | DELETE | 行を消す | DELETE FROM contacts WHERE id = 4; |
| 表を作る・消す | CREATE TABLE・DROP TABLE | 表の形を決める・表ごと消す | CREATE TABLE contacts (...); |
| まとめて確定・取り消し | BEGIN・COMMIT・ROLLBACK | トランザクションの開始・確定・取り消し | 後の節で実演 |
SELECT のよく使う書き足しです。
| 書き足し | 意味 |
|---|---|
WHERE 条件 |
条件に合う行だけにする |
ORDER BY 列 |
並べかえる(DESC で大きい順) |
GROUP BY 列 |
同じ値ごとにまとめて数える・合計する |
JOIN 表 ON 条件 |
別の表とつなぐ |
LIMIT 件数 |
先頭から何件だけ取る |
SQL は「どうやって探すか」ではなく「何がほしいか」を書く言葉です。 どの順でファイルを読むか、インデックスを使うかは DBMS が決めます。この記事で使う命令は、どの製品でもほぼ同じ形で動きます。製品ごとの細かい違い(日付の関数・件数の制限の書き方など)は、関連記事「SQL入門|基本文法一覧と書き方を実行結果つきで解説【コピペOK】」で扱っています。
SQLiteでデータベースを作ってみる(住所録)
この節では、SQLite で住所録のデータベースを作り、SQL で追加・検索・更新・削除・集計した実物を確かめられます。
SQLite は、サーバーを立てずに1つのファイルでデータベースを作れる DBMS です。 公式サイトでは「小さく、速く、自己完結した、信頼性の高い SQL データベースエンジン」で、ソースコードはパブリックドメイン(誰でも自由に使える)とされています。Ubuntu では apt の sqlite3 パッケージで sqlite3 コマンドが入ります。2026年10月23日時点の公式サイトの最新版は 3.54.1(2026年10月16日)です。
次の SQL を addr.sql に保存し、sqlite3 addr.db < addr.sql で実行しました。addr.db が無ければ新しく作られます。
.headers on
.mode list
.separator " | "
CREATE TABLE contacts (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
pref TEXT NOT NULL,
phone TEXT
);
INSERT INTO contacts (id, name, pref, phone) VALUES
(1, '佐藤 花子', '東京都', '03-1111-2222'),
(2, '鈴木 一郎', '大阪府', '06-3333-4444'),
(3, '高橋 次郎', '東京都', NULL),
(4, '田中 美咲', '福岡県', '092-555-6666');
SELECT * FROM contacts;
SELECT name, phone FROM contacts WHERE pref = '東京都';
UPDATE contacts SET phone = '03-7777-8888' WHERE id = 3;
DELETE FROM contacts WHERE id = 4;
SELECT * FROM contacts ORDER BY id;
SELECT pref, COUNT(*) AS 人数 FROM contacts GROUP BY pref;
id | name | pref | phone
1 | 佐藤 花子 | 東京都 | 03-1111-2222
2 | 鈴木 一郎 | 大阪府 | 06-3333-4444
3 | 高橋 次郎 | 東京都 |
4 | 田中 美咲 | 福岡県 | 092-555-6666
name | phone
佐藤 花子 | 03-1111-2222
高橋 次郎 |
id | name | pref | phone
1 | 佐藤 花子 | 東京都 | 03-1111-2222
2 | 鈴木 一郎 | 大阪府 | 06-3333-4444
3 | 高橋 次郎 | 東京都 | 03-7777-8888
pref | 人数
大阪府 | 1
東京都 | 2
上から順に、4人を入れた直後の全件、東京都の人だけ、高橋さんの電話番号を入れて田中さんを消した後、都道府県ごとの人数です。最初の3行(.headers など)は SQL ではなく sqlite3 コマンドの表示の設定です。NULL は「値が無い」ことを表し、空の欄として表示されました。
決まりに合わないデータは、DBMS が入れずに止めます。 同じ id、空の都道府県を入れようとしたときの出力です。
$ sqlite3 addr.db "INSERT INTO contacts VALUES (1, '山田 太郎', '京都府', NULL);"
Error: stepping, UNIQUE constraint failed: contacts.id (19)
$ sqlite3 addr.db "INSERT INTO contacts (id, name, pref) VALUES (5, '山田 太郎', NULL);"
Error: stepping, NOT NULL constraint failed: contacts.pref (19)
SQLite には、ほかの製品と違う点が1つあります。ふつうの表では、INTEGER と決めた列にも文字が入ります。 公式の説明では、列の型は「できればこの型に変える」という希望で、変えられない値はそのまま入ります。型を厳しく守らせたいときは、表の最後に STRICT を付けます(3.37.0 以降)。
$ sqlite3 :memory: "CREATE TABLE t(n INTEGER); INSERT INTO t VALUES ('abc'); SELECT n, typeof(n) FROM t;"
abc|text
$ sqlite3 :memory: "CREATE TABLE t(n INTEGER) STRICT; INSERT INTO t VALUES ('abc');"
Error: stepping, cannot store TEXT value in INTEGER column t.n (19)
アプリからは、プログラミング言語のライブラリを通して SQL を送ります。Python には sqlite3 が標準で入っています。
import sqlite3
con = sqlite3.connect("addr.db")
pref = "東京都" # 画面で選ばれた値のつもり
rows = con.execute(
"SELECT name, phone FROM contacts WHERE pref = ? ORDER BY id", (pref,)
).fetchall()
for name, phone in rows:
print(name, phone)
con.close()
佐藤 花子 03-1111-2222
高橋 次郎 03-7777-8888
画面から来た値は ?(プレースホルダー)で渡し、SQL の文字列に直接つなげません。 文字列をつなげると、入力によって SQL の意味が変わってしまう危険があります。sqlite3 コマンドの使い方は、関連記事「SQLiteの使い方|コマンド早見表とPython連携を実行例で解説」で扱っています。
PostgreSQLで複数の表をつなぐ(ネットショップの例)
この節では、サーバー型の PostgreSQL で4つの表を作り、JOIN でつないで「誰が何をいくら買ったか」を出した実物を確かめられます。
PostgreSQL は、オープンソースのサーバー型 RDB です。 2026年10月23日時点の公式のサポート表では、最新は 18(18.6)で、16 は 2028年11月までサポートされます(19 は RC 版の段階)。
試験用のデータベースを createdb s370db で作り、先ほどの図のとおりに表を作りました。
CREATE TABLE customers (
customer_id integer PRIMARY KEY,
name text NOT NULL,
email text NOT NULL UNIQUE
);
CREATE TABLE products (
product_id integer PRIMARY KEY,
name text NOT NULL,
price integer NOT NULL CHECK (price >= 0),
stock integer NOT NULL CHECK (stock >= 0)
);
CREATE TABLE orders (
order_id integer PRIMARY KEY,
customer_id integer NOT NULL REFERENCES customers(customer_id),
ordered_on date NOT NULL
);
CREATE TABLE order_items (
order_id integer REFERENCES orders(order_id),
product_id integer REFERENCES products(product_id),
qty integer NOT NULL CHECK (qty > 0),
PRIMARY KEY (order_id, product_id)
);
INSERT INTO customers VALUES
(1, '佐藤 花子', 'hanako@example.com'),
(2, '鈴木 一郎', 'ichiro@example.com');
INSERT INTO products VALUES
(101, 'USBケーブル', 980, 50),
(102, 'マウス', 2480, 10),
(103, 'キーボード', 6980, 1);
INSERT INTO orders VALUES (1001, 1, '2026-10-20'), (1002, 2, '2026-10-21');
INSERT INTO order_items VALUES (1001, 101, 2), (1001, 102, 1), (1002, 101, 1);
| 決まりごと(制約) | 意味 |
|---|---|
PRIMARY KEY |
主キー。重複も空も許さない |
NOT NULL |
空を許さない |
UNIQUE |
同じ値を2回入れない(メールアドレスなど) |
CHECK (stock >= 0) |
条件に合わない値を入れない(在庫がマイナスにならない) |
REFERENCES |
外部キー。相手の表にある値しか入れない |
psql の \d products で、表の設計図を見られます。
Table "public.products"
Column | Type | Collation | Nullable | Default
------------+---------+-----------+----------+---------
product_id | integer | | not null |
name | text | | not null |
price | integer | | not null |
stock | integer | | not null |
Indexes:
"products_pkey" PRIMARY KEY, btree (product_id)
Check constraints:
"products_price_check" CHECK (price >= 0)
"products_stock_check" CHECK (stock >= 0)
Referenced by:
TABLE "order_items" CONSTRAINT "order_items_product_id_fkey" FOREIGN KEY (product_id) REFERENCES products(product_id)
4つの表を JOIN でつなぎ、注文の明細と、顧客ごとの合計を出しました。
SELECT c.name AS 顧客, o.order_id AS 注文番号, p.name AS 商品, i.qty AS 数量, p.price * i.qty AS 小計
FROM orders o
JOIN customers c ON c.customer_id = o.customer_id
JOIN order_items i ON i.order_id = o.order_id
JOIN products p ON p.product_id = i.product_id
ORDER BY o.order_id, p.product_id;
SELECT c.name AS 顧客, SUM(p.price * i.qty) AS 合計
FROM orders o
JOIN customers c ON c.customer_id = o.customer_id
JOIN order_items i ON i.order_id = o.order_id
JOIN products p ON p.product_id = i.product_id
GROUP BY c.name ORDER BY 合計 DESC;
顧客 | 注文番号 | 商品 | 数量 | 小計
-----------+----------+-------------+------+------
佐藤 花子 | 1001 | USBケーブル | 2 | 1960
佐藤 花子 | 1001 | マウス | 1 | 2480
鈴木 一郎 | 1002 | USBケーブル | 1 | 980
(3 rows)
顧客 | 合計
-----------+------
佐藤 花子 | 4440
鈴木 一郎 | 980
(2 rows)
注文の表には顧客名も商品名も書いていないのに、JOIN で ID をたどると名前と金額がそろいます。 商品名や価格を変えても、変えるのは products の1行だけです。JOIN を含む SQL の基本の書き方は、関連記事「SQL入門|基本文法一覧と書き方を実行結果つきで解説【コピペOK】」で扱っています。
データベースとExcelの違い(表の扱い・同時更新・整合性)
この節では、表計算ソフトとデータベースの違いを、PostgreSQL で実際に起こしたエラー・取り消し・同時更新・検索の速さで確かめられます。
どちらも行と列の表に見えますが、表計算ソフトは「人が見て計算する表」、データベースは「たくさんのプログラムと人が、決まりを守って読み書きする表」です。 違いが出るのは次の4点です。
表の扱い
「二万円」を価格の列に入れると、PostgreSQL はエラーで止めた
整合性(データの正しさ)
在庫のマイナス、存在しない顧客の注文、使われている顧客の削除を止めた
途中で失敗したとき
5つの処理の4つ目で失敗し、注文も在庫も元のままだった
同時に更新したとき
最後の1個を2人が同時に買い、売れたのは1個だけだった
ここからは、4点を1つずつ実物で確かめます。
決まりに合わないデータを入れない(制約)
商品・顧客・注文の表に、わざと決まりに合わない変更を送りました。
=> INSERT INTO customers VALUES (3, '高橋 次郎', 'hanako@example.com');
ERROR: duplicate key value violates unique constraint "customers_email_key"
DETAIL: Key (email)=(hanako@example.com) already exists.
=> INSERT INTO orders VALUES (1003, 99, '2026-10-22');
ERROR: insert or update on table "orders" violates foreign key constraint "orders_customer_id_fkey"
DETAIL: Key (customer_id)=(99) is not present in table "customers".
=> UPDATE products SET stock = stock - 2 WHERE product_id = 103;
ERROR: new row for relation "products" violates check constraint "products_stock_check"
DETAIL: Failing row contains (103, キーボード, 6980, -1).
=> INSERT INTO products VALUES (104, 'モニター', '二万円', 5);
ERROR: invalid input syntax for type integer: "二万円"
=> DELETE FROM customers WHERE customer_id = 1;
ERROR: update or delete on table "customers" violates foreign key constraint "orders_customer_id_fkey" on table "orders"
DETAIL: Key (customer_id)=(1) is still referenced from table "orders".
=> INSERT INTO customers (customer_id, email) VALUES (4, 'x@example.com');
ERROR: null value in column "name" of relation "customers" violates not-null constraint
DETAIL: Failing row contains (4, null, x@example.com).
| 送った変更 | 止めた決まり | 守られたこと |
|---|---|---|
| 同じメールで2人目を登録 | UNIQUE | 1つのメールに1人 |
| 存在しない顧客99の注文 | 外部キー | 持ち主のいない注文ができない |
| 在庫1個のキーボードを2個減らす | CHECK | 在庫がマイナスにならない |
| 価格に「二万円」 | 型(integer) | 合計の計算が壊れない |
| 注文のある顧客を削除 | 外部キー | 注文から顧客をたどれなくならない |
| 名前の無い顧客 | NOT NULL | 必ず名前がある |
決まりを表の設計に書いておけば、どのアプリ・どの人が書き込んでも同じように守られます。 制約の書き方は CREATE TABLE の中に書くのが基本で、あとから追加することもできます。
途中で失敗したら全部取り消す(トランザクション)
トランザクションは、いくつかの処理をひとまとめにし、全部成功したら確定(COMMIT)、1つでも失敗したら全部取り消す(ROLLBACK)仕組みです。 振り込みの「出金」と「入金」のように、片方だけ終わると困る処理に使います。
顧客2がキーボード1個とマウス20個(在庫10個)を注文する処理を、1つのトランザクションで流しました。
BEGIN;
INSERT INTO orders VALUES (1003, 2, '2026-10-23');
INSERT INTO order_items VALUES (1003, 103, 1);
UPDATE products SET stock = stock - 1 WHERE product_id = 103;
INSERT INTO order_items VALUES (1003, 102, 20);
UPDATE products SET stock = stock - 20 WHERE product_id = 102;
COMMIT;
SELECT product_id, name, stock FROM products ORDER BY product_id;
SELECT count(*) AS 注文1003の件数 FROM orders WHERE order_id = 1003;
BEGIN
INSERT 0 1
INSERT 0 1
UPDATE 1
INSERT 0 1
psql:tx.sql:7: ERROR: new row for relation "products" violates check constraint "products_stock_check"
DETAIL: Failing row contains (102, マウス, 2480, -10).
ROLLBACK
product_id | name | stock
------------+-------------+-------
101 | USBケーブル | 50
102 | マウス | 10
103 | キーボード | 1
(3 rows)
注文1003の件数
----------------
0
(1 row)
4つ目までは成功していましたが、5つ目のマウスの在庫で失敗し、COMMIT は ROLLBACK になりました。 キーボードの在庫は1のまま、注文1003も残っていません。「注文はできたのに在庫が減っていない」といった中途半端な状態が残りません。
データベースの処理が守る4つの性質を、頭文字をとって ACID と呼びます。
| 性質 | 意味 | 上の実物では |
|---|---|---|
| A 原子性(Atomicity) | 全部やるか、全部やらないか | 5つの処理がまとめて取り消された |
| C 一貫性(Consistency) | 決まりに合わない状態にならない | 在庫がマイナスにならなかった |
| I 独立性(Isolation) | 同時に動く処理が互いに混ざらない | 次の節の同時更新 |
| D 耐久性(Durability) | 確定したものは、電源が落ちても消えない | COMMIT した注文1001・1002 |
COMMIT・ROLLBACK の書き方とエラーのときの動きは、関連記事「SQLトランザクションとは|COMMIT・ROLLBACKの書き方と実行結果」で扱っています。
2人が同時に同じ行を変えたら(同時更新)
在庫が1個だけのキーボードを、2人が同時に買う場面を作りました。A さんの処理は在庫を減らしてから3秒待って確定し、B さんの処理はその1秒後に同じ行を減らそうとします。どちらも「在庫が1以上なら1減らす」という同じ SQL です。
-- A さん
BEGIN;
UPDATE products SET stock = stock - 1 WHERE product_id = 103 AND stock >= 1;
SELECT pg_sleep(3); -- 支払いの処理に時間がかかっているつもり
COMMIT;
-- B さん(A さんの1秒後)
UPDATE products SET stock = stock - 1 WHERE product_id = 103 AND stock >= 1;
-- A さん
UPDATE 1
COMMIT
-- B さん
UPDATE 0
Time: 2041.416 ms (00:02.041)
-- 最後の在庫
0
flowchart TD
A1[Aさん 在庫を1減らす<br>行に鍵がかかる] --> B1[Bさん 同じ行を減らす<br>鍵が外れるまで待つ]
B1 --> A2[Aさん COMMIT<br>在庫0で確定]
A2 --> B2[Bさん 在庫0で条件を見直す<br>UPDATE 0 で売れない]
B さんの UPDATE は約2秒待たされ、A さんの確定後に「在庫0なので対象なし(UPDATE 0)」になりました。 在庫はマイナスにならず、1個を2人に売ることもありません。PostgreSQL のドキュメントでは、既定の分離レベル Read Committed で、ほかの処理が更新中の行は確定か取り消しまで待ち、確定したら新しい値で WHERE の条件を見直す、と説明されています。B さんのアプリは UPDATE 0 を見て「売り切れ」と表示できます。
大量のデータから速く探す(インデックス)
会員100万人の表を作り、メールアドレスで1人を探す時間を、インデックス(索引)の有無で比べました。
CREATE TABLE members (id integer PRIMARY KEY, email text NOT NULL, pref text NOT NULL);
INSERT INTO members
SELECT g, 'user' || g || '@example.com', (ARRAY['東京都','大阪府','愛知県','福岡県','北海道'])[1 + g % 5]
FROM generate_series(1, 1000000) AS g;
SELECT id, pref FROM members WHERE email = 'user765432@example.com'; -- インデックスなし
CREATE INDEX members_email_idx ON members (email);
SELECT id, pref FROM members WHERE email = 'user765432@example.com'; -- インデックスあり
行数 | 大きさ
---------+--------
1000000 | 87 MB
-- インデックスなし(2回)
Time: 49.844 ms
Time: 69.329 ms
Gather (cost=1000.00..14542.43 rows=1 width=14) (actual time=84.503..88.839 rows=1 loops=1)
Workers Planned: 2
Workers Launched: 2
-> Parallel Seq Scan on members (cost=0.00..13542.33 rows=1 width=14) (actual time=71.196..76.741 rows=0 loops=3)
Filter: (email = 'user765432@example.com'::text)
Rows Removed by Filter: 333333
Execution Time: 88.861 ms
-- インデックスあり(2回)
Time: 0.331 ms
Time: 0.055 ms
Index Scan using members_email_idx on members (cost=0.42..8.44 rows=1 width=14) (actual time=0.003..0.004 rows=1 loops=1)
Index Cond: (email = 'user765432@example.com'::text)
Execution Time: 0.008 ms
索引の大きさ
--------------
39 MB
インデックスが無いと、PostgreSQL は100万行を3つの処理に分けて全部読み、1行を見つけていました(Seq Scan)。インデックスを作ると、本の索引のように目的の行へ直接行き(Index Scan)、時間はおよそ1,000分の1になりました。 その代わり、インデックスは39MBの場所を使い、行を追加・更新するたびに索引も書きかえます。よく検索する列にだけ作るのが基本です。実行計画(EXPLAIN)の読み方は、本文の EXPLAIN の行のように「Seq Scan か Index Scan か」を見るところから始めます。
主なデータベース製品の比較(MySQL・PostgreSQL・Oracle・SQL Server・SQLite・MongoDB・Redis)
この節では、よく名前を聞く7つの製品の種類・ライセンス・向いている用途が比較表で分かります。
| 製品 | 種類・形 | ライセンス・無料で使えるか | 向いている用途 |
|---|---|---|---|
| MySQL | RDB・サーバー型 | Community Edition は GPL。商用ライセンスもある | Web サービス・CMS |
| PostgreSQL | RDB・サーバー型 | PostgreSQL License(BSD・MIT に近い) | Web サービス・業務システム・分析 |
| Oracle AI Database | RDB・サーバー型 | 商用。無料版 26ai Free は 2 CPU スレッド・RAM 2GB・データ12GBまで | 大きな企業の基幹システム |
| SQL Server | RDB・サーバー型 | 商用。Express(小規模向け)と Developer(開発・試験用)は無料 | Windows・.NET の業務システム |
| SQLite | RDB・ファイル型 | パブリックドメイン | スマホ・ブラウザ・組み込み・小さなツール |
| MongoDB | NoSQL ドキュメント型 | Community Server は SSPL | JSON の形のまま扱うアプリ |
| Redis | NoSQL キーバリュー型(メモリ上) | Redis 8 から RSALv2・SSPLv1・AGPLv3 から選ぶ | キャッシュ・セッション・ランキング |
表の内容は、2026年10月23日時点の各社の公式サイトで確かめたものです。現行の版は次のとおりでした。
| 製品 | 2026年10月23日時点の公式の表記 |
|---|---|
| PostgreSQL | 18.6 が最新(19 は RC 1)。16 は 16.15 |
| MySQL | ダウンロードページに 26.10.0・26.7.0・9.7.4 LTS・8.4.13 LTS・8.0.46 |
| SQLite | 3.54.1(2026年10月16日) |
| Oracle | Oracle AI Database 26ai |
| SQL Server | SQL Server 2025 |
クラウドでは、これらの DBMS をサービスとして借りる形(Amazon RDS・Google Cloud SQL・Azure SQL Database など)もよく使われます。サーバーの用意・バックアップ・版の更新を事業者が受け持ち、料金は使った分で決まります。
どれを選ぶかの目安
| 状況 | 選ばれることが多いもの | 理由 |
|---|---|---|
| SQL をはじめて学ぶ | SQLite | 入れてすぐ1ファイルで試せる |
| Web サービス・業務システムを作る | PostgreSQL・MySQL | 無料で使え、情報が多い |
| 会社ですでに使っている製品がある | その製品 | 運用の手順と人がそろっている |
| スマホ・デスクトップのアプリに内蔵 | SQLite | サーバーが要らない |
| キャッシュ・ランキング・セッション | Redis | メモリ上で速い |
| 形が決まらない JSON をそのままためる | MongoDB(または PostgreSQL の jsonb) | 列を先に決めなくてよい |
製品が違っても、表・主キー・SQL・トランザクションの考え方は同じです。 1つで覚えたことは、ほかの RDB にもほぼそのまま使えます。
データベースを学ぶ順番
この節では、はじめての人がつまずかずにデータベースを身につける順番と、それぞれで読む記事が分かります。
SQLite で表を作り、SELECT を書く
この記事の住所録をそのまま打ち込む。WHERE・ORDER BY・GROUP BY で結果が変わるのを見る。
INSERT・UPDATE・DELETE と JOIN
WHERE を付け忘れると全行が変わることを、試しの表で確かめる。2つの表を ID でつなぐ。
表の設計を学ぶ
主キー・外部キー・正規化・ER 図。どの表に何を書くかを自分で決める。
トランザクションとインデックス
途中で失敗したとき・同時に更新したとき・遅いときに何が起きるかを、この記事の実物で確かめる。
PostgreSQL か MySQL を入れて使う
ユーザーと権限、バックアップ、アプリからの接続。サーバー型ならではの操作を覚える。
資格で知識を整理する
基本情報技術者試験のデータベースの分野から、さらに深めるならデータベーススペシャリスト試験へ。
設計・SQL・トランザクション・性能までを午後の記述問題で問われる国家試験の内容と勉強の進め方は、関連記事「データベーススペシャリスト試験とは|日程・合格率・午後対策を実例で解説」で扱っています。
- 1本番のデータで練習しない試しの表やデータベースを作り、終わったら消す。この記事でも試験用のデータベースは最後に削除した
- 2UPDATE・DELETE は先に SELECT で対象を見る同じ WHERE で SELECT し、件数が合っているのを見てから実行する
- 3大事な変更は BEGIN してから結果を見て COMMIT、おかしければ ROLLBACK で戻せる
- 4決まりは表の設計に書くNOT NULL・UNIQUE・CHECK・外部キーで、アプリが変わっても守られる
- 5画面の入力は SQL に直接つなげないプレースホルダー(?・$1)で値として渡す
よくある質問
Q. データベースとは簡単に言うと何ですか? A. あとで探したり使ったりできるように、決まった形で整理してためたデータの集まりです。住所録やネットショップの会員・商品・注文が身近な例です。
Q. データベースの身近な例は? A. ネット通販の会員と注文、銀行の口座の残高、予約サイトの空き枠、図書館の貸出、スマホの連絡先やメッセージなどです。SQLite の公式サイトは、Android・iPhone・主なブラウザに SQLite が入っていると説明しています。
Q. DBMS とデータベースの違いは? A. データベースはためたデータそのもの、DBMS はそれを作り・出し入れし・守るソフトです。PostgreSQL や MySQL は DBMS の名前ですが、日常ではまとめて「データベース」と呼ぶことも多くあります。
Q. データベースと Excel の違いは? A. データベースは列ごとに型と決まりを持ち、決まりに合わないデータを入れません。途中で失敗したときの取り消し、同時に更新したときの順番待ち、大量のデータの速い検索も DBMS が受け持ちます。この記事では、在庫のマイナスや二重販売を PostgreSQL が止める様子を実物で確かめています。
Q. リレーショナルデータベース(RDB)とは? A. データを行と列の表に入れ、表どうしを ID(主キーと外部キー)でつないで扱うデータベースです。SQL で操作し、MySQL・PostgreSQL・Oracle・SQL Server・SQLite が代表的な製品です。
Q. NoSQL とは?RDB との違いは? A. 表以外の形(キーと値・JSON の文書・大きな表・グラフ)でデータを扱うデータベースの総称です。AWS の解説では、NoSQL は柔軟さや水平方向の拡張のために ACID の一部をゆるめることが多い、とされています。
Q. SQL とは? A. リレーショナルデータベースに表を作る・データを入れる・探す・変える・消すを頼むための言葉です。ISO/IEC 9075 として国際規格になっていて、SELECT・INSERT・UPDATE・DELETE が基本の4つです。
Q. 主キーとは?
A. 表の中で行を1つに決めるための列です。同じ値を2回入れられず、空にもできません。この記事の SQLite でも、同じ id を入れると UNIQUE constraint failed で止まりました。
Q. データベースは無料で使えますか? A. PostgreSQL・MySQL Community Edition・SQLite は無料で使えます。Oracle と SQL Server は商用の製品ですが、Oracle AI Database 26ai Free、SQL Server の Express と Developer という無料の版があります。
Q. MySQL と PostgreSQL の違いは? A. どちらも無料で使えるサーバー型の RDB で、基本の SQL は同じ形で動きます。ライセンスは MySQL Community Edition が GPL、PostgreSQL が BSD・MIT に近い PostgreSQL License です。細かい関数や型には違いがあるので、使う製品のドキュメントで確かめます。
Q. データベースはどうやって勉強すればよいですか? A. SQLite で表を作って SELECT を書くところから始め、更新と JOIN、表の設計(主キー・正規化・ER 図)、トランザクションとインデックス、サーバー型の DBMS の運用、と進めるのが一般的な順番です。この記事の「データベースを学ぶ順番」に、段階ごとの記事をまとめています。
まとめ
- データベースは、決まった形で整理してためたデータの集まり。DBMS(PostgreSQL・MySQL・SQLite など)が作成・出し入れ・保護を受け持ち、アプリは SQL で頼む。
- 種類はリレーショナル(表)と NoSQL(キーバリュー・ドキュメント・ワイドカラム・グラフ)。迷ったらリレーショナルから学ぶ。
- 表は行(1件)と列(項目)でできていて、主キーで行を1つに決め、外部キーで表どうしをつなぐ。JOIN でたどると、名前を1か所に書くだけで注文と顧客がそろう。
- SQLite は1ファイル、PostgreSQL はサーバーとして動く。SQLite のふつうの表は INTEGER の列に文字が入り、STRICT で厳しくできる。
- Excel との違いは、型と制約(6種類の誤りを止めた)、トランザクション(失敗で全部取り消し)、同時更新(2秒待って UPDATE 0、二重販売なし)、インデックス(100万行で約1,000分の1の時間)。
- 製品は用途とライセンスで選ぶ。表・主キー・SQL・トランザクションの考え方はどの RDB でも共通。
参考・出典
確認日はいずれも 2026年10月23日です。
- SQLite「SQLite Home Page」:https://www.sqlite.org/index.html
- SQLite「Most Widely Deployed and Used Database Engine」:https://www.sqlite.org/mostdeployed.html
- SQLite「Appropriate Uses For SQLite」:https://www.sqlite.org/whentouse.html
- SQLite「STRICT Tables」:https://www.sqlite.org/stricttables.html
- PostgreSQL「Versioning Policy」:https://www.postgresql.org/support/versioning/
- PostgreSQL「License」:https://www.postgresql.org/about/licence/
- PostgreSQL 16 Documentation「Transaction Isolation」:https://www.postgresql.org/docs/16/transaction-iso.html
- MySQL「MySQL Community Edition」:https://www.mysql.com/products/community/
- MySQL「MySQL Community Downloads」:https://dev.mysql.com/downloads/mysql/
- MySQL 8.4 Reference Manual「MySQL Releases: Innovation and LTS」:https://dev.mysql.com/doc/refman/8.4/en/mysql-releases.html
- Oracle「Oracle AI Database Free」:https://www.oracle.com/database/free/
- Microsoft「SQL Server のダウンロード」:https://www.microsoft.com/ja-jp/sql-server/sql-server-downloads
- Microsoft「Excel specifications and limits」:https://support.microsoft.com/en-us/office/excel-specifications-and-limits-1672b34d-7043-467e-8e27-269d656771c3
- MongoDB「Community Edition Licensing」:https://www.mongodb.com/legal/licensing/community-edition
- Redis「Licenses」:https://redis.io/legal/licenses/
- AWS「NoSQL とは何ですか?」:https://aws.amazon.com/jp/nosql/
- IBM「What is a relational database?」:https://www.ibm.com/think/topics/relational-databases
- ISO「ISO/IEC 9075-1:2023 Information technology — Database languages SQL — Part 1: Framework」:https://www.iso.org/standard/76583.html
- NTT東日本「データベース」:https://business.ntt-east.co.jp/bizdrive/word/database.html
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「データベースとは|種類・Excelとの違い・SQLの基本を実例で解説」
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。