C言語+MySQL入門|MySQL Serverの働き

C言語+MySQL入門|MySQL Serverの働き

第2章では、Windowsに開発環境を整え、C言語で作成したhello.cをコンパイルして実行しました。また、MySQL Serverをインストールし、MySQLクライアントから接続して、サーバーが応答することも確認しました。

第3章では、そのMySQL Serverに在庫管理用のデータベースやテーブルを作成していきます。

具体的な操作へ進む前に、接続した先でMySQL Serverがどのような仕事をしているのかを整理しましょう。

この記事では、次の内容を扱います。

  • MySQL Serverとクライアントの役割の違い
  • クライアントからの接続を受け付ける仕組み
  • 接続するユーザーの認証と、操作権限の確認
  • SQLを受け取って処理し、結果を返す流れ
  • データの保存と、アプリを終了した後の扱い
  • 在庫管理アプリ側で用意する処理

この記事の到達点は、MySQL Serverが接続・認証・SQL実行・データ保存を担当し、クライアントへ処理結果を返すことを説明できるようになることです。

MySQL Serverはデータ管理を担当するプログラム

MySQL Serverは、クライアントからの要求を受け付け、データベースを管理するプログラムです。

第1章で学んだとおり、ここでいうサーバーは、必ずしも専用の大型コンピューターを意味しません。今回の学習では、自分のWindows PC上でMySQL Serverを動かしています。

MySQL Serverは、起動するとクライアントからの接続を待ち受け、接続したクライアントに代わってデータベースへのアクセスを管理します。

在庫管理アプリで考えると、主に次のような仕事を担当します。

MySQL Serverの仕事在庫管理アプリでの例
接続を受け付ける商品を管理するアプリからの接続要求を受け取る
ユーザーを認証する接続に使うアカウントと認証情報を確認する
操作権限を確認する商品の取得や登録が許可されているかを確認する
SQLを実行する商品を検索したり、在庫数を変更したりする
データを保存・管理する商品情報や入出庫履歴を保持する
結果を返す取得した商品情報や、処理の成功・失敗を伝える

たとえば、アプリで商品一覧を表示するとき、MySQL Serverがウィンドウや表の見た目まで作るわけではありません。

MySQL Serverは、要求された商品情報を取得して返します。その情報を画面に並べるのは、クライアント側の仕事です。

データを処理する仕事と、利用者へ見せる仕事を分けて考えることが、仕組みを理解する出発点になります。

MySQLクライアントとMySQL Serverを区別しよう

第2章では、コマンドプロンプトからmysqlを起動しました。

このmysqlは、MySQL Serverに接続してSQLを送るためのクライアントです。SQLを入力し、返された結果を確認するために使います。

名前が似ていますが、Windows上の実行ファイルには次の違いがあります。

名前役割今回の使い方
mysql.exeコマンドラインクライアントSQLを手入力し、結果を確認する
mysqld.exeMySQL Serverの本体接続やSQLを受け付け、データを管理する
後で作成するCアプリ自作のクライアント商品登録や一覧表示などの操作を提供する

第3章では、主にmysqlクライアントを使ってデータベースを操作します。

第4章以降では、CプログラムからMariaDB Connector/Cを利用して、同じMySQL Serverへ接続します。

接続するプログラムが変わっても、データを管理する中心はMySQL Serverです。

図1:クライアントとMySQL Serverの役割分担

この図から分かること

MySQLクライアントとCアプリは、どちらもMySQL Serverへ要求を送る側です。

MySQL Serverは、その要求を受け付け、権限を確認し、データの検索や更新を行います。クライアントは返された結果を受け取り、それぞれの方法で表示します。

同じWindows PCの中で動いていても、クライアントとサーバーは別々のプログラムです。

Windowsサービスとして接続を待ち受ける

今回の環境では、MySQL ServerをMySQL84という名前のWindowsサービスとして登録しています。

Windowsサービスは、通常のアプリのような操作用ウィンドウを開かずに、バックグラウンドで動作できます。MySQL Serverも、Windowsサービスとして起動・停止を管理できます。dev.mysql.com

第2章の設定では、Windowsの起動に合わせてサービスが自動的に起動する構成にしました。

