主夫ときどきプログラマ

データベース、Webエンジニアリング、コミュニティ、etc

MySQLのSakila Sample Database を使ってみよう

この記事は「MySQL Casual Advent Calendar 2018」9日目の記事です。

qiita.com

21日目の記事も書いています。

masayuki14.hatenablog.com

Sakilaとは

MySQLから公式のサンプルデータベースが公開されています。 MySQL :: Sakila Sample Database その名も Sakila !! イルカのマスコットの名前が冠されています。

Sakilaデータベースは書籍やチュートリアルなどのサンプルとして使えるような標準のデータベースを提供しているので、MySQL8.0の新機能を試してみるなどの用途に最適です。 私も新機能の検証や確認などのちょっとした目的のためにサンプルとして使っています。 通常のテーブルに加え、ビュー、ストアドプロシージャ、トリガなども含まれているので、これらの使い方を具体的なコードとして参照することもでき、学習教材として使うこともできます。

SakilaにはレンタルDVD店のシステムをモデルとしたデータベースが構成されています。 顧客の情報やレンタルの履歴、映画のマスタ情報などが登録されています。

Sakilaデータベースのインストール

Sakilaデータベースは MySQL :: Other MySQL Documentation からダウンロードできます。 Example Databases の sakila database からダウンロードでき、形式は TGZzip から選択できます。

$ wget 'http://downloads.mysql.com/docs/sakila-db.zip'
$ unzip sakila-db.zip

解凍すると sakila-db/ ディレクトリが展開されます。テーブルなどのデータベース構成用のSQLsakila-schema.sql に記されています。エディタで見てみるとテーブルの他にビュー、プロシージャ、ファンクションを作成するSQLも含まれています。 その後 sakila-data.sql を読み込んでデータを登録します。

mysql> source sakila-db/sakila-schema.sql;
mysql> source sakila-db/sakila-datasql;

一連の作業をワンライナーで実行することもできます。

$ mysql -u root -p < <( \
    wget 'http://downloads.mysql.com/docs/sakila-db.zip' \
    && unzip -o sakila-db.zip 1>/dev/null \
    && cat sakila-db/sakila-schema.sql sakila-db/sakila-data.sql \
  )

※表示の都合上複数行で表示しています。

正しくインストールできている場合は次のようにテーブルが表示されます。

mysql> use sakila;
Database changed
mysql> show tables;
+----------------------------+
| Tables_in_sakila           |
+----------------------------+
| actor                      |
| actor_info                 |
| address                    |
| category                   |
| city                       |
| country                    |
| customer                   |
| customer_list              |
| film                       |
| film_actor                 |
| film_category              |
| film_list                  |
| film_text                  |
| inventory                  |
| language                   |
| nicer_but_slower_film_list |
| payment                    |
| rental                     |
| sales_by_film_category     |
| sales_by_store             |
| staff                      |
| staff_list                 |
| store                      |
+----------------------------+
23 rows in set (0.00 sec)

show tables ではテーブルに加えビューも一覧に表示されるので、ビューのみを表示したい場合は information_schema を参照する必要があります。

mysql> select table_name from information_schema.views where table_schema = 'sakila';
+----------------------------+
| TABLE_NAME                 |
+----------------------------+
| actor_info                 |
| customer_list              |
| film_list                  |
| nicer_but_slower_film_list |
| sales_by_film_category     |
| sales_by_store             |
| staff_list                 |
+----------------------------+
7 rows in set (0.00 sec)

7つのビューが定義されているのがわかります。

MySQL Workbench も使える

Sakilaに格納されているテーブルのリレーションについては、sakila.mwbMySQL Workbenchで開くことで参照できます。

f:id:masayuki14:20181207120709p:plain
mysql workbench

それぞれのテーブルやビューがどういう設計になっているかもドキュメントが用意されています。

MySQL :: Sakila Sample Database :: 5.1 Tables
MySQL :: Sakila Sample Database :: 5.2 Views
MySQL :: Sakila Sample Database :: 5.3 Stored Procedures
MySQL :: Sakila Sample Database :: 5.4 Stored Functions
MySQL :: Sakila Sample Database :: 5.5 Triggers

データベースの利用例とちょっとした解説

データベースの利用例についてもサンプルが公開されています。
MySQL :: Sakila Sample Database :: 6 Usage Examples

DVDを借りる

customer_id=3Linda Williamsさんが、inventory_id=10Ace Goldfingerをレンタルするケースを考えます。対応するのは staff_id=1Mike Hillyerさんです。

在庫の確認

DVDをレンタルするためにはまず指定された商品の在庫を確認する必要があります。 在庫の有無の確認は investory_in_stock(10) のようにファンクションに在庫のID inventory.inventory_id を与えることで確認できます(1or0が返ります)。

inventory_in_stock() では rental テーブルから貸出中の情報を参照し在庫の有無を判断しています。 rental テーブルにレコードが存在し rental.return_date is null のレコードが貸出中となります。

mysql> select inventory_in_stock(10);
+------------------------+
| inventory_in_stock(10) |
+------------------------+
|                      1 |
+------------------------+
1 row in set (0.00 sec)

貸出を登録

貸出は rental テーブルへ行を挿入します。

mysql> insert into rental 
       (rental_date, inventory_id, customer_id, staff_id) 
       values(now(), 10, 3, 1);
Query OK, 1 row affected (0.20 sec)

支払いの登録

get_customer_balance() ファンクションで支払い金額を算出します。 payment テーブルに登録されていない未払いの金額があればそれも加算されます。

mysql> select @balance := get_customer_balance(3, now());
+--------------------------------------------+
| @balance := get_customer_balance(3, now()) |
+--------------------------------------------+
|                                       4.99 |
+--------------------------------------------+
1 row in set (0.00 sec)

支払いが済んだら金額を payment テーブルに登録します。

mysql> insert into payment 
       (customer_id, staff_id, rental_id, amount,  payment_date)
       values(3, 1, last_insert_id(), @balance, now()) ;
Query OK, 1 row affected (0.02 sec)

mysql> select * from payment;

最後に

これまではちょっとしたSQLを実行するにもサンプルのデータベースを自分で作ってデータを登録したりしていましたが、Sakilaを知ってからは積極的に使うようになりました。 MySQL8.0ではCTEやWindow関数などの新機能が追加されているので、Sakilaを使ってSQLを書いてみたいと思います。

データベースのバックアップについて知っておきたい基本のはなし

バックアップとは

データベースシステムの障害や操作ミスなどに備えて、データの複製を作成することです。 対象はアプリケーションに使われているデータのみの場合や、データベースのユーザーや権限などの定義データ、データファイル、定義ファイル、トランザクションのログファイルなど多岐に渡り、システム要件に合わせてバックアップ対象を検討することが必要です。

データベース管理者にとって、データベースに格納されたデータをいかに守るかは重要なテーマで、バックアップはデータベース運用において重要な仕事の一つです。 ダウンタイムやパフォーマンスの低下を起こさないためにもバックアップを最初から計画し設計しておく必要があります。

バックアップが必要な理由

システムのクラッシュ、ハードウェアの障害、誤ったデータ操作による削除などの問題が発生した場合に備え、データを復旧して元に戻せるようにデータベースをバックアップすることが重要です。 その代表的な理由は以下のようなものです。

障害からの復旧

バックアップの最も一般的な理由は障害から復旧することです。障害とは何か、データの重要な部分が壊れたり利用できなくなったりすることを指しています。

障害の例

  • ハードウェアの異常
  • ソフトウェアの異常
  • データの誤った削除
  • サーバーの故障

しかし、この動機は実際には他の理由ほど重要でないことが多くなっています。AWSGCPといったクラウド環境を利用することが多い現代では、物理サーバーを運用することに比べ、障害が発生することが少なくなっています。

データの分析、調査、チューニング

サービスを運用していると、過去のある時点に戻ってデータベースのテーブルやレコードがどのような状態であったかを分析したいことがあります。 バックアップがあれば過去の状態を調べることが可能となります。適切なデータをテストサーバーに戻してプロダクション環境に影響与えずデータを分析、調査することができるようになります。パフォーマンスに影響与えるような遅いクエリを実行したい時や、遅いクエリをチューニングしたい時も同様に役に立ちます。

また、開発の過程でテストを実施することにも利用できます。

レプリケーションの実施

MySQLではデータを別のサーバーに転送したりレプリケーションのスレーブサーバーをセットアップするために使用することもできます。

突発的なことへの対応

サービスにとって重要な顧客が誤って(または自分の意志で)何らかのデータを削除したけれど、それをもとに戻したくなることは少なくありません。また、訴訟や法的な要件により過去のある時点のデータベースの状態を知る必要が生じることもあります。

バックアップからのリカバリ

リカバリーが大切

バックアップが必要な理由を述べてきましたが、バックアップ以上に大切なのがリカバリーです。優れたバックアップシステムがあっとしても、リカバリーが機能していないとそれは意味がありません。リカバリーシステムがスムーズに機能することは、バックアップシステムを構築するよりも大切なことなのです。 しかし、リカバリーよりもバックアップが優先されてしまうには以下のような背景があります。

  • 手順としてはバックアップが先です。バックアップがないとリカバリーは実施できません。そのためバックアップの作成を優先してしまいます。しかしリカバリーの要件、目的を達成するためにバックアップは存在します。まずはリカバリーの要件を洗い出さなければなりません。
  • バックアップは日常的な作業になりえます。バックアッププロセスの自動化や調整は日々の作業で最適化されていきます。しかしリカバリー作業は日常的に発生しません。意図的にリカバリープロセスを調整していかないと、スムーズなリカバリーシステムを構築することはできません。
  • バックアップは日常的な状況で行われますが、リカバリーは危機的状況に行われます。それも突発的に発生します。
  • バックアップは誰でもできる作業にしやすいですが、リカバリーは属人性が高くなる傾向にあります。日々のトレーニングや仕組みによって、リカバリー作業を複数のスタッフが行えるようにしておく必要があります。

障害が発生した場合に備えてバックアップを作成しますが、いざ障害が発生した時にバックアップから障害発生の直前の状態にもどすためにはリカバリーについてよく知る必要があります。

リカバリーの要件

リカバリーについて検討するためには、まずリカバリー要件を定義することが大切です。例えば次のようなことを検討します。

  • データの損失がどの程度許容できるか。Point-In-Time リカバリは必要か、それとも標準バックアップ以降に発生した作業が失われても容認できるか。
  • リカバリーはどれくらい素早く実施できるか。ダウンタイムがどれくらいなら許容できるか。
  • アプリケーションとユーザーが受け入れることができるのはどのような影響か(一部の機能が使えない、など)。また、そのよう状況でも引き続き稼働するには、どうすればよいか。
  • リカバリが必要なのはなにか。サーバー全体、1つのデータベース、1つのテーブル、など。

心情としてはいかなる損失も許容せず、迅速なリカバリーを実施したいところですが、人的リソースやバックアップにかかる費用などを踏まえ現実的な選択をすることが大切です。

リカバリーに必要なもの

バックアップはある時点でのデータベースの状態なので、障害発生の直前までにはズレがあります。 そのズレを埋めるために必要なのが更新ログで、この2つを組み合わせてバックアップ時点以降の任意の状態にデータベースを復旧することが可能となります。 一般的にロールフォワードによるリカバリーと呼ばれます。

バックアップの種類

バックアップにはデータベースサーバーの状態や、バックアップデータのフォーマットなどで分類できる様々な方法があります。

データベースサーバーの状態による分類

ホットバックアップ

ホットバックアップはデータベースサーバーを停止させずにバックアップを行う方法です。 データが多い場合はバックアップに時間がかかる為、バックアップ作成中にデータが更新される可能性があります。 バックアップ中にデータの整合性を失うような変化が行われないように適切にロックを行うよう注意する必要があります。 オンラインバックアップとも呼ばれます。

コールドバックアップ

コールドバックアップはデータベースサーバーを停止してバックアップを行う方法です。 サーバーが停止しているのでデータファイルをそのままコピーすることが可能なので、最も速く簡潔なバックアップの方法の1つです。 ただしサーバーを停止する必要があるためあらかじめ予定されたメンテナンス期間など限られた場面だけで利用可能です。

バックアップ中にサーバーが使用できないためクライアントが悪影響受ける可能性があります。そのためオフラインにすることができるレプリケーションサーバーから取得することでこれを回避することもできます。

オフラインバックアップとも呼ばれます。

バックアップデータのフォーマットによる分類

物理バックアップ

物理バックアップはサーバーのデータファイル自体をバックアップする方法です。データベースの内容を格納するディレクトリとファイルのコピーで構成され、OSのファイルコピー機能を使って実施することができます。バックアップにはログや構成ファイルなどの関連ファイルも含めることができます。

利点としては最小限のサイズで取得できる点と、バックアップとリストアにかかる時間が最も短くできるという点です。一方欠点はバックアップやリストアする単位はツールに依存するため、自由度が低い場合があります。また、バージョンの異なるサーバーやマシンの間では互換性が取れない場合があります。

このバックアップは問題が発生した場合に短時間で回復することができるので、大規模で重要なデータベースに適しています。

論理バックアップ

データベースからデータを抜き出してバックアップする方法です。データベースに格納されているテーブルのデータやテーブルを構築するためのSQLを出力します。 SQL文を用いて記述されるためバージョン間の互換性が高く、他のRDBMSにも移植することができます。また、バックアップ内容をテキストで出力するので人間が見て判断することができます。

一方、物理バックアップに比べサイズが大きくなりやすく、またリストアにかかる時間がとても大きくなってしまいます。 リストア時にテキストデータをバイナリデータに変換したり、インデックスの作成等の処理を行う必要があるためサーバーにかかる負荷も大きくなります。

バックアップの取得方式による分類

フルバックアップ

ある時点のデータベースの内容をすべてを対象としたバックアップです。すべてが対象となるためバックアップにかかる時間が長くなりデータサイズも大きくなりますが、リストアの処理が単純になります。 安全性としては最も高くなりますが、データの増加に比例してバックアップにかかる時間が長くなります。

差分バックアップ

直前のフルバックアップ以降に更新されたデータのみのバックアップです。更新されたデータのみを対象にするため、バックアップにかかる時間が短くなり、データのサイズも小さくなります。 更新された部分のみが対象となるため、単体だけではデータをリカバリーすることはできません。リストア時には直前のフルバックアップと合わせて行う必要があり手順が複雑になる傾向にあります。

増分バックアップ

直前のバックアップ(フルバックアップとは限らない)以降に更新されたデータのみのバックアップです。 バックアップにかかる時間も短くなり、データサイズも小さくなりますが、差分バックアップよりもリストア作業が複雑になります。

最後に

次の技術書典で、MySQLのバックアップについての本を書きたいなぁと思っていますが、本になるほどの分量ってどれくらいなんだろう。 バックアップについての一般論と具体的な方法をまとめたいと思っています。パートごとに随時ブログ記事にしていきます。

「こういう内容を知りたい」とかあれば何かしらの方法で教えてください。 あと何かしらの方法でレビューしてくれる人を募集します。 何でもいいので関わってくれた人には、完成の暁に出来上がった本を贈りたいと思います。

とにかく御託並べてないで書けっていうはなし。

APIから取得したJSONをとりあえずMySQL8.0に入れてJSON_TABLE()でどうにかする

f:id:masayuki14:20181017152938p:plain

MySQL8.0から追加された機能の一つに JSON_TABLE() 関数がある。これを使うとJSON型のデータを表形式に出力することができる。 MySQLをドキュメントストアとして使う場合、この関数を使用することで別のテーブルとJOINできるようになるので重要な関数だ。 今回はこれを使ってJSONデータをCSVに変換する簡単な方法を紹介する。

どうしてこうなった

内閣府から提供されているRESAS-APIから市町村データを取得してCSVにしたい、というタスクがあった。 以下の2つのAPI都道府県と市町村の一覧が取得できるので、都道府県ごとに結合して一つのCSVファイルを作ることを目指した。

このAPIは簡単に利用登録ができ、発行されるAPI_KEYを使って以下のようにAPIをコールできる。

$ export API_KEI=<your_api_key>
$ curl -H "X-API-KEY: $API_KEY" -X GET 'https://opendata.resas-portal.go.jp/api/v1/prefecture'

MySQL8.0を利用する

MySQLは5.7からJSON型を利用できるので、とりあえずAPIから取得したJSONをそのままテーブルに入れてみよう、ということで以下のようにテーブルを作成した。

CREATE TABLE `j_prefectures` (
  `doc` json DEFAULT NULL
) ENGINE=InnoDB;

CREATE TABLE `j_cities` (
  `doc` json DEFAULT NULL
) ENGINE=InnoDB;

とてもシンプル。

ワンライナーMySQLJSONを入れる

都道府県のAPIは1回コールすればJSONが取得できるので、それをワンライナーでそのままテーブルにINSERTする。 テーブルもシンプルなのでSQLもシンプルにできるため、プログラミング言語を使う必要はない。

$ mysql -u root -p[password] resas < <(echo "insert into j_prefectures (\`doc\`) values ('" $(curl -H 'X-API-KEY: '$API_KEY -X GET 'https://opendata.resas-portal.go.jp/api/v1/prefectures')  "')" )

簡単に解説しておく。 mysql -u root -p < file.sqlという構文でfile.sqlに書かれたSQL文を実行できる。 bashの機能で<( command )とするとcommandの出力をファイルとして扱ってくれる。 なのでechocurl でINSERT文を作ってmysqlに渡している。 また -p[password]コマンドラインからパスワードを渡すことができるが、コマンド履歴に残るので注意が必要だ。

同様に市町村一覧もAPIから取得してINSERTする。市町村のAPIprefCodeを指定しないといけないので1から47まで値をかえてコールする。 これもワンライナーで実行できる。

$ while read code; do mysql -u root -p[password] resas < <(echo "insert into j_cities(\`doc\`) values ('" $(curl -H 'X-API-KEY: '$API_KEY -X GET 'https://opendata.resas-portal.go.jp/api/v1/cities?prefCode='$code)  "')"); done < <(seq 1 47)

JSON_TABLE() を使って表にする

JSON_TABLE()を使うと、都道府県と市町村をそれぞれ表で出力することができる。

select prefecture.*
from j_prefectures, JSON_TABLE(
  `doc`,
  "$.result[*]"
  columns (
    prefCode int path '$.prefCode',
    prefName varchar(64) path '$.prefName'
  )
) prefecture;

+----------+-----------+
| prefCode | prefName  |
+----------+-----------+
|        1 | 北海道    |
|        2 | 青森県    |
|        3 | 岩手県    |
|        4 | 宮城県    |
|        5 | 秋田県    |
select cities.*
from j_cities, JSON_TABLE(
  `doc`,
  "$.result[*]"
  columns (
    prefCode int path '$.prefCode',
    cityCode varchar(64) path '$.cityCode',
    cityName varchar(64) path '$.cityName',
    bigCityFlag varchar(4) path '$.bigCityFlag'
  )
) cities;

+----------+----------+--------------------+-------------+
| prefCode | cityCode | cityName           | bigCityFlag |
+----------+----------+--------------------+-------------+
|        1 | 01100    | 札幌市             | 2           |
|        1 | 01101    | 札幌市中央区       | 1           |
|        1 | 01102    | 札幌市北区         | 1           |
|        1 | 01103    | 札幌市東区         | 1           |
|        1 | 01104    | 札幌市白石区       | 1           |

JSON_TABLE()のバグ

じつは JSON_TABLE() で作成された表へのアクセスはroot権限のユーザーしかできない。 このバグはMySQL Bugs: #90610: ERROR 1142 (42000) when using JSON_TABLEで報告されていて 8.0.13 で修正されるようだ。

CTEでラップしてJOINする

MySQL8.0からCTEが利用できるので、JSON_TABLE()で作成した表どうしをJOINすることができる。

with
prefectures as (
  select pref_tbl.*
  from j_prefectures, JSON_TABLE(
    `doc`,
    "$.result[*]"
    columns (
      prefCode int path '$.prefCode',
      prefName varchar(64) path '$.prefName'
    )
  ) pref_tbl
),
cities as (
  select city_tbl.*
  from j_cities, JSON_TABLE(
    `doc`,
    "$.result[*]"
    columns (
      prefCode int path '$.prefCode',
      cityCode varchar(64) path '$.cityCode',
      cityName varchar(64) path '$.cityName',
      bigCityFlag varchar(4) path '$.bigCityFlag'
    )
  ) city_tbl
)
select * from prefectures join cities using (prefCode);

+----------+-----------+----------+--------------------+-------------+
| prefCode | prefName  | cityCode | cityName           | bigCityFlag |
+----------+-----------+----------+--------------------+-------------+
|        1 | 北海道    | 01100    | 札幌市             | 2           |
|        1 | 北海道    | 01101    | 札幌市中央区       | 1           |
|        1 | 北海道    | 01102    | 札幌市北区         | 1           |
|        1 | 北海道    | 01103    | 札幌市東区         | 1           |
|        1 | 北海道    | 01104    | 札幌市白石区       | 1           |

CSVで出力する

これでAPIから取得したJSONを結合して一つの表にできたのでCSVファイルに出力する。

select * from prefectures join cities using (prefCode)
into outfile '/var/lib/mysql-files/prefecture.csv'
fields terminated by ',' ;

secure-file-prev による制限

secure-file-prev システム変数によって SELECT ... INTO OUTFILE などのデータの入出力が制限されているため、出力先には気をつける必要がある。

MySQL :: MySQL 8.0 Reference Manual :: 5.1.6 Server Command Options

SHOW VARIABLES で確認できるので、出力先はこれに指定されているディレクトリにしよう。

mysql> show variables like 'secure%';
+------------------+-----------------------+
| Variable_name    | Value                 |
+------------------+-----------------------+
| secure_file_priv | /var/lib/mysql-files/ |
+------------------+-----------------------+
1 row in set (0.00 sec)

まとめ

MySQL8.0で強化された機能を使うことで、JSONを使うタスクを簡単に処理できるので、この記事を読んだ人は是非試してみよう。

第9回 関西DB勉強会でMySQL8.0の発表してきた

f:id:masayuki14:20181013174502j:plain

kansaidbstudy.connpass.com

第9回関西DB勉強会で発表してきた。良い勉強になった。

きっかけ

きっかけはツイッターでの突然のお誘い。

「す」さんはOSS Gateというコミュニティで一緒に活動をしているけど東京の人なので会うことは殆どなかったりする。RubyコミッターでRabbitの作者なのでRuby界隈のすごい人だと思ってたら、実はDB界隈にも顔の広い人で、なんかもうすごいすごいすごい人だというのが今回わかった。だからって何も怖くないやさしい人。

他のお2人もMySQLオフィシャルの人というこで、私でいいのか状態だったけど、ものは試しということで引き受けることにした。 うまくお膳立てもしてもらったので、Blockchain勉強会 in Kyoto #05で発表したものをブラッシュアップして発表することになった。

その時の記事がこちら。 MySQL8.0のJSON型における正規化について - 主夫ときどきプログラマ

人の縁とか過去の活動とか、人生何が起こるかわからないし、何が役に立つかわからない。 でも振り返るとそれらがつながってるのがわかる。

当日の様子

関西DB勉強会への参加自体もはじめてだった。 発表中にも質問がでたりつっこみが入ったりするようで、けっこうフランクな雰囲気だった。 人数も多いのにいい雰囲気が作れているのは運営の人たちの手腕なんだろうなあと思う。

kintoneFileMakerのソリューションのセッションや(どちらも今回始めて知った)、Insight Qubeというハードウェアのセッションもあり、扱う内容の幅の広さに驚いた。

もちろんSQLServerPostgreSQLMySQL、AmazonAuroraといったエンジニア寄りの話も充実していた。 長時間の勉強会が久しぶりだったので正直疲れた。でも懇親会でいろいろとお話できたのでとても楽しい勉強会だった。次回も参加しよう。

自分の発表は

さて、自分の発表はというと、最後ということもあり時間も押していたので、予定の持ち時間よりも短い発表になった。 これは事前に予想していたので、序盤の解説をわりと飛ばしてデモを中心に行った。 先に話をした山﨑さんがうまく流れを作ってくれたので、MySQL8.0の新機能の使い方や動きなどはうまく伝わったんじゃないかと思う。

そしてちゃんと緊張した。こちらも予想通りだったので、デモでのタイピングは準備しておいたテキストのコピペを貼り付けるというテクニックで回避した。さすがだ。

でもディスプレイをミラーリングしてなかったから、スクリーンの様子が見づらいなかでのデモだったのでこれはなにか対策を考えないといけない。 ミラーリングしたらスピーカーノート見れないしなぁ。

後日Twitterのタイムライン #dbkanを見てみると、わかりやすかったなどのポジティブな感想があったのでそれだけで発表してよかったなーと思う。 また発表できるように今後もMySQL8.0をおもちゃにして遊んでみよう。

発表のスライドはこちら。前半のMySQLの新機能解説も合わせてどうぞ。

イベントの告知

発表の中でも告知させてもらったけど、OSS Gateワークショップが大阪であるので、OSS開発に興味があるけど、どうしていいかわからない、という人がいれば参加してくれるとうれしい。サポーターが参加者に付いてサポートしてくれるので、ほとんどの人がはじめの一歩をうまく踏み出せている。

oss-gate.doorkeeper.jp

テクテクテックもテーマがマニアックですが、いかがでしょう。

spookies.connpass.com

spookies.connpass.com

11月21/22日に図ったかのようにMySQLPostgreSQLの大きいイベントが東京である。東京はこういうのがあるからやっぱりうらやましいよね。どっちも行きたいけど。。。

勉強会の会場を提供しているInsight Technologyさん主催の三木会も面白そうなので参加してみたい。

[2018/10/18(木): 三木会@大阪] 『Pythonから使える列指向ファイルフォーマット・Parquetを使おう』『2018年データベースの選択は? SSDは、Oracle / SQLServer / MySQL / PostgreSQLのパフォーマンスを救えるのか??』 | db tech showcase

他の発表のスライド

他の発表のスライドも公開されているので一緒に載せておく。

他のブログ

タイムラインでいくつか見つけたのでそれも一緒に載せておく。

run-around.hatenablog.com

radiocat.hatenablog.com

odashinsuke.hatenablog.com

カジュアル面談の失敗談

Wantedlyのプロフィールを記入しておくと、スカウトメッセージが届くことがある。 会社によっては「転職予定はありません」という旨の返信をする場合もあるし、返信に困ってそのまま放置してしまうことも。 この場合はホント申し訳ない。ごめんなさい。

メッセージによっては不信感を抱くものもある。 あまりプロフィールが充実してないのに「弊社にぴったりだと思い」みたいなことが書いてあるメッセージは謎だ。

そんな中でカジュアル面談しましょう、となることがある。 基本的にオンラインでの面談をお願いしているが、いくつかの面談を通して感じたことをまとめた。

注)ソフトウェアエンジニア界隈のはなしです。

こっちから話したいことはあんまりないですよ

先方は基本的に会社の紹介や事業の紹介をしてくれるが、 こっちは「スカウト」という名目でメッセージをもらって面談に対応しているので、 「何か聞きたいことあるのかな」というスタンスなのであんまり話すことがない。

なので「なにか質問ありますか?」みたいに言われても「別に・・・」となってしまう。 事前にどういう話をしたいか、みたいなことを教えて欲しい。 アジェンダとかアンケートがあればなお良い。

プロフィールほんとに見ているか疑問

プロフィールには「紹介文」や「このさきやってみたいこと」を書いているし、Tiwtte/Blog/GitHubのリンクもある。スカウトしてくるくらいだからその辺りもチェックされているのかな、と思いきやそうでもない。 せっかく時間を作っているのだから有意義な時間にしたいとは思うものの、はじめに不信感や疑念を持ってしまうとその後を良い時間にするのは困難だ。

京都に住んでいるのに、東京の企業が「コーヒー飲みに来ませんか?」ってどういうつもりなんだろう。

遊びに来ませんか、ってなに?

遊びに来ませんか?って言われても困る。 分かってるけど、遊びたいわけじゃないでしょ、っていう。

Hello hey | hey こんな感じにイベント化していると行きやすい。

もし、なんらかのスカウトでカジュアル面談をオファーするとしたら。

文句ばっかり言っててもしょうがないので、もし自分がエンジニアを採用したい企業側だったらこうしたほうがいいかな、というものも書いておく。

事前に目的を明確にする

カジュアル面談で何を話したいかを事前に明確にする。 会社を知ってもらうためなのか、プロフィールについて詳しく知りたいことがあるのかなど。 目的がはっきりしていないカジュアル面談はお互いにいいものにはならない。

事前にアジェンダのようなものを示しておく

事前に何を話すのかをお互いに共有すれば、それぞれ準備をすることができる。 スカウトされた側も話すことを事前に考えることができるし、準備ができていない場合は延期することも可能になる。

市場調査のひとつにする

これからの時代は、企業と従業員がより対等な関係になっていくだろう。 企業は必要な人材を明確にしつつ、その人材が企業に何を求めているかを知る必要がある。

  • エンジニアはどういう働き方をしたいか
  • 会社でどういう体験をしたいか
  • どういう人と働きたいか

などを直接ピックアップする。

相手がフリーランスだったら

社員として迎えたいのか、フリーランスのままでも仕事をしたいのか明確にする。 あと単価を聞きましょう。