1.

SQL CREATE TABLE|基本構文・データ型・制約・主キー・外部キー

編集
この記事の要点
  • CREATE TABLE 文で新しい表(テーブル)を作成する
  • 基本構文は CREATE TABLE 表名 ( 列名 データ型 [制約], ... [表制約] )
  • 列ごとに型と制約(NOT NULL / UNIQUE / PRIMARY KEY / DEFAULT / CHECK)を指定する
  • 主キー / 外部キーは複数列の場合表制約として末尾に書く
  • 存在チェック付きで作りたいときは CREATE TABLE IF NOT EXISTS を使う(DBMS により差あり)

CREATE TABLE とは

SQL で新しい表(テーブル)を作成するには CREATE TABLE 文を使います。列の名前、データ型、制約をまとめて指定し、データ格納の枠組みを定義します。

基本構文

CREATE TABLE 表名 (
    列名1 データ型1 [列制約],
    列名2 データ型2 [列制約],
    ...
    [表制約 (主キー / 外部キー / CHECK / UNIQUE)]
);

基本例

CREATE TABLE employees (
    emp_id      INT          PRIMARY KEY,
    emp_name    VARCHAR(100) NOT NULL,
    email       VARCHAR(255) UNIQUE,
    hire_date   DATE         DEFAULT CURRENT_DATE,
    salary      DECIMAL(10,2) CHECK (salary >= 0),
    dept_id     INT,
    created_at  TIMESTAMP    DEFAULT CURRENT_TIMESTAMP
);

主なデータ型

DBMS により名称が一部異なりますが、代表的な型は以下です。

用途代表的な型備考
整数INT / BIGINT / SMALLINTサイズで使い分け
小数DECIMAL(p,s) / NUMERIC金額など正確に扱いたい値
浮動小数FLOAT / DOUBLE / REAL科学計算など
文字列(固定長)CHAR(n)常に n 文字で格納
文字列(可変長)VARCHAR(n)最大 n 文字
長文TEXT / CLOB長文用
日付DATE / TIME / TIMESTAMP / DATETIMEDBMS で差あり
真偽BOOLEAN / BITOracle は NUMBER(1) 代用
バイナリBLOB / VARBINARY画像・ファイル等

列制約

制約意味
NOT NULLNULL を許さない
UNIQUE列内で値が一意
PRIMARY KEY主キー(NOT NULL + UNIQUE)
DEFAULT 値INSERT 時に省略された場合の既定値
CHECK (条件)挿入 / 更新時に条件を満たす値のみ許可
REFERENCES 親表(列)外部キー参照

表制約(複数列にまたがる制約)

列単位の制約とは別に、テーブル末尾にまとめて書く表制約があります。複合主キーや複数列の外部キーで使います。

CREATE TABLE order_items (
    order_id  INT NOT NULL,
    item_no   INT NOT NULL,
    product_id INT NOT NULL,
    quantity   INT NOT NULL,
    -- 表制約
    PRIMARY KEY (order_id, item_no),
    FOREIGN KEY (order_id)   REFERENCES orders(order_id),
    FOREIGN KEY (product_id) REFERENCES products(product_id),
    CONSTRAINT chk_qty CHECK (quantity > 0)
);

主キーの書き方 2 通り

-- 列制約として
CREATE TABLE t1 (
    id INT PRIMARY KEY,
    name VARCHAR(50)
);

-- 表制約として(複合主キー時もこちら)
CREATE TABLE t2 (
    id    INT,
    sub   INT,
    name  VARCHAR(50),
    PRIMARY KEY (id, sub)
);

外部キー(FOREIGN KEY)

親テーブルに存在する値しか入れさせない制約です。ON DELETE / ON UPDATE で連鎖動作を指定できます。

CREATE TABLE orders (
    order_id  INT PRIMARY KEY,
    customer_id INT NOT NULL,
    FOREIGN KEY (customer_id)
        REFERENCES customers(customer_id)
        ON DELETE CASCADE  -- 親が消えたら子も消す
        ON UPDATE CASCADE  -- 親のキーが変わったら子も追随
);
動作意味
CASCADE連動して削除 / 更新
SET NULL子側を NULL にする(NOT NULL 列は不可)
SET DEFAULT子側を DEFAULT 値に
RESTRICT / NO ACTION子が居る間は親の削除 / 更新を拒否

自動採番(IDENTITY / SERIAL / AUTO_INCREMENT)

主キーを自動採番にしたい場合、DBMS ごとに書き方が異なります。

DBMS書き方
MySQLid INT NOT NULL AUTO_INCREMENT PRIMARY KEY
PostgreSQLid SERIAL PRIMARY KEY または id INT GENERATED ALWAYS AS IDENTITY
SQL Serverid INT IDENTITY(1,1) PRIMARY KEY
Oracleid NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY
SQLiteid INTEGER PRIMARY KEY AUTOINCREMENT

IF NOT EXISTS(既存ならスキップ)

マイグレーション初回実行の冪等性を保ちたいとき便利。

CREATE TABLE IF NOT EXISTS users (
    id    INT PRIMARY KEY,
    name  VARCHAR(50) NOT NULL
);

MySQL / PostgreSQL / SQLite で利用可。Oracle は伝統的に未対応で、EXECUTE IMMEDIATEUSER_TABLES の事前判定で代替します。

既存テーブルからコピー(CTAS)

-- 構造とデータをまとめてコピー
CREATE TABLE employees_backup AS
SELECT * FROM employees;

-- 構造だけ(WHERE で 0 件にする)
CREATE TABLE employees_empty AS
SELECT * FROM employees WHERE 1 = 0;

一時テーブル / グローバル一時テーブル

-- セッション内だけ生きる一時表
CREATE TEMPORARY TABLE tmp_log (
    id INT, msg VARCHAR(200)
);

テーブル作成後によくやること

  • インデックス追加: CREATE INDEX idx_emp_name ON employees(emp_name);
  • コメント付与(PostgreSQL): COMMENT ON COLUMN employees.emp_name IS '従業員名';
  • テーブル変更: ALTER TABLE employees ADD COLUMN phone VARCHAR(20);
  • 削除: DROP TABLE employees;

よくあるトラブル

症状原因
「table already exists」同名テーブルがある。IF NOT EXISTSDROP 先行
「invalid identifier」予約語と衝突。バッククオートや二重引用符で囲む
外部キーで作成失敗親テーブル未作成 / 親列が UNIQUE/PRIMARY KEY でない / 型不一致
NOT NULL で INSERT 失敗該当列を必ず指定 / DEFAULT を付与

FAQ

Q: 列の順序は重要?
A: 論理的には任意ですが、INSERT 値の暗黙的な順序や、人間が読む際の自然さに影響します。主キーを先頭にまとめる慣習が一般的。

Q: 型は後から変えられる?
A: ALTER TABLE ... ALTER COLUMN(DBMS によって構文差)で可能ですが、データの再整形・ロックが発生するので慎重に。

Q: 複合主キーと代理キー、どちらがいい?
A: 多くの現場では代理キー(id INT AUTO_INCREMENT)を主キーにし、業務上の一意性は UNIQUE 制約で表現します。

関連

  • 表関連 — 親カテゴリ
  • ALTER TABLE / DROP TABLE
  • CREATE INDEX — 索引
  • 主キー / 外部キー / NOT NULL / UNIQUE
  • 正規化 / データ型設計
編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. 表の作成
  2. カラムの追加
  3. カラムの定義変更
  4. カラムの削除
  5. 表の削除

最近更新/作成されたページ