読者です 読者をやめる 読者になる 読者になる

脱職エントリー

いつか退職エントリーを書いて一人前のエンジニアを名乗りたい

MySQLユーザ会会 in 長野 2017に行ってきた

このイベントの参加メモです。

が、自分が無知すぎるので、せっかく東京から凄い人たちが来たのに自分は1割も理解に及んでないので申し訳ないなぁと言う気持ちと罪悪感から当エントリーはスタートしてます。

nseg.connpass.com

 

ちなみに筆者はDjangoのオーアールマッパーに頼り切った生活をしているため、裏側がmysqlなのかpostgresなのかsqlite3なのかすら意識することなくDjangoの処理を書いているため、さすがにそれじゃ不味いだろうなと言うことは頭の片隅に置きつつも今のところあんまり困っていない現状があったりします。

こんな話を聞くと登壇された方々は怒り出すか軽蔑するかも知れませんが、少なくとも2017年5月時点までの仕事でそ辺りの知識が必要になったことがないのです。

極端な話、ニューギニアの狩猟採取民族に向かってスマホも使えない野蛮人だと言ったところで彼らの生活に必要なスキルじゃないんだからしょうがないよねって思ってください。(必死の予防線)

 

MySQLとは - 坂井 恵(@sakaik)

 

データベースとは、mysqlとはについて簡潔にまとまっていました。
今のバージョンがいくつで次はこれみたいな基本的な話も聞けました。
(InnoDBとかMyISAMってなんなんだろうという疑問は後で調べてなんとなく分かりました。)

 

MySQL 8 - @RKajiyama

(資料見つからず)

なんとMySQLの中の人による、MySQL8で導入される新機能についての色々な説明です。

色々あるみたいですが、MySQL8はめっちゃ早くなる、デフォルトのエンコーディングがutf8mb4になるので絵文字が使える。ロックの粒度が変わるぐらいしか理解の範囲にありませんでした。

(個人的には昔知らずに標準のママlatin1で建てて、日本語入らないよ〜って泣いた経験があるので世界標準のデータベース製品目指すなら必然じゃないのかなとも思いますし絵文字とかが標準で使えるのはいいですね)

 

〇 yoku0825を支える技術 @yoku0825

 

大変恐縮ですがなんの話をしているのか分かりませんでした。

 MySQLって”私のSQL”って意味だと勝手に思っていたのですが開発者のお子さんの名前だったんですね。

 

〇Transactd PHP ORM - BizStation Corp.(@bizstationcorp)

PHPのORMの紹介です。(資料見つからず)


(すみません、PHPを知らないため、ふーんという感じでなんとなくで聞いてました。。いつかこの製品を使う場面に迫られたら思い出します。)

 

 

〇 MySQL文字コード - とみたまさひろ(@tmtms)

 

当日の資料は見当たりませんでしたが1つ前のバージョンは見つけました。

www.slideshare.net

 

エンコーディングとキャラクターセットの違いの意味がようやく分かりました。
日本語の厳密な検索は色々とめんどくさいなぁという印象です。
検索はいつでも使うことなので、お客様に検索がおかしいとか突っ込まれたら思い出そうと思います。

 

 

〇まとめ

懇親会でも色々と話を伺いましたが、まぁ何だか分からないけど熱いなぁと、最近はAWSのRDSを建てて後は全てamazon様に全てをゆだねているシアトルの植民地的な生き方を選んでいるのですが、やはり、会社に何人か、できればチームに一人とかインフラにめっちゃ詳しい人も必要だなぁと思いました。
そして今のところ、コンソール画面が苦手な僕にはインフラエンジニアとしての生き方はできないなぁとも思いました。

 

困ったときには今日の資料を思い出せるようにしたいですね。

あとはMySql8は今日聞いた話では超高性能っぽいので使って見たいですね!(postgresとどっちが早いんだろう)

 

MyNaのシールを頂きました。

mynaって鳥みたいです。

https://www.google.co.jp/search?q=myna&source=lnms&tbm=isch&sa=X&ved=0ahUKEwjdqbPpte7TAhXHv7wKHdeOBCcQ_AUICigB&biw=1180&bih=613

f:id:darakunomiti:20170514121543j:plain

 

これをmacに貼る覚悟はできていないのでそっと机に閉まっておこうと思います。

 

Django入門その後に(8)〜TとVを追加してとにかく動かす〜

ここから先は少し複雑で、いくつかのことを同時に直さないと動かすことができません。
まずはやることを図示します。

urlにアクセスしたとき
f:id:darakunomiti:20170506181417j:plain

最初のMTVモデルではurlについて説明をはしょりましたが、実際にはurlがcontrollという役割を担います。
MTVのViewの前にどのViewを呼ぶかを振り分ける、コントロールという処理があるんですですね。

流れとしては、①プロジェクトのurls.py→②アプリケーションのurls.py→③アプリケーションのViews.pyの指定したメソッド→④取得したデータをtemplateに詰めて返す

処理の順番に従うと①から書くのが良いと思うのですが、①を書くためには呼び出す②が必要で、②を書くには③が・・となるので④番のtemplateから書いていこうと思います。

最終的に何を表示したいか

最終的には先ほど登録したゆきよ様の名前を1行表示します。

④template置き場を作ろう

templateの置き場はまぁ諸説ありますが、seiyuu_info/info/template/に置こうと思います。

  • seiyuu_info/info/直下にtemplatesフォルダを追加します。
  • その中にlist.htmlを追加します。
  • htmlを以下のように修正します。
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>ゆきよ様</title>
</head>
<body>
<p>{{seiyuu.name}}</p>
</body>
</html>

ここでは{{seiyuu.name}}にデータベースから読み出した声優さんのお名前を表示します。{{ }} 二重の中括弧に括られた中にデータベースから取得したお名前を表示します。
なお、筆者はwebapiばかり作っているhtmlど素人なので、自分の勉強もかねて素のhtmlで行こうと思います。

③Viewを追加しよう

次にView(処理)を書きましょう。

seiyuu_info/views.py
from django.shortcuts import render  # レスポンス用の関数
from info.models import Seiyuu  # データベースを使えるようにする 

# Create your views here.


def get_yukiyo(request):
    """ゆきよ様のデータを返す"""

    seiyuu = Seiyuu.objects.get(name='藤井ゆきよ')  # 声優さんTBLからゆきよ様のデータだけ取得します。
    return render(request,
                  'seiyuu_list.html',  # 使用するテンプレート
                  {'seiyuu': seiyuu})  # テンプレートに渡すデータ

seiyuu = Seiyuu.objects.get(name=‘藤井ゆきよ’)

ここでは名前が'藤井ゆきよ'であるようなレコードをselectしています。
テーブル名.objects.get(条件)とすることで、Seiyuuテーブルの中身を一件だけselectできますが複数件(または0件)来た場合はエラーとなります。
条件の書き方も色々ありますが、今回は field名=‘条件文'という書き方にしました。
ここは感覚的に分かるかなと思います。

レコードを取得したら、次にrequestデータを受け取って、レスポンスデータを返します。
テンプレートは先ほど作成したseiyuu_list.htmlです。
seiyuu_list.htmlでは{{seiyuu.name}}を表示ししようとしていますので、seiyuuというレコードをそのまま渡します。

viewを呼ぶとtemplateにデータを詰めて返すところはできました。
しかし、まだurlにこの処理がどのurlから呼ばれるか書いていないので追加しましょう。

②アプリケーションのurlからlistを呼ぶ処理を書く

アプリケーションinfoでurlとviewを繋げます。
seiyuu_info/info/urls.pyを追加する

``from django.conf.urls import url from info.views import get_yukiyo # ゆきよ様のデータを呼び出す関数を追加

urlpatterns = [ url(r'^get_yukiyo/$‘, get_yukiyo), # http://XXX/info/list にアクセスされたらseiyuu_listの関数を呼び出す ]```

①プロジェクトのurlsからアプリケーションinfoを呼ぶ

webプロジェクト全体とinfoプロジェクトを繋げます。
ここについても、開くと英語でなにか書かれていると思いますが、あそこを参考にすれば大丈夫です。

from django.conf.urls import url, include # includeの追加
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^info/', include('info.urls')) # 先ほど追加したinfo.urlをinclude(良い翻訳が浮かばない)する
]```

include('info.urls')についてですが、この書き方をすることで、 info/urls.pyに書かれた全てのurlを取り込むことができます。(今回はyukiyoしかありませんが・・)</br> 

この時点で以下のアドレスにアクセスするとお名前が表示されていると思います。

[http://127.0.0.1:8000/info/yukiyo/:title]


まずはこれで最低限の疎通ができました。
これ以降はMVTのそれぞれに絞って細かく見ていこうと思います。

Django入門その後に(7)〜Adminサイトを見てみよう〜

ここではDjangoでGUIGUIデータの投入が行えるadminについて見ていこうと思います。

1.その前にスーパーユーザーを作ろう

adminサイトを作る前にスーパーユーザーを作りましょう。
当たり前の話ですがadminサイトが誰からも見えてしまったらセキュリティ上とんでもないことです。
ログインは必須なのでその権限を持ったスーパーユーザーをつくりましょう

$  python manage.py createsuperuser
Username (leave blank to use 'XXXX'): admin
Email address: amind@email.com
Password: minadminad
Password (again): minadminad

こんな風にユーザー名、メールアドレス、パスワード(8文字以上、usernameと似た名前はダメ)を決めると作られます。
もう分かってるかも知れませんが、スーパーユーザーの情報はDjangoで最初にmigrateしたときに自動的に作られたUserテーブルに保存されています。

2.DjangoAdminを書こう

seiyuu_info/info/adminを見てみましょう。

まだこれしか書かれていません

# Register your models here.

さくっとSeiyuuモデルを追加してみましょう。

from django.contrib import admin
from info.models import Seiyuu  # Seiyuuクラスをimportする
# Register your models here.


class SeiyuAdmin(admin.ModelAdmin):  # 声優アドミンのクラスを宣言
    pass

admin.site.register(Seiyuu, SeiyuAdmin)  # 決まった書き方
# 書き方
class [モデル名]Admin(admin.ModelAdmin):  # 
    pass

admin.site.register([モデル名], [上記のクラス名])  # 決まった書き方

Djangoを実行して確認してみよう

$ python manage.py runserver

そして、アドミンサイトに入ってみましょう。

http://127.0.0.1:8000/admin

ログインするとなにか画面ができてますね!

f:id:darakunomiti:20170506022334j:plain

早速Seiyuusの所を押してみましょう

f:id:darakunomiti:20170506023704j:plain

適当に入力してSAVEを押すと一覧にゆきよ様が追加されましたね!
ちなみにこの記事を書いてるときはサカサマのパテマを見てるのですが、普通のヒロイン感あっていいですね。 こういう役もっとやってもいいと思います。
f:id:darakunomiti:20170506023727j:plain

一覧から開くとこんな感じで修正や削除ができます。

f:id:darakunomiti:20170506025228j:plain

後は感覚的にadminサイトを扱えると思います。一旦これでデータをGUIGUI作れるようになりました。
いよいよ。MTVモデルのTとVを一緒に作ろうと思います。次回はちょっと作業が多くて大変かも知れません。

Django入門その後に(8)〜TとVを追加してとにかく動かす〜 - 脱職エントリー

Django入門その後に(6)〜migrateって何〜

今度こそ遂にようやくデータベースに反映しますがその過程について少し細かく書いていこうと思います。

マイグレートに関する3つのコマンド

マイグレートってなんぞ
f:id:darakunomiti:20170506011702j:plain

マイグレーションにはざっくり3つのコマンドがあります。

  • showmigration: 今のデータベースへの反映状態を表示する
  • makemigraiton: models.pyの内容を読んでマイグレーションファイルを作る
  • migrate: マイグレーションファイルの内容をデータベースに反映する

それぞれについて細かく見ていきましょう

①showmigrationで反映状態を確認しよう

$ python manage.py showmigrations とコマンドを打ってみましょう

 [X] 0001_initial
 [X] 0002_logentry_remove_auto_add
auth
 [X] 0001_initial
 [X] 0002_alter_permission_name_max_length
 [X] 0003_alter_user_email_max_length
 [X] 0004_alter_user_username_opts
 [X] 0005_alter_user_last_login_null
 [X] 0006_require_contenttypes_0002
 [X] 0007_alter_validators_add_error_messages
 [X] 0008_alter_user_username_max_length
contenttypes
 [X] 0001_initial
 [X] 0002_remove_content_type_name
info
 (no migrations)
sessions
 [X] 0001_initial

多分こんな感じにでてくると思います。
最初にDjangoが標準で作るdjango_migrationsを表示しています。

②makemigration

反映状態を確認したらマイグレーションファイルを作ってみましょう。

Migrations for 'info':
  info/migrations/0001_initial.py
    - Create model Seiyuu

なんかでましたね

ここでもう一度先ほどのコマンドを叩いてみましょう $ python manage.py showmigrations

 [X] 0001_initial
 [X] 0002_logentry_remove_auto_add
auth
 [X] 0001_initial
 [X] 0002_alter_permission_name_max_length
 [X] 0003_alter_user_email_max_length
 [X] 0004_alter_user_username_opts
 [X] 0005_alter_user_last_login_null
 [X] 0006_require_contenttypes_0002
 [X] 0007_alter_validators_add_error_messages
 [X] 0008_alter_user_username_max_length
contenttypes
 [X] 0001_initial
 [X] 0002_remove_content_type_name
info
 [ ] 0001_initial ★なんかできてる!
sessions
 [X] 0001_initial

次にフォルダを覗いてみましょう seiyuu_info/info/ f:id:darakunomiti:20170505234128j:plain

0001_initial.pyというのができていますが、これがマイグレーションファイルの実体になります。infoapiには未反映の0001_initialというマイグレートファイルがあるよということですね。
ちなみに反映済みになると先頭の[]が[X]になります

3.migrate

実際に反映するにはmigrateというコマンドを打ちます。

$ python manage.py migrate

  Apply all migrations: admin, auth, contenttypes, info, sessions
Running migrations:
  Applying info.0001_initial... OK

これでデータベースにデータが反映されました。

せっかくなので実際にデータベースを開いて確認してみよう

$ sqlite3 db.sqlite3
sqlite> .schema info_seiyuu
CREATE TABLE "info_seiyuu" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(255) NOT NULL, "gender" integer NULL, "birth_day" date NULL, "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL);

info_seiyuuというTBLが作られています。

  • 名前はSeiyuuではなく [アプリケーション名]_[Djangoに書いたTBL名]で作られますが実際にDjangoで操作するときに意識することはありません。普通にSeiyuuで扱います。
  • IDなんて宣言した覚えがない!→これは定義するときにPKを指定しないとDjango側でIDという名前でPKを自動で作ります。これは大事です。

れで、遂に、やっと、Djangoとデータベースが繋がりました。
ドカベンが柔道から野球を始めるまでに6巻、まどかが魔法少女になるまでに12話掛かりましたが、このチュートリアルは記事6本使って、まだMTVのMしか終わっていませんが一つ一つを丁寧に理解しながら進むことで、色々応用が利くので、ゆっくりと進みましょう。

次回はこれらを登録・更新・削除するadminサイトについて見ていこうと思います。

Django入門その後に(7)〜Adminサイトを見てみよう〜 - 脱職エントリー

Django入門その後に(5)〜モデルを作ろう〜

ここまでDjangoをほとんど書いてなくてジレッタイガーかもしれませんが、一つ一つの手順をじっくり理解しながら進むスタイルですのでご理解ください

余談ですがガラスの艦隊ってアニメは第1話で革命が起きて王制を倒してその革命のリーダーが実は女だったって所まで分かるぐらい20分に詰め込みましたが、2話以降はよく知りません。

1.MTVモデルの復習から

とにかく今回からやっとDjangoの製造にとっかかります。
まずはMTVのM、モデルから行こうと思います。
モデルって何だっけって人のためのイラストを再掲しますとこんな感じです。

MTVモデルについて
f:id:darakunomiti:20170507010044j:plain

要はデータベース部分です。最近はテーブル定義するのにSQL文とか要らないんですよね。Djangoで書いたものを反映してくれます。 すっごーい

2.実際に書いてみよう

今回追加するデータベースはinfoのアプリケーションで使うので/info/models.py に追加します。

from django.db import models  # お決まり


class Seiyuu(models.Model):  # SeiyuuというTableを宣言する、頭文字が大文字が流儀
    """声優さんの一覧"""

    #  性別を選択する選択肢を宣言
    GENDER_CHOICES = (
        (1, '男性'),
        (2, '女性'),
        (3, 'その他'),
    )

    # フィールドを定義します
    # verbose_name:人間に表示する名前を決める、adminサイトとかで使う
    name = models.CharField(max_length=255, verbose_name='名前')  # max_lengthは長さの最大値
    # choicesにタプルを指定することで選択肢のエリアにできる、
    # blankやnullをOKにするかどうか
    gender = models.IntegerField(verbose_name='性別', choices=GENDER_CHOICES, blank=True, null=True)
    birth_day = models.DateField(verbose_name='誕生日', blank=True, null=True)

    created_at = models.DateTimeField(auto_now_add=True)  # レコードが追加された時にその時間を保存します
    updated_at = models.DateTimeField(auto_now=True)  # レコードが更新されたタイミングで現在時間が保存されます。

    def __str__(self):  # クラスを呼び出したときに何が帰るか?(基本何でも良いです)
        return self.name

3. 細かく見てみよう

ここではSeiyuuというTableを宣言しています。

name = models.CharField(max_length=255, verbose_name='名前')

Char型の”名前”という最大255文字のfieldを宣言しています。
verbose_nameというのは人間にも分かる名前を意味しますが、後述するadminサイトで表示するときに「名前」と表示することができます。

choices

性別のように入力項目に制限がある場合は、choicesを使います。
タプルで宣言した項目だけが登録出来るようになります(この場合は1か2)

※タプルというのは、値の中身を絶対に変えられない配列です。丸括弧とカンマ区切りで宣言します。

4.戻り値

これを書いておかないと後述するadminサイトがエラーで表示されません。
とりあえずそのモデルの持つ代表的な項目を返せば良いと思います
あんまりよく分かってないです

書き方
    def __[戻すときの型]__(self):
        return self.戻すfield

    def __str__(self):
        return self.name

書き方のイメージはこんな感じです

[プロジェクトフォルダ]/[アプリケーション名]/models.py

from django.db import models # お決まりの書き方


class [TBL名](models.Model): 

    # フィールドを定義します
   フィールド名 = models.型Field(この中の書き方は色々)
 
    def __[型名]__(self):
        return self.フィールド名

覚えていて欲しいコーディングルールはこんな感じです。

  • TBL名はclass Xxxxで宣言する.
  • TBL名は先頭大文字で単語は複数単語の場合は繋げて書く(例: PrettyRhythm等)

  • field名は小文字で書く

  • field名は単語が複数の時はアンダースコアで繋げて書く(pretty_rhythm等)

ということでいい加減migrate(djangoに書いた定義を実際のデータベースに反映する)をしましょう。

Django入門その後に(6)〜migrateって何〜 - 脱職エントリー

Django入門その後に(4)〜繋がるDB〜

ここではデータベースとDjangoを繋げます。
繋がるストーリー、カラフルストーリーです。(意味不明)

youtu.be

カラフルストーリーのPVは声優系PVとしては珠玉の出来映えです。
10代の素材を損なわない、制服という分かりやすい記号に、2人のダンシングスキルそして、ワンカットPVという努力と工夫の詰まった大変素晴らしいものです。

1.データベースの設定はどこで決める?

データベースへの接続設定はsettinngs.pyに書きます。

settings.py

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

標準ではsqlite3に繋がるようになってます。
sqlite3ってなんだよって人もいると思いますがその謎はすぐに解けます。

2.データベースの設定を実際のデータベースに反映させよう

とりあえず何も考えずにマイグレーション(DjangoとDBを同期させる)という処理をやってみましょう。

$ python manage.py migrate

  Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying sessions.0001_initial... OK

なんか色々動きましたね!

もう一回フォルダを見てみましょう

├── db.sqlite3: ★なんか出来てる!
├── info
│    (中略)

├── manage.py
└── seiyuu_info
    ├── 中略

db.sqlite3というのがデータベースの実体になります。

3.sqlite3に入って実際に作成されたデータベースを確認してみよう

今回生成されたデータベースの中に入ってみましょう。

sqlite3 [接続先のデータベース]
$  sqlite3 db.sqlite3
SQLite version 3.16.0 2016-11-04 19:09:39
Enter ".help" for usage hints.
sqlite> 
sqlite> 
sqlite> 
sqlite> 
sqlite> .tables  ★このコマンドでテーブルの一覧が見れます
auth_group                  auth_user_user_permissions
auth_group_permissions      django_admin_log          
auth_permission             django_content_type       
auth_user                   django_migrations         
auth_user_groups            django_session            
sqlite> 

先ほどのmigrateというコマンドで色々できました。
じゃこれって何なんだろうというのも絵にしました。

マイグレートについて
f:id:darakunomiti:20170503183007j:plain

ここまでデータベースの定義なんて何一つ書いてませんが、テーブルがいくつかできてますね。
何かというと、Djangoは標準でテーブルをいくつか作ります。例えばセッション管理とかユーザー情報みたいなところを標準で生成します。
うーん、至れり尽くせりですね

次は実際に声優情報のデータベースを追加していきましょう。

Django入門その後に(5)〜モデルを作ろう〜 - 脱職エントリー

Django入門その後に(3)〜MTVモデルって何ですか? 難しいですか? 教えてもらって良いですか?〜

終末何してますか?は見てませんし、内容も全然知りません。ごめんなさい

 MTVモデルって何?

Djangoの基本的な考えにMTVモデルについてです。 公式チュートリアル

中身は貼りませんが、この説明だとまずはMVCモデルが分からないと意味不明じゃないでしょうか
例によって絵を描きますが、深夜テンションで冷静な判断ができないので、アイドルオタクとアイドルを例にした絵を描きました。

MTVモデルって何?
f:id:darakunomiti:20170507005421j:plain

オタクからのコールリクエストに対して写真(データ)をアルバム(Model)から探して、thankyouと書かれたフレーム(template)に詰めてレスポンスすることでオタクをぶち切れさせてるんですね
このアルバムから写真を探してきてフレームに詰めて渡す行為全般が処理(View)になります。
オタクはすぐにぶち切れます。

もうちょっと技術寄りに書くとこんな感じです。

MTVモデルって何?(技術寄りに)
f:id:darakunomiti:20170507010044j:plain

(この例ではwikipediaの表示を例にしていますが、wikipediaDjango製ではありません、分かりやすい例としてwikipediaを出しています。)
ここではwikipedia.org/悠木碧をブラウザから叩くことで、該当の処理(View)が呼ばれてデータベース(Model)から名前や生年月日や出演歴を取得した後にhtmlファイル(template) にその文章や写真を詰めて返しています。templateは表示の部分を司っています。

これを今手元にあるファイルのどこに当てはまるか考えて見ましょう

├── info
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── migrations
│   │   └── __init__.py
│   ├── models.py: ★ここがモデルです。ここにデータベースの定義を書きます
│   ├── tests.py
│   └── views.py: ★ここがViewです。ここに処理を書きます。
├── manage.py
└── seiyuu_info
    ├── __init__.py
    ├── __pycache__
    │   ├── __init__.cpython-35.pyc
    │   └── settings.cpython-35.pyc
    ├── settings.py ★ここにデータベース接続情報を書きます
    ├── urls.py
    └── wsgi.py

templateがないですね。ここは後で追加します。

ということで、次からはMTVのModelについて見ていこうと思います。

Django入門その後に(4)〜繋がるDB〜 - 脱職エントリー