ただし、自動起動に設定していても、設定やファイルの権限などに問題があると、起動に失敗する場合があります。接続できないときは、サービスが実行中かどうかを確認することが大切です。

クライアントを起動することと、サーバーを起動することは別

mysqlクライアントを起動しただけで、停止中のMySQL Serverが自動的に起動するわけではありません。

反対に、mysqlクライアントを終了しても、通常はMySQL Serverまで停止しません。

操作起こること
MySQL84を起動するMySQL Serverが動き、接続を受け付ける準備をする
mysqlクライアントから接続する起動済みのサーバーへ接続を要求する
mysqlクライアントでexitを実行するそのクライアントの接続と実行を終了する
MySQL84を停止するサーバーが停止し、クライアントから利用できなくなる

複数のクライアントが接続している場合、一つのクライアントを終了しても、ほかのクライアントの接続まで終了するわけではありません。

接続先とポートを指定してサーバーへ向かう

今回の学習環境では、次の接続先を使います。

項目今回の値意味
接続先127.0.0.1クライアントを動かしているPC自身
ポート3306今回のMySQL Serverが通常の接続を受け付ける窓口
接続方式TCP/IP同じPC内でも通信を使って接続する

ここで指定するのは、データファイルの保存場所ではありません。

クライアントは、127.0.0.1の3306番ポートで待ち受けるMySQL Serverへ接続します。その後、利用するデータベースや実行する操作を指定します。

接続時にはユーザーを認証する

接続要求が届くと、MySQL Serverは接続するユーザーを確認します。

今回の教材では、MySQLのユーザー名と、そのユーザーに設定したパスワードを使って接続します。

MySQLのアカウントは、ユーザー名だけでなく、接続元との組み合わせで扱われます。また、認証情報やアカウントの状態などの確認に失敗すると、接続は拒否されます。

このように、接続しようとしている相手を確認する仕組みを認証と呼びます。

Windowsのユーザーとは別に考える

Windowsへサインインするときのユーザーと、MySQLへ接続するときのユーザーは別のものです。

今回の環境には、次のように異なる役割のアカウントが登場します。

アカウント担当すること
WindowsへサインインするユーザーVS Codeやターミナルなどを操作する
MySQLサービスの実行アカウントWindows上でサーバーを動かし、必要なファイルへアクセスする
MySQLのrootMySQL内のデータベースやユーザーなどを管理する
後で作る学習用の専用ユーザーCアプリから接続し、許可されたデータ操作を行う

第2章で登場したNetworkServiceは、Windows側でサービスを実行するためのアカウントです。

MySQLへログインするときに指定するrootとは、役割も管理される場所も異なります。

接続後も操作の権限を確認する

認証に成功して接続できたからといって、すべての操作が許可されるわけではありません。

MySQL Serverは、接続後に送られた要求について、そのユーザーに必要な権限があるかを確認します。dev.mysql.com

たとえば、商品一覧を読むことは許可されていても、商品を削除することは許可されていないユーザーを用意できます。

確認する段階確認すること例
認証接続するアカウントとして認められるかユーザー名とパスワードなどを確認する
操作権限の確認要求された操作を実行してよいか商品の取得や削除が許可されているかを確認する

接続できることと、目的のSQLを実行できることは、分けて確認します。

この違いが分かると、ログイン後にエラーが出た場合も、すぐにパスワードの問題だと考えずに済みます。

第3章の後半では、Cアプリで使う学習用の専用ユーザーを作成し、必要な操作ができることを確認します。

図2:接続時の認証と操作時の権限確認

この図から分かること

接続時には、MySQL Serverがアカウントや認証情報を確認します。

接続後には、送られたSQLを実行する権限があるかを確認します。認証と操作権限の確認は、異なる目的を持つ仕組みです。

商品一覧を表示できても、商品の登録や削除まで許可されているとは限りません。

SQLを受け取り、要求された処理を実行する

接続できたクライアントは、MySQL ServerへSQLを送ります。

SQLには、どのデータを取得したいか、どの行を追加・変更・削除したいかといった操作を記述します。

在庫管理アプリでは、主に次の命令を使っていきます。

命令行う操作在庫管理での例
SELECTデータを取得する商品名や在庫数を取得する
INSERT新しい行を追加する新しい商品を登録する
UPDATE既存の行を変更する商品の単価や在庫数を変更する
DELETE既存の行を削除する指定した商品を削除する

MySQL Serverは、SQLの文法や、対象のテーブル・列、必要な権限などを確認し、実行できる要求を処理します。

テーブルに設定された制約も、データを追加・変更するときの確認に関係します。たとえば、主キーが重複するデータを登録しようとすると、エラーになります。

商品を検索する流れを考えてみよう

ここでは、今後作成するproductsに、次のような商品が登録されている場面を考えます。

まだテーブルを作成する操作は行いません。処理の流れを理解するための例です。

商品ID商品名単価在庫数
101ノート18024
102ボールペン12050

商品IDが101の商品の名前と在庫数を調べるときは、次のように進みます。

  1. クライアントが、商品IDを条件にした検索SQLを送る。
  2. MySQL Serverが要求を確認する。
  3. MySQL Serverが条件に合う商品データを取得する。
  4. MySQL Serverが商品名と在庫数を返す。
  5. クライアントが受け取った値を画面へ表示する。

この例でクライアントが受け取るデータは、次のようになります。

商品名在庫数
ノート24

mysqlクライアントなら、取得した値を文字の表として表示できます。

後で作るCアプリなら、受け取った値をprintfで表示したり、GTK 4の画面に並べたりできます。

同じデータでも、表示方法はクライアント側で決められます。

検索と更新では返される情報が異なる

すべてのSQLが、商品の一覧のような行と列を返すわけではありません。

処理クライアントが受け取って確認する主な情報
商品の検索条件に合う行と列の値
商品の登録・変更・削除成功・失敗や処理に関係する件数など
SQLの実行に失敗エラー番号やエラーメッセージなど

また、検索結果が0件であることと、SQLの実行に失敗したことも違います。

商品IDが存在しなければ、正常に検索できても商品は見つかりません。一方、テーブル名を間違えていれば、検索そのものが失敗します。

Cプログラムを作るときは、この違いを確認して、利用者へ適切なメッセージを表示する必要があります。

データはMySQL Serverが管理する場所へ保存する

これから作る在庫管理用のデータベースとテーブルには、次の名前を使います。

名前役割
inventory_db在庫管理用のデータベース
products商品情報を保存するテーブル
stock_history入庫・出庫の履歴を保存するテーブル

MySQL Serverは、データディレクトリなどのサーバー側の保存領域を管理します。クライアントは、通常のデータ操作でその保存ファイルを直接編集せず、SQLを通して読み書きを要求します。The MySQL Server

ここで、自分の作業フォルダとの違いを確認しておきましょう。

保存するもの保存場所の考え方
C言語のソースコードC:\c-mysqlの章別ディレクトリへ保存する
作成した実行ファイル対応する章のディレクトリへ保存する
SQLを記述したファイル第3章ではchap03へ保存する
SQLによって登録した商品データMySQL Serverが管理する保存領域へ保存される

chap03にSQLファイルを保存しても、それだけでMySQLのデータが変わるわけではありません。

SQLファイルは、実行したい命令を記録したテキストです。その内容をサーバーへ送り、正常に実行されることで、データベースの作成やデータの登録が行われます。

アプリを終了しても、確定したデータは残る

Cプログラムの変数は、プログラムが動いている間の値を保持します。

一方、通常の永続テーブルへ登録し、確定したデータは、クライアントを終了しても残ります。

たとえば、次のような使い方ができます。

  1. アプリから商品を登録し、変更を確定する。
  2. アプリを終了する。
  3. 後でアプリを起動し、MySQL Serverへ接続する。
  4. 商品一覧を取得し、前に登録した商品を確認する。

ただし、確定していない変更まで、切断によって自動的に保存されると考えないようにしましょう。処理を確定・取り消しする仕組みは、第8章のトランザクションで詳しく扱います。

図3:作業用ファイルとサーバーが保存するデータ

この図から分かること

C:\c-mysqlに保存するソースコードやSQLファイルと、MySQL Serverが管理する商品データは別のものです。

SQLファイルには命令を保存します。その命令をサーバーへ送り、実行することで、データベースの内容を操作できます。

また、クライアントの終了と、登録済みデータの削除は別の操作です。確定した商品データは、後から再接続して利用できます。

複数の接続からの操作も支える

在庫管理アプリでは、事務所で商品を確認しながら、倉庫で出庫を登録することも考えられます。

MySQL Serverは、複数のクライアントからの接続を受け付けます。ただし、同じデータを複数の接続から変更するときは、処理が食い違わないように調整する仕組みが必要です。

MySQLの標準的なストレージエンジンであるInnoDBには、トランザクションや行単位のロックなど、データの整合性や同時操作を支える機能があります。ストレージエンジンは、サーバー内部でテーブルの読み書きなどを担当する仕組みです。

今は、細かな内部構造まで覚えなくても大丈夫です。

ただし、MySQL Serverを使えば、在庫管理のルールまで自動的に完成するわけではないことは押さえておきましょう。

たとえば、在庫が5個の商品に対し、二つのアプリが同時に4個ずつ出庫しようとする場面を考えます。

それぞれのアプリが最初に在庫数を読んで確認するだけでは、両方が出庫できると判断してしまう可能性があります。

このような場合に備えて、更新時の条件や、複数のSQLをまとめる方法を設計します。具体的な対処は第8章で学びます。

MySQL Serverとアプリで担当する仕事を分ける

MySQL Serverには、データを管理するためのさまざまな機能があります。

それらを利用しながら、在庫管理アプリとしての動作を組み立てるのが、Cプログラム側の仕事です。

やりたいこと主にアプリ側で用意する処理サーバー側で利用する処理
商品を登録する入力を受け取り、内容を確認する登録SQLを実行し、制約を確認する
商品一覧を表示する取得した値を見やすく並べる条件に合う商品データを取得する
商品を削除する対象を確認し、必要に応じて利用者へ確認する削除SQLを実行し、関連する制約を確認する
在庫を出庫する商品IDと数量を受け取り、処理を組み立てる条件付き更新やトランザクションを実行する
エラーを知らせる利用者に分かる説明を表示するエラー番号や詳細を返す

たとえば、商品名の入力欄が空かどうかを画面で確認する処理と、テーブルの制約を使って不適切なデータを拒否する処理は、両方を組み合わせて利用できます。

また、別のアプリが商品情報を変更しても、すでに表示している一覧が自動的に書き換わるとは限りません。必要なタイミングでデータを取得し直し、画面へ反映する処理もアプリ側に用意します。

エラーが起きた段階から確認しよう

MySQLを使うときは、どの段階で処理が止まったかを考えると、確認する場所を絞りやすくなります。

起きていること主に確認する内容
サーバーへ接続できないMySQL84の状態、接続先、ポート
認証で拒否されるMySQLのユーザー名、パスワード、接続元、アカウントの状態
接続できるが操作を拒否される対象のデータベースやテーブルに対する権限
SQLの文法エラーが出る命令の書き方、記号、指定の順序
テーブルや列が見つからない選択しているデータベース、テーブル名、列名
データの登録や変更が拒否される主キーの重複、外部キーなどの制約、値の内容
検索は成功するが商品が表示されない保存済みデータ、検索条件、アプリの表示処理

接続の問題とSQLの問題を分けるだけでも、調べる順序が分かりやすくなります。

たとえば、サーバーに接続できていない段階で、商品の検索条件を直しても解決しません。反対に、SQLのテーブル名を間違えている場合、サーバーを再起動しても名前の間違いは直りません。

表示された内容を読み、接続・認証・SQL実行・結果表示のどこまで進んだのかを確認していきましょう。

次はMySQLへログインする

次の記事では、管理作業用のrootアカウントでMySQL Serverへ接続します。

第2章で使った127.0.0.1と3306を接続先に指定し、学習用に設定したパスワードを使います。パスワードを対話入力する方法と、コマンドへ直接指定する方法の両方を確認します。

接続後は、mysql>というプロンプトの読み方や、SQLの入力・終了の方法を学びます。そこから、在庫管理アプリで使うデータベースを作成する準備へ進みましょう。

Follow me!