🍭

M1 MacでDocker+MySQLの環境をつくり遊ぼう

2022/03/13に公開

M1 MacでDocker+MySQLの環境をつくる

以下の記事を参考にしてMySQLの練習をしようと思ったのでその記録です。こういうのを1から自分でやろうとすると大変なので非常にありがたいです。
https://zenn.dev/takuho/articles/efc40344f3122e

指示通りに進めると以下のエラーが発生。

Creating network "mysql-docker-main_default" with the default driver
Pulling mysql (mysql:latest)...
latest: Pulling from library/mysql
ERROR: no matching manifest for linux/arm64/v8 in the manifest list entries

調べてみると、M1 Macを使っている場合には起きるらしい。対処法は各所に書かれているので、docker-compose.ymlを更新(platform: linux/x86_64を追加しています)

version: "3"

services:
  mysql:
    platform: linux/x86_64
    image: mysql:latest
    container_name: mysql_container
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: sakila
      TZ: "Asia/Tokyo"
    volumes:
      - ./my.cnf:/etc/mysql/conf.d/my.cnf
      - ./init:/docker-entrypoint-initdb.d
    ports:
      - "3306:3306"

これで無事に動きました。

環境整えても遊ばないと意味がないので、遊んでみた

これで無事に遊べそうです。というわけで、以下の問題を解きました。初学者には難しいかもとか思いました。
https://qiita.com/a-pompom/items/0e80fbaeed7657e7b474

問題1Nickさんが登場する映画

select film.title from film

inner join film_actor
on film.film_id = film_actor.film_id

where film_actor.actor_id in (
select actor.actor_id from actor
where actor.first_name = 'Nick'
)

問題2日本に住んでいるお客さんの名前

select customer.first_name, customer.last_name, country.country from customer

inner join address
on customer.address_id = address.address_id

inner join city
on address.city_id = city.city_id

inner join country
on city.country_id = country.country_id

where country.country = 'Japan'
select customer.first_name, customer.last_name from customer
where customer.address_id in (
	select address.address_id from address
	where address.city_id in (
		select city.city_id from city
		where city.country_id in (
			select country.country_id from country
			where country.country = 'Japan'
		)
	)
)

問題32005年5月26日にレンタルされた映画のカテゴリ別のレンタル回数ランキング

select category.name, count(*) as rental_count from category

inner join film_category
on category.category_id = film_category.category_id

inner join inventory
on film_category.film_id = inventory.film_id

inner join rental
on inventory.inventory_id = rental.inventory_id

where DATE_FORMAT(rental.rental_date, '%Y%m%d') = '20050526'

group by category.name
order by rental_count desc

簡単な問題から取り組めるように課題を考えてみた

以下は自分で考えた問題です。以下の本を参考にしつつ、徐々にレベルが上がるようにしています。
https://www.amazon.co.jp/SQL-第2版-ゼロからはじめるデータベース操作-ミック-ebook/dp/B01HD5VWWO/ref=sr_1_5?__mk_ja_JP=カタカナ&crid=1T2X61AELK1O&keywords=SQL&qid=1647259213&sprefix=sql%2Caps%2C200&sr=8-5

問題A-1 customerのテーブルから名前(first name, last name)とEmailを取得する

select first_name, last_name, email
from customer

問題A-2 actorのテーブルから名前を取得し、列に別名をつける

last_nameを姓、first_nameを名、にする

select last_name as "姓", first_name as "名"
from actor

問題A-3 customerのテーブルからfirst_nameの重複を除いて一覧を取得する

select distinct(first_name)
from customer

問題A-4 actorのfirst_nameが"Nick"のactorテーブル一覧を取得する

select *
from actor
where first_name = "Nick"

問題B-1 paymentとcustomerのテーブルをcustomer_idでつなぐ

select *
from customer

inner join payment
on customer.customer_id = payment.customer_id

追加課題:left join, right join, outer join, cross joinについても調べてみる

問題B-2 rentalテーブルから値段の高い順に並び替える

ToDo

問題B-3 customerテーブルの名前を性名の昇順にならべる

ToDo

問題C-1 お客さまの名前と、お客さまのトータルの支払い金額を、金額が高い順に並べる。

select
  concat(customer.first_name, ' ', customer.last_name) customer_name,
  sum(payment.amount) total_payment
from
  payment
inner join
  customer
on
  payment.customer_id = customer.customer_id

group by customer_name
order by total_payment desc

問題C-2 フィルムのタイトルと、タイトルごとのトータル支払い金額を、金額が高い順に並べる。

select
  film.title title,
  sum(payment.amount) total_payment
from
  payment

inner join
  rental
on
  payment.rental_id = rental.rental_id

inner join
  inventory
on
  rental.inventory_id = inventory.inventory_id
  
inner join
  film
on inventory.film_id = film.film_id

group by title
order by total_payment desc

問題C-3 1回あたりの貸し出し単価が高いfilm順に並べる

ToDo

最後に

ToDoは問題を考えただけで特に手をつけていないので、思い立った時にやります。
良さそうな問題が思いついた時にアップデートしていきます。
面白そうな問題や、効率の良い書き方などあればお知らせください。

補足

そもそも、SQLを書きたいという場合にはGoogleのBigQueryを使うというのも選択肢としてありだと思います。トライアル期間であれば無料で自由に使えますし、Cloudサービスについて知るきっかけにもなり個人的にはこちらでも良いと思っています。

Discussion