📘

【初学者向け】DockerでSQL学習環境を構築しよう -ChatGPTを活用してデータ作成

2024/03/11に公開

はじめに

初学者向けにDockerを使用してSQLの実行環境を構築していきます。この記事ではMySQLを使用します。
前提条件としてDockerがインストールされていることとします。

使用するもの

  • Docker(Docker Compose)
  • MySQL 8.0

環境

  • macOS Ventura 13.6(AppleシリコンM2)
  • Docker 24.0.6

Dockerを使用するメリット

Dockerはコンテナ技術を使用した仮想化ソフトです。
PC上に仮想化された環境を用意できるので、MySQLなどを直接PCにインストールする必要がなく、プロジェクトごとに環境を用意できます。

フォルダ構成

最終的なフォルダ構成は下記になります。

├── Dockerfile
├── compose.yaml
├── csv/  -ここにサンプルデータを入れる
│   ├── Users.csv
│   ├── Posts.csv
│   └── Comments.csv
└── sql/  -ここにSQLの実行ファイルを入れる
    ├── init.sql
    └── load_data.sql

データベース作成

今回はSNSのようなユーザーが投稿とコメントをできるような簡単なデータベースを用意します。

Users

カラム名 データ型 NULL キー 初期値 AUTO INCREMENT 外部キー
user_id INT NO PRIMARY YES
nickname VARCHAR(50) NO

Posts

カラム名 データ型 NULL キー 初期値 AUTO INCREMENT 外部キー
post_id INT NO PRIMARY YES
user_id INT NO FOREIGN Users(user_id)
content TEXT YES
post_date DATETIME NO

Comments

カラム名 データ型 NULL キー 初期値 AUTO INCREMENT 外部キー
comment_id INT NO PRIMARY YES
post_id INT NO FOREIGN Posts(post_id)
user_id INT NO FOREIGN Users(user_id)
content TEXT YES
comment_date DATETIME NO

SQLファイルの作成

データベースとテーブルを作成するためのSQLファイルを作成します。

init.sql
-- データベースの作成
CREATE DATABASE IF NOT EXISTS social_media_platform;

-- データベースを使用
USE social_media_platform;

-- Usersテーブルの作成
CREATE TABLE IF NOT EXISTS Users (
    user_id INT AUTO_INCREMENT PRIMARY KEY,
    nickname VARCHAR(50) NOT NULL
);

-- Postsテーブルの作成
CREATE TABLE IF NOT EXISTS Posts (
    post_id INT AUTO_INCREMENT PRIMARY KEY,
    user_id INT NOT NULL,
    content TEXT,
    post_date DATETIME NOT NULL,
    FOREIGN KEY (user_id) REFERENCES Users(user_id)
);

-- Commentsテーブルの作成
CREATE TABLE IF NOT EXISTS Comments (
    comment_id INT AUTO_INCREMENT PRIMARY KEY,
    post_id INT NOT NULL,
    user_id INT NOT NULL,
    content TEXT,
    comment_date DATETIME NOT NULL,
    FOREIGN KEY (post_id) REFERENCES Posts(post_id),
    FOREIGN KEY (user_id) REFERENCES Users(user_id)
);

次に後で作成するCSVデータを読み込むためのSQLファイルを用意します。

load_data.sql
USE social_media_platform;

-- Users.csvのデータをインポート
LOAD DATA INFILE '/var/lib/csv/Users.csv'
INTO TABLE Users
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n'
IGNORE 1 ROWS;

-- Posts.csvのデータをインポート
LOAD DATA INFILE '/var/lib/csv/Posts.csv'
INTO TABLE Posts
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n'
IGNORE 1 ROWS;

-- Comments.csvのデータをインポート
LOAD DATA INFILE '/var/lib/csv/Comments.csv'
INTO TABLE Comments
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n'
IGNORE 1 ROWS;

これらのSQLファイルを/sqlフォルダ内に配置します。

サンプルデータの作成

サンプルデータのCSVを作成するためにChatGPTを使用します。
下記のような質問を投げかけます。

CSVと指定することで下記のようにダウンロードできる形式で回答が返ってきます。

これを/csvフォルダ内に配置します。

MySQLコンテナのセットアップ

ファイルの準備

Dockerfileのみでセットアップもできますが、実務ではSQL単体で使うことはあまりないと思うので、compose.yamlとDockerfileを用意してdocker composeを使用してセットアップします。

Dockerfile
FROM mysql:8.0
compose.yaml
services:
  db:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: myproject #ここは任意の名前に変えてください
    command: --default-authentication-plugin=mysql_native_password
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: password 
      MYSQL_DATABASE: mydatabase
    volumes: #コンテナ内にファイルを同期します
      - ./sql/init.sql:/docker-entrypoint-initdb.d/init.sql
      - ./csv:/var/lib/csv
      - ./sql:/sql
    ports:
      - "3306:3306"

volumesの中の- ./sql/init.sql:/docker-entrypoint-initdb.d/init.sqlを記述することで、コンテナを立ち上げた際に先ほど配置したinit.sqlファイルが実行されてテーブルが作成されます。

ターミナルでコマンド実行

まずはイメージを作成してコンテナを立ち上げます。

docker compose up -d

次にコンテナ内に入り、MySQLに接続します。

docker exec -it db_internet_tv mysql -u root -p

Enter password:と表示されるので、パスワードを入力します。
compose.yamlのMYSQL_ROOT_PASSWORD:で記述した値なので、ここではpasswordと入力します。
下記のように表示されたら接続OKです。

mysql>

次にCSVのデータをMySQLに取り込みます。

source /sql/load_data.sql

ターミナル上でなにかクエリを実行してみて結果が返ってきたら取り込みOKです。

(例)

mysql> SELECT COUNT(*) FROM Comments;
+----------+
| COUNT(*) |
+----------+
|   100000 |
+----------+
1 row in set (0.01 sec)

おまけ

上記のようにターミナルからMySQLに接続した状態で、ターミナル上でSQLを書いて実行しても良いですが、見にくく管理もしにくいと思うので、その時はSQLファイルを別途用意してそこに記述して実行することをおすすめします。

├── Dockerfile
├── compose.yaml
├── csv/
│   ├── Users.csv
│   ├── Posts.csv
│   └── Comments.csv
└── sql/
    ├── init.sql
    ├── load_data.sql
    └── test.sql  -ここに追加
source /sql/test.sql

以上

Discussion