C言語+MySQL入門|データベースを作成する

C言語+MySQL入門|データベースを作成する

前の記事では、MySQLへログインし、SQLを入力して結果を確認する方法を学びました。

今回は、在庫管理アプリで使用するデータベースを作成します。名前は、これまでの記事で紹介してきたinventory_dbです。

データベースは、商品情報や在庫履歴などのテーブルをまとめて管理する場所になります。まずはその入れ物を用意し、正しく作成できたことを確認しましょう。

この記事では、次の作業を行います。

  • データベースとテーブルの関係を確認する
  • inventory_dbを作成する
  • 文字セットと照合順序の意味を知る
  • 作成したデータベースを一覧で確認する
  • inventory_dbを作業対象として選択する
  • 選択したデータベースと設定を確認する

この記事の到達点は、inventory_dbを作成し、これからテーブルを作るための作業対象として選択できることです。

在庫管理用のデータベースを用意しよう

今回作成するinventory_dbには、後の記事で商品情報と在庫履歴のテーブルを作成します。

名前種類役割作成するタイミング
inventory_dbデータベース在庫管理で使うテーブルをまとめる今回
productsテーブル商品名、単価、在庫数などを保存する3.5
stock_historyテーブル入庫・出庫の履歴を保存する3.6

データベースを作成しただけでは、商品情報を保存するテーブルまでは作られません。

たとえば、書類を整理する場面なら、今回は整理用の棚を用意する段階です。その中にどのような項目を持つ表を置くかは、これから順番に決めていきます。

データベース名とフォルダ名を区別する

inventory_dbは、MySQL Serverの中で使うデータベース名です。

第2章で作成したC:\c-mysqlは、自分のソースコードやSQLファイルなどを保存する作業フォルダでした。

名前何を表すか
C:\c-mysql学習用の作業フォルダ
C:\c-mysql\chap03第3章のSQLファイルなどを保存する場所
inventory_dbMySQL Serverが管理するデータベース

Windowsのエクスプローラーでinventory_dbというフォルダを作っても、MySQLのデータベースを作成したことにはなりません。

今回は、MySQLクライアントからSQLを送り、サーバーにデータベースを作成してもらいます。

図1:在庫管理用のデータベースとテーブルの関係

この図から分かること

MySQL Serverの中にinventory_dbを作成し、その中に商品情報や在庫履歴のテーブルを用意します。

今回作成するのはデータベースです。productsとstock_historyは、後の記事で作成します。

この順序を意識すると、今どの部分を準備しているのかが分かりやすくなります。

管理用のrootでログインする

データベースの作成は、前の記事と同じく管理用のrootで行います。

すでに接続していてmysql>が表示されている場合は、その接続を使って進められます。

接続していない場合は、Windowsのコマンドプロンプトを開き、次のコマンドでMySQLのbinフォルダへ移動してください。

cd /d "C:\Program Files\MySQL\MySQL Server 8.4\bin"

続けて、接続コマンドを実行します。

mysql -h 127.0.0.1 -P 3306 -u root -p

パスワードの入力を求められたら、今回の学習用パスワードであるpasswordを入力します。

パスワードを直接指定する方法では、次のコマンドを使用します。

mysql -h 127.0.0.1 -P 3306 -u root -ppassword

どちらか一方の方法で接続してください。直接指定したパスワードは画面や履歴などに残るため、この方法は学習用の例として扱います。

接続後は、次のプロンプトが表示されます。

mysql>

ここからのSQLは、mysql>へ入力します。 WindowsのコマンドプロンプトやUCRT64へ直接入力するものではありません。

CREATE DATABASEでinventory_dbを作成する

データベースを作成する命令は、CREATE DATABASEです。

今回は、データベース名に加えて、文字セットと照合順序も指定します。これにより、この教材で使う文字の設定を明確にしておきます。

在庫管理用のデータベースを作成する

mysql>で、次のSQLを実行してください。

CREATE DATABASE inventory_db
    CHARACTER SET utf8mb4
    COLLATE utf8mb4_0900_ai_ci;
実行結果の例

新しく作成できた場合は、次のように表示されます。

Query OK, 1 row affected (0.04 sec)

実行時間は環境によって異なります。

Query OKは、命令が正常に実行されたことを表します。ここで表示される1 row affectedは、商品が1件登録されたという意味ではありません。今回はデータベースを作成した段階です。

SQLの部分意味
CREATE DATABASEデータベースを作成する
inventory_db作成するデータベース名
CHARACTER SET utf8mb4データベースの既定の文字セットを指定する
COLLATE utf8mb4_0900_ai_ciデータベースの既定の照合順序を指定する
;SQLの終わりを示す

CREATE DATABASEの実行には、対象に対するCREATE権限が必要です。今回は、準備作業を行うためにrootを使用しています。

SQLを複数行に分けて入力すると、途中では->が表示されます。最後のセミコロンまで入力してEnterキーを押すと、SQLが実行されます。

名前はinventory_dbにそろえる

inventoryは在庫、dbはデータベースを表す略語です。

この教材では、後の接続プログラムやSQLでもinventory_dbという名前を使用します。

別の名前でもデータベースは作成できますが、その場合は以降のコードやコマンドも読み替える必要があります。まずは教材と同じ名前にそろえると、入力間違いを確認しやすくなります。

文字セットと照合順序を知る

作成したSQLには、少し長い設定名が登場しました。

ここでは、文字セットと照合順序を分けて考えてみましょう。

設定主な役割今回使用する値
文字セット文字をどのような符号化で扱うかを決めるutf8mb4
照合順序文字列を比較したり並べたりするときの規則を決めるutf8mb4_0900_ai_ci

utf8mb4で日本語などの文字を扱う

utf8mb4は、MySQLでUTF-8の文字データを扱うための文字セットです。

1文字を1~4バイトで表現し、日本語を含むUnicodeの文字を扱えます。

在庫管理アプリでは、ノートやボールペンなど、日本語の商品名を登録することがあります。そのため、今回のデータベースではutf8mb4を指定します。

なお、これはデータベース側の設定です。VS CodeでファイルをUTF-8として保存する設定や、クライアントとの通信に使う文字セット、ターミナルの表示設定とは役割が異なります。

データベースをutf8mb4にしただけで、すべての文字化けが自動的に解消されるわけではありません。 日本語を入力・表示する際には、関係する設定もそろえて確認していきます。

照合順序は文字列の比較に関係する

照合順序は、文字列の一致判定や並び順に使われる規則です。

今回指定したutf8mb4_0900_ai_ciは、MySQL 8.4で利用できる照合順序です。名前の末尾にあるaiはアクセントの違いを、ciは大文字・小文字の違いを区別しないことを表します。

たとえば、この規則で英字を比較するときは、大文字のAと小文字のaを同じとみなします。

今は名前全体を暗記する必要はありません。文字セットが文字の表現方法、照合順序が文字列の比較規則を担当する、と理解しておきましょう。

データベースの設定はテーブル作成時の既定値になる

今回指定した文字セットと照合順序は、データベースの既定値です。

後でテーブルを作成するときに、テーブル側で別の文字セットや照合順序を指定しなければ、この設定が使われます。

そのため、テーブルを作り始める前に、データベース側の設定を決めておくと扱いやすくなります。

作成したデータベースを一覧で確認する

成功メッセージを確認したら、データベースの一覧も見てみましょう。

データベースの一覧を表示する

次のSQLを実行します。

SHOW DATABASES;
実行結果の例

rootで接続している今回の環境では、次のようなデータベースが表示されます。

+--------------------+
| Database           |
+--------------------+
| information_schema |
| inventory_db       |
| mysql              |
| performance_schema |
| sys                |
+--------------------+

環境によっては、ほかのデータベースも表示されます。

この一覧の中にinventory_dbがあれば、指定した名前で作成できたことを確認できます。

SHOW DATABASESで表示される範囲は、接続ユーザーの権限にも関係します。後で専用ユーザーを使うと、rootと同じ一覧になるとは限りません。

最初からあるデータベースも役割を持つ

inventory_db以外の名前も表示されますが、これらはMySQLが管理や情報提供に利用するものです。

名前主な役割
information_schemaデータベースやテーブルなどの構造に関する情報を提供する
mysqlアカウントや権限など、サーバー管理に必要な情報を保持する
performance_schemaサーバーの動作や性能の調査に使う情報を提供する
sys調査用の情報を確認しやすくするビューなどを提供する

今回の商品情報は、これらの管理用データベースへ作成せず、自分で用意したinventory_dbで管理します。

図2:データベースの作成と一覧による確認

この図から分かること

CREATE DATABASEでデータベースを作成し、SHOW DATABASESでその存在を確認します。

成功メッセージに加えて一覧も確認すると、目的の名前で作成できていることが分かります。

ただし、一覧に表示されたことと、作業対象として選択されていることは別です。

USEで作業対象のデータベースを選ぶ

inventory_dbを作成できたら、次に作業対象として選択します。

データベースを作成しただけでは、そのデータベースが自動的に現在の作業対象になるわけではありません。

inventory_dbを選択する

次のSQLを実行します。

USE inventory_db;
実行結果の例
Database changed

この表示になれば、現在の接続で使用する既定のデータベースがinventory_dbへ切り替わっています。

USEは、データベースを新しく作る命令ではありません。作成済みのデータベースを、これから操作する対象として選びます。

命令行うこと
CREATE DATABASEデータベースを作成する
SHOW DATABASES利用可能なデータベースの一覧を表示する
USE現在の接続で使用するデータベースを選択する

既定のデータベースを選ぶと、後でテーブル名だけを指定したSQLを実行するとき、そのデータベース内のテーブルが対象になります。

USEによる選択は、別のUSEで切り替えるか、その接続が終了するまで有効です。

選択中のデータベースを確認する

作業対象を選択したら、前の記事でも使ったDATABASE()で確認してみましょう。

現在のデータベース名を表示する

次のSQLを実行します。

SELECT DATABASE() AS current_database;
実行結果の例
+------------------+
| current_database |
+------------------+
| inventory_db     |
+------------------+

前の記事では、データベースを選択していなかったため、結果はNULLでした。

今回はUSEを実行したので、inventory_dbが表示されます。

表示される値意味
inventory_db今回のデータベースが選択されている
別のデータベース名別のデータベースが選択されている
NULL既定のデータベースを選択していない

これからテーブルを作成するときも、作業対象が合っているかを確認すると、別のデータベースへ作成してしまう間違いを防ぎやすくなります。

文字セットと照合順序を確認する

続けて、inventory_dbの文字セットと照合順序も確認します。

今回は、データベースの情報を提供するINFORMATION_SCHEMA.SCHEMATAを読み取ります。

少し長い名前ですが、まずはデータベースの設定を確認できる情報源、と考えてください。

選択中のデータベースの設定を表示する

inventory_dbを選択した状態で、次のSQLを実行します。

SELECT
    SCHEMA_NAME AS database_name,
    DEFAULT_CHARACTER_SET_NAME AS character_set_name,
    DEFAULT_COLLATION_NAME AS collation_name
FROM INFORMATION_SCHEMA.SCHEMATA
WHERE SCHEMA_NAME = DATABASE();
実行結果の例
+---------------+--------------------+--------------------+
| database_name | character_set_name | collation_name     |
+---------------+--------------------+--------------------+
| inventory_db  | utf8mb4            | utf8mb4_0900_ai_ci |
+---------------+--------------------+--------------------+

INFORMATION_SCHEMA.SCHEMATAには、データベース名や既定の文字セット、照合順序などの情報が用意されています。

SQLの部分意味
SCHEMA_NAMEデータベース名を取得する
DEFAULT_CHARACTER_SET_NAME既定の文字セットを取得する
DEFAULT_COLLATION_NAME既定の照合順序を取得する
FROM INFORMATION_SCHEMA.SCHEMATAデータベースに関する情報を取得元にする
WHERE SCHEMA_NAME = DATABASE()現在選択しているデータベースに絞り込む
AS結果の列名を付ける

このSQLは設定を読み取るためのものです。データベースの設定を書き換える処理ではありません。

まだデータベースを選択していない場合は、今回の条件では行が取得されません。先にUSE inventory_dbを実行したか確認してください。

テーブルがまだないことを確認する

データベースを作成した直後は、商品テーブルも在庫履歴テーブルもありません。

現在のデータベースにあるテーブルを確認するには、SHOW TABLESを使います。

テーブルの一覧を表示する

次のSQLを実行します。

SHOW TABLES;
実行結果の例

今回新しく作成したinventory_dbでは、次のように表示されます。

Empty set (0.00 sec)

Empty setは、今回の一覧に表示するものがないことを表します。

データベースの作成に失敗したという意味ではありません。 テーブルをまだ作成していないので、この段階では正常な結果です。

SHOW TABLESは、選択中のデータベースにあるテーブルやビューを確認するために使えます。

後の記事でproductsやstock_historyを作成すると、一覧に名前が表示されるようになります。

図3:作成・選択・内容確認は別々の操作

イラスト作成用プロンプト

この図から分かること

データベースの作成、作業対象の選択、内容の確認は、それぞれ別の操作です。

inventory_dbを作成した後、USEで選択し、DATABASE()で選択結果を確認します。

SHOW TABLESで何も表示されなくても、作成直後であれば問題ありません。これからテーブルを追加していきます。

同じ名前のデータベースがある場合

同じCREATE DATABASEをもう一度実行すると、inventory_dbがすでに存在するため、通常はERROR 1007が表示されます。

これは、最初の作成に失敗したという意味ではありません。同じ名前のデータベースを重ねて作ろうとしたことが原因です。

すでに今回の学習で作成済みなら、作成SQLを繰り返さず、USEで選択して続けられます。

IF NOT EXISTSを使う方法もある

データベースが存在しないときだけ作成したい場合は、IF NOT EXISTSを付けます。

CREATE DATABASE IF NOT EXISTS inventory_db
    CHARACTER SET utf8mb4
    COLLATE utf8mb4_0900_ai_ci;

すでに存在する場合は、新規作成を行わず、既存のデータベースを残します。通常のCREATE DATABASEでは、同名のデータベースが存在するとエラーになります。

実行結果の例

inventory_dbがすでに存在する場合は、次のように表示されます。

Query OK, 0 rows affected, 1 warning (0.00 sec)

ここで大切なのは、IF NOT EXISTSは、既存のデータベースを今回の設定へ作り直す指定ではないという点です。

状態動作
inventory_dbがない指定した設定で新しく作成する
inventory_dbがある既存のデータベースを残し、新規作成しない
既存の文字セットが異なるこの命令だけでは変更されない
既存のテーブルやデータがあるその内容は削除されない

以前から同名のデータベースがある場合は、今回の学習用として使ってよいものか、設定と内容を確認してください。

同名のエラーを消すために、既存のデータベースを削除する必要はありません。

接続し直したときは作業対象を確認する

作成したinventory_dbは、mysqlクライアントを終了しても残ります。

ただし、USEによる選択は接続ごとの状態です。前の記事と同じ、データベース名を指定しないコマンドで接続し直した場合は、再び作業対象を選びます。

USE inventory_db;
SELECT DATABASE() AS current_database;
実行結果の例

USEの実行後にDatabase changedと表示され、続くSELECTでは次の結果が得られます。

+------------------+
| current_database |
+------------------+
| inventory_db     |
+------------------+

別のクライアントを同時に起動した場合も、その接続で使用するデータベースは別に選択します。

項目接続終了後の扱い
作成したinventory_dbサーバー側に残る
データベース内のテーブルや確定済みデータサーバー側に残る
USEで選んだ作業対象その接続の終了とともに選択状態が終わる

接続し直すたびにCREATE DATABASEを実行する必要はありません。

作成や確認で困ったときは

表示・状況主に確認すること
ERROR 1007が表示される同名のデータベースをすでに作成していないか
権限がないと表示される管理用のrootで接続しているか
ERROR 1064が表示されるSQLのスペル、空白、記号、指定の順序
USEでERROR 1049が表示されるデータベース名が正しいか、作成済みか
SHOW TABLESでERROR 1046が表示されるUSEでデータベースを選択したか
DATABASE()がNULLになる現在の接続で作業対象を選択したか
作成直後のSHOW TABLESがEmpty setになるまだテーブルを作成していなければ正常
文字セットや照合順序が見つからない名前の入力と、接続先が教材のMySQL 8.4環境かを確認する

入力間違いを直すときは、命令だけでなくinventory_dbの綴りも確認しましょう。

また、データベースの設定確認で期待と違う値が出た場合は、別のデータベースを選択していないか、以前作成した同名のデータベースを使っていないかを確認します。

次はテーブルと主キーを復習する

inventory_dbを作成し、作業対象として選択できたら、テーブルを用意する土台が整いました。

次の記事では、SQLite編で学んだテーブル・行・列と、主キーの役割を復習します。

商品をどのような項目で表し、一つの商品をどの値で識別するのかを確認してから、productsの作成へ進みましょう。

Follow me!