思考を整理するのに使えるオンラインホワイトボードMiroの個人的な使い方あれこれ

f:id:nam_yu_sql:20210115083150p:plain この記事はあとでcloud.config tech blogにマルチポストする予定です。

昨今リモートワークが推奨されていますが、そんな時節のせいなのか過去に自分が書いたブログ記事の中ではオンラインホワイトボードMiroの記事はやけに読まれています。
前回Miroについて書いてから時間が空き、一般的な部分の説明はほぼほぼやりつくしてしまった感じもするのですが、今回は自分が普段どのようにMiroを使っているかを示しながら思考の整理について語ってみようと思います。

Miroとは

MiroはMiro者が開発しているWebアプリケーションで、Miro社曰くはonline collaborative whiteboard platformと呼んでいます。日本だとよく「オンラインホワイトボード」と呼ばれています。
元々はRealtime boardという名前のアプリで会社名もRealtimeboard.incだったのですが、2019年にアプリの名前が変わり、その時に社名も変更したようです。
主な機能は、ホワイトボードを使うような直感的な図の作成機能と、それをリアルタイムでほかのユーザーと共有する機能です。
例えば、左のメニューから付箋のアイコンを選んで好きな色を選んだら・・・
f:id:nam_yu_sql:20210115083211p:plain 適当な場所をクリックするだけでそこに付箋を張り付けることができます。
f:id:nam_yu_sql:20210115083221p:plain 関係性を示したいときは付箋をクリックしたときに出てくる青丸をほかの物体にドラッグしてやれば簡単に矢印を引くこともできます。
f:id:nam_yu_sql:20210115083230p:plain 矢印を引くときはさりげなく他の物体に吸い付いてくれたりしてくれるのでさりげなく使い勝手がいいです。

こんな基本機能のMiroですが、普段自分がどのようにMiroを使っているかご紹介したいと思います。

いろんな使い方

例えば、自分の場合すごくシンプルなTodoリストのボードを作っています。
タスク管理ツール自体はMiro以外にもあり、より高機能なものも色々あります。
なのでMiroをタスク管理ツールとしてチームで使うことはあまりありませんし自分もいつも使っているわけではないのですが、やることが増えてきて混乱しそうになった時に頭の中のダンプ先として個人的なTodoリストとしてMiroを使っています。仕事以外のタスクも一緒に突っ込めるのも利点かもです。
直感的に素早くタスクを付箋にして張り出せるのと、タスク間の依存関係を矢印で示したりして何が「待ち」の状態になっているか分かりやすく示せます。
f:id:nam_yu_sql:20210115083240p:plain また、読んだ本の内容をまとめて勉強会の資料にしたりしています。
色分けができるので、赤い付箋はこの章の問い、そこに向かって引いている矢印はその問いに対する答えを示すなど、役割を持たせられます。
f:id:nam_yu_sql:20210115083254p:plain 勉強会や話を聞くときのメモとして利用したこともあります。これはいつぞやGlobal AI Nightに参加したときのメモですね。講義を受けながら、後ろではこんなメモをとってました。
ぜひ記事と見比べてみてください。
f:id:nam_yu_sql:20210115083309p:plain 他に、何かの処理のロジックを整理するためにフローチャートのようなものを書いたこともあります。Miroの基本的な機能で図形を描くこともできるので、このような使い方もできます。他にもお見せできる内容ではないのですがシーケンス図なんかも書いています。
f:id:nam_yu_sql:20210115083320p:plain 他にも、ここで示すことはできないのですが仕事の中で考えていることがややこしくなってきたときにMiroはよく使います。
書いたことをほかの人に見せることはほとんどないのですが、「何かに悩んだらそれを書き出してみる」というのは問題解決のいい方法だと言われているのを個人的には信じているので、そのためのツールとして使っています。
普段このように思考を整理するのにMiroを使うことが多いのですが、指向を整理するのに何やるかといったら頭の中で考えているとりとめのないことを列挙してそこから関連するものをまとめて整理したり一つ一つの問題に対する回答を結び付け足りしていると思います。
Miroでは一番基本的な機能として付箋を貼ってそれらを矢印で結びつけることができるのですが、それがこういった思考の整理に役立っている気がします。
自分が書いたMiroの最初の記事が思考のロギングの話だったのもそこから来ています。

おわりに

今回は普段よく使っているMiroについて個人的によくやる使い方の例からMiroについて語ってみました。
私はMiroは自分の考えをまとめるために一人で使いがちですが、リモートワーク環境下で意思疎通のために複数人で使うこともできます。ぜひ一度使ってみてください。

RDB脳なぼくらのためのKQL⇔SQL対応表

f:id:nam_yu_sql:20210114075523j:plain この記事はcloud.config tech blogにもマルチポストしています。

tech-blog.cloud-config.jp

結論

今回は結論から書きます。「SQLでいうところのアレ、KQLだとどんな感じだったっけ」という人はココだけ読めば解決です。
|SQL|KQL|
|---|---|
|SELECT | project|
|FROM句 | 一番最初の行にテーブル名を書くだけ|
|WHERE | where|
|LIKE '%[検索文字]%' | contains "[検索文字]"|
|GROUP BY | summarize|
|ORDER BY | sort by|
|LIMIT(またはOFFSET~FETCH) | take|
|COUNT | count|

※他にも思い出したものがあれば順次追加していきます
また、書いている途中で見つけたのですがもう少し広い範囲での対応表はMicrosoftによってこちらに元々用意されているようですのでこちらも見てみてください。

クエリ例

StormEvents   
| project State, StartTime, EpisodeId, EventType, InjuriesDirect, Source  
| where Source contains "new"  
| sort by StartTime  
| take 100  

基本的な書き方として、偉業目にテーブル名を書いて2行目以降は「|」を挟んで書きます。

KQLとは

KQLは、SQLでいうところのCRUDの動作のうちRead動作だけを行えるちょっと特殊な書き方をするクエリ言語です。「Kusto Query Language」の略がKQLです。
主な使用場面としては、Azure Log Analyticsのようなログを蓄積するリソースにおいて蓄積されたログデータを検索、表示させる際に使用します。Log Analytics他にも使う場面はあるのかもしれませんが網羅的に把握はできてないです・・・。
ログのような大量の蓄積されたデータから、効率よく、欲しい形で簡単にデータを読み出すためのクエリ言語がKQLであるという形です。読み取りしかできないというのも使用用途がログの検索であるというところからきているようです。

他にも、今回はスコープから外れるので紹介しませんでしたが「render」というキーワードを使用してログから簡単にグラフを出力する機能もあります。
例えば以下のようなクエリを書くだけで簡単にタイムチャート図が出力されます。

StormEvents   
| summarize count()  by d = bin(StartTime, 30d)  
| render timechart   

f:id:nam_yu_sql:20210114075546p:plain

使用する際はLog Analyticsの「ログ」のメニューからKQLを書く窓を開くこともできるのですが、他に「Kusto.Explorer」というツールもあり、こちらを使うとデスクトップアプリケーションから様々な機能の助けを借りつつクエリを書くこともできます。SQL Serverに対するA5 SQLやSSMSみたいなものですね。

簡単に試せる環境があるのよ

また、KQLを簡単に試せる環境があります。
ここにはあらかじめデータが挿入された環境があり、KQLを打ち込むことでいくつかのテーブルから結果を出力することができます。
例えば初期状態だとサンプルのクエリとして

StormEvents   
| where StartTime >= datetime(2007-11-01) and StartTime < datetime(2007-12-01)  
| where State == "FLORIDA"    
| count   

が入力されています。
この実行結果としてはCountに23が出力されます。
このクエリを基にして例えば最後の行のcountを外すとその23件のデータが全カラム表示されたり、projectを使うことで表示するカラムを絞り込むことが出来たりします。
ここで様々なクエリを試してみることができるので、様々なクエリを試してみましょう。

おわりに

KQLはLog Analyticsでログを確認するときによく使用するもので社内でも時々急に使うことになったりするのですが、キーワードが独特なので一見とっつきづらい感じがします。
多くの人は多かれ少なかれSQLを書いたり触れたりした経験はあると思うのですが、その知識をベースにしてKQLはこんな感じだよと説明したらわかりやすいのではないのではないのかというのがこの記事の試みです。
KQLを初めて使う!けどSQLは触ったことあるよという方の理解の助けになれば幸いです。

参考

【小ネタ】k8sのLens使ってみたらちょっと詰まったので解決してきたメモ

f:id:nam_yu_sql:20210113081135j:plain

この記事はcloud.co.fig tech blogにマルチポストしてきました。

tech-blog.cloud-config.jp

こんにちは、コンテナが立つと初めてわが子が立ったように喜ぶなむゆです。
去年、「k8sのIDE、Lensが便利な件について」という記事を見て、あぁ~kubernetes周りのツールについても知りたいな~Lens使ってみよっかなと思い立ちました。
それで実際に使ってみたのですが、Lensで接続するクラスターを指定するのに必要なkubeconfig周りで若干詰まって、それを解決してきたので今回はそのネタで一席打ちます。

kubeconfigとは

kubeconfigとはkubernetesクラスターに接続するのに使う接続文字列のようなもので、「接続先のクラスターのurlはここよ~」とか「接続するときはこの認証情報を使うんよ~」といった情報が記されています。
kubernetesに接続する際にはこのファイルを使って接続を行うため、Lensのようなツールでも接続文字列として使用しているわけです。
デフォルトでは[ホームディレクトリ]/.kube/configのパスに存在するほか、「KUBECONFIG」の環境変数で指定されたパスや「--kubeconfig」のパラメータで指定したパスに存在するファイルをkubeconfigファイルとして使用できます。
詳しくはこちら

起きたこと

Azure上に「namuyutest01」という名前でAKSのリソースを作成し、ローカルでaz login を行ってクレデンシャルを取得しました。
Lensを起動すると接続先のkubeconfigファイルを求められたので現在使用しているkubeconfigを表示するコマンドのkubectl config viewコマンドを使用してkubeconfigを表示しました。だいたいこんな感じです。
f:id:nam_yu_sql:20210113081218p:plain 「REDACTED」って何なの・・・と思いつつこれをコピーしてLensに張り付け、接続してみたらエラーが発生しました。
f:id:nam_yu_sql:20210113081229p:plain というかLens、goのコードで動いてるのですね・・・
等と妙に感心しました。
f:id:nam_yu_sql:20210113081246p:plain

解決方法

結論から言いますと、kubectl config view --raw コマンドを使ってちゃんと生のkubeconfigを取得しましょうねということでした。
kubectl config view のコマンドだとあまりにも文字数の多いトークンなどの情報が「REDACTED」として省略されていたのですね。

生のkubeconfigを取得してLensに張り付けて接続すると・・・
f:id:nam_yu_sql:20210113081255p:plain やった~~~~~~~~~!

教訓

正直自分はkubernetesAKSでしか使用していなかったので、kubeconfigファイルについて「あーget-credentialで取得できるやつ」程度の認識でいました。
実際にはその中身にはちゃんと意味があるので、中身に何が書かれているかはちゃんと把握しておくべきです!

ということでLensを使う時に遭遇したエラーを解決したお話でした。
よっしゃこれでLens使えるぞー!
業務で役立つことは間違いないので、ぜひ使ってみましょう。

Azure DevOpsのパイプラインを回すAPIがあるんだって

この記事はcloud.config tech blogにマルチポストしております。

tech-blog.cloud-config.jp

どうも、パイプラインが回るとうれしいなむゆです。
Azure DevOpsのパイプラインをコードから回したくなること、ありませんか?
普段はAzure DevOpsのパイプラインは文字通りのDevOpsのためのCI/CDパイプラインを回すために使いますが、時としてこれを手動で回したい、しかもできればアプリケーション上から!ということもあるかと思います。~え、ない?~

AzureDevOpsにはそんな時に使えるAPIが用意されています。
今回はそれを使ってAPIからAzure DevOps上のパイプラインを回してみます。

Azure DevOpsパイプラインを回すAPIを叩いてみる

まずはAzure DevOpsのOrganizationとプロジェクトを作ります。
この辺りのやり方はAzure DevOpsでサクっとCI/CDを組んでみるシリーズが参考になりますのでこちらでは省略。
結果としては以下のようなOrganization名「Namuyun」プロジェクト名「Namuyuno」で作成しました。
f:id:nam_yu_sql:20210111143407p:plain それでは、パイプラインで使うパイプラインyamlファイルをAzure DevOpsの機能の一つのReposで作られているGitリポジトリに突っ込んでいきます。
f:id:nam_yu_sql:20210111143430p:plain 今回作成したpipeline.yamlの中身はこんな感じです。

trigger: none  
pr: none  
  
parameters:  
  - name: "sample1"  
    type: string  
    displayName: "Sample1"  
  - name: "sample2"  
    type: number  
    default: 0  
    displayName: "Sample2"  
  
jobs:  
  - job: sample_job  
    displayName: sample job  
    pool:  
      vmImage: ubuntu-16.04  
    steps:  
      - script: |  
          echo Sample1 Value is: ${{ parameters.sample1 }}  
          echo Sample2 Value is: ${{ parameters.sample2 }}  

ざっくりとした意味合いとしては、
- このパイプラインはPRやマージをトリガーにしては回りませんよ~
- このパイプラインは回すときにパラメーターとして「sample1」、「sample2」という名前の引数を受け取りますよ~
- このパイプラインで実行することはパラメーターとして受け取った「sample1」、「sample2」をコマンドラインで出力しますよ~

みたいなことを書いてます。

お次はパイプラインを作ります。メニューからPipelinesを選び、右上の「New Pipeline」ボタンを押します。
f:id:nam_yu_sql:20210111143451p:plain pipeline.yamlのコードはAzure Reposにおいてあるのでそれを選びーの
f:id:nam_yu_sql:20210111143732p:plain リポジトリ名は「Namuyuno」で作ったのでそれを選びーの
f:id:nam_yu_sql:20210111143756p:plain 今回は既に作ってあるyamlファイルを読み込むので「Existing Azure Pipelines YAML file」選びーの
f:id:nam_yu_sql:20210111143804p:plain 「Path」で今回使うパイプラインyamlファイル選びーの
f:id:nam_yu_sql:20210111143858p:plain するとパイプラインyamlファイルの中身を確認できるので問題なければ右上の下↓から「Save」を選択します。これでパイプラインが作成されます。
f:id:nam_yu_sql:20210111143914p:plain 「All」のタブを選ぶと作ったパイプラインが確認できます。今回は名前を「Namuyuno」に変えています。これをクリックします。
f:id:nam_yu_sql:20210111143922p:plain すると作成したパイプラインの詳細画面に映るのですがここでそのページのurlに注目。
「definitionId=○○」とありますが、この番号を覚えておきます。
あとでAPIを叩くときに回したいパイプラインのIdを指定するときに使います。
f:id:nam_yu_sql:20210111143931p:plain 次はパイプラインを回すAPIを叩くのに必要なアクセストークンを作成します。DevOpsの画面右上の方にある心臓が歯車に置き換えられちゃった人みたいなアイコンをクリックして「Personal access tokens」をクリックします。
f:id:nam_yu_sql:20210111143948p:plain するとトークンの一覧の画面が開くので、左上の「New Token」をクリックします。
f:id:nam_yu_sql:20210111144005p:plain 作成するトークンの設定する画面が開くので、名前と設定する権限、有効期限を設定します。「Scope」はトークンに与える権限を設定できるのですが「Custom defined」を選び、下に出てくるスコープの一覧から「Build」の「Read & excute」を選択し、「Create」をクリックします。
ちなみに有効期限の最大は1年なのでアプリケーションに組み込むとき等は注意です!
f:id:nam_yu_sql:20210111144024p:plain すると、トークンが作成され、表示されます。
作成されたトークンはこの画面にしか表示されないのできちんとコピーしておきましょう。
f:id:nam_yu_sql:20210111144053p:plain これでパイプラインAPIを叩く準備は完了です!
今回はPostmanを使ってパイプラインを回すAPIを叩いてみます。
このAPIのURLは、
https://dev.azure.com/{Organization名}/{プロジェクト名}/_apis/pipelines/{回したいパイプラインのId}/runs?api-version=6.0-preview.1
です。HttpメソッドはPOSTです。
今回はOrganization名、プロジェクト名、回したいパイプラインのIdはそれぞれ「namuyun」、「Namuyuno」、「2」で置き換えます。
そしてさらに、アクセストークンの設定も行っていきます。
なので、Postmanでは「Authorization」のタブを開き、TYPEを「Basic Auth」と指定します。するとUsernameとPasswordの入力欄が出てくるので、Passwordの欄に先ほどコピーしたトークンを張り付けます。
Usernameは入力しなくて大丈夫です。
f:id:nam_yu_sql:20210111144115p:plain それができたら、メッセージの本文を作成していきましょう。
「Body」のタブに移動して、タイプは「raw」を選択します。
するとBodyの中身を書き込める欄が出てくるので、ここにメッセージの本文を書き込んでいきます。
メッセージの形式としては、

{  
  "resources": {  
    "repositories": { "self": { "refName": "refs/heads/{パイプラインを回すのに使うブランチ名}" } }  
  },  
  "templateParameters": {パイプラインに渡すパラメーター(Json)}}  
}  

となっています。
今回はパラメーターとして「sample1」「sample2」を渡すので、その内容はtemplateParametersに書き込んでおきます。
f:id:nam_yu_sql:20210111144125p:plain 準備ができたら「Send」を押してリクエストを送ります。レスポンスステータス200番が返って来たら成功!

では、パイプラインがちゃんと回っているか確認するためAzure DevOpsも見てみましょう。

パイプラインの名前の横に時計アイコンが出ていればリクエストを受け付けてパイプラインを回す準備をしています。回転しているアイコンが出ていればパイプラインが回っています!
f:id:nam_yu_sql:20210111144155p:plain 時間がたつとパイプラインの横のマークは緑のチェックマークになるはずです。パイプラインがコケたらバツ印になります・・・
どちらにせよ、処理が終わったらそのパイプラインの処理結果を見ていましょう。
「CmdLine」の項目を選択すると、処理が成功していればパイプラインyamlで記述したとおりsample1とsample2のパラメータに入力した値が出力されているはずです!
f:id:nam_yu_sql:20210111144214p:plain

おわりに

今回はAzure DevOpsから公開されているAPIを使用してAzure DevOpsパイプラインを回しました。
Azure pipelineを回すにはほかにもaz cliを使用した方法もあります。
状況に応じて使い分けていきましょう。

参考

firebase functionsからrealtime databaseに接続するのに軽く詰まったのでメモ

f:id:nam_yu_sql:20200802203941j:plain この記事は後ほどcloud.config tech blogに転載する予定です。

ことの発端

最近ぼくの中でまたfirebase x vue(nuxt)欲が強くなってきていて、(将来のお仕事にもしたいし)再びサイトなんかを作ったりして遊んでいる。
その中で、この間はフロントエンドをfirebase hostingでホストし、APIをfunctionsに作ってそこからrealtime databaseとやりとりするアーキテクチャでサイトを作ろうとした。
その時、functionsからrealtimedatabaseへの接続ってどうやるんだっけ?と軽く混乱して半日ほど潰してしまった。
そこまで高度なテクニックで解決するものじゃない初歩的な話だけど、この先同じ事がまた起こった時に備えてのメモとして、あるいは同じところで詰まった人のため、この記事を残しておきたい。

functionsからrealtime databaseへの接続方法

基本はfirebaseのドキュメントにあるとおりだ。
firebase initでアプリケーションを作ったのだから何か専用の設定をして繋げるんじゃないかと思って色々調べたけれど、そんなこともなかった。
大まかに言うと、javascriptのコードでrealtime databaseに接続するサンプルの通りにすればいい。

firebaseのプロジェクトのページに入って左上の「プロジェクトの概要」の横の歯車から「プロジェクトを設定」を選ぶ。
f:id:nam_yu_sql:20200802204009p:plain
初期状態ではマイアプリが登録されていないので、「マイアプリを追加」から適当な名前を付けてアプリを追加する。
f:id:nam_yu_sql:20200802204027p:plain
すると以下のような接続文字列が取得できるのでコピーする。
f:id:nam_yu_sql:20200802204040p:plain
これを利用してfunctionsのAPIの受け口となるindex.js(あるいは.ts)を以下のようにする。

import * as functions from "firebase-functions";  
import firebase = require("firebase");  
const firebaseConfig = {  
  apiKey: "ここはシークレット",  
  authDomain: "namuyu-functions-test.firebaseapp.com",  
  databaseURL: "https://namuyu-functions-test.firebaseio.com",  
  projectId: "namuyu-functions-test",  
  storageBucket: "namuyu-functions-test.appspot.com",  
  messagingSenderId: "777861796007",  
  appId: "1:777861796007:web:60a7472d9557465d450b82",  
};  
// Initialize Firebase  
firebase.initializeApp(firebaseConfig);  
  
export const addCurrentTime = functions.https.onRequest((request, response) => {  
  firebase  
    .database()  
    .ref("date/" + new Date())  
    .set({  
      currentTime: new Date().toString(),  
      testData: "sample",  
    });  
});  
  

この中のfirebaseは初期状態でpackage.jsonに入っていないので、コードを書き換える前後でnpm install firebaseしておくこと!

ここまでやって```npm run serve してurlを叩くと、realtime databaseの方に以下のようにデータが溜まっていくはず。
f:id:nam_yu_sql:20200802204216p:plain

おわりに

こんな感じに、firebase functionsからrealtime databaseにアクセスしてデータのやり取りを行えるようになる。
が、正直これはjavascriptのコードからであればどこでも同様に行えるので、functionsでなくても同様に動くはずである。
というか、逆にfunctionsなら特別に何かをしなければならないってことでもないというのに気付くのに時間を取ってしまった感じがある。
本来はfirebaseのデータベースにはフロントからクエリを送るとフロントエンドと繋がってデータベースの中身が書き換わるとそれがフロントまで伝搬してリアクティブに表示内容が書き換わるという素敵な機能があったりもするのだけど、そこまでリアルタイムな処理が必要じゃなかったりフロントエンドとバックエンドを分離して最悪バックエンドからfirebaseをはがすとなった時のことも考えると、データベースとのやりとりはfunctions経由で行った方がいいんじゃないかって思うような場合もある。

あと、今回のコードでは接続文字列をコードの中に含めてしまっているが、実際の開発の際にはこれを外部のjsonあたりから受け取るようにして、そのjsonはコード管理とは別に管理することも忘れないように!
2020/8/30追記 どうも実際はAPIキーは隠蔽する必要がないそうな。
フロントエンドにfirebaseを組み込むと配信されるjavascriptにも埋め込まれるので結局APIキーが公開される。
そしたらその公開されたAPIキーで偽の別アプリ作ればfirebase上のデータベースとかアクセスし放題やないかいと思うが、実際にそれで別アプリを作ったところで実際にRead/Writeできるのは設定したルールで決められてる範囲だけだ。
そしてそれらの機能はauthenticationと結びつけられているので、APIキーを入手しても結局別の認証手順を踏まないとリソースの中身をいじれない。
ゆえに実際にはAPIキーを別管理にする必要はない、らしい。

そろそろ「学び方」を学びたくて「リファクタリング・ウェットウェア―達人プログラマーの思考法と学習法」書評

f:id:nam_yu_sql:20200427100403j:plain
※この記事は後ほどcloud.config techblogにもマルチポストします。

学習効率を上げたくて

学習効率って、考えたことありますか?
エンジニアとしてよりよく仕事をしていくためには常に新しいことを学んでいくことが不可欠と言われています。
何か新しいことを学ぼうといった場合、私たちは普段何を学ぶかを考えがちですが(例えばどんなフロントエンドフレームワークを触ってみようかとか新しい言語を触ってみるとして何がいいかとか)、どうせ学ぶならより早く、高いレベルまで学べた方がいいですよね。
だって学ぶべきことは界隈にはほぼ無限にあって、そのくせ時間は有限で。
一つのことを学ぶのにあまりに長い時間を変えていると、自分の学習能力のなさに辟易してそれだけで投げ出すことも度々あります。
そういった事態を避けるためにも、そもそもどうやって学ぶか、学習効率を上げるにはどうすべきかみたいなことを最近考えるようになってきました。
そんな中で見つけたのがこの書籍です。

リファクタリング・ウェットウェアの概要

この本が扱っているのは、認知科学神経科学、心理学などの概念に基づいた思考法や学習方法です。
特に、O'reilly本ということもあり、想定している読者としてプログラマーを想定しているため、特にプログラマーにとって分かりやすいたとえや共感しやすい状況の例を挙げながら説明していることが特徴的です。
その中で、プログラムを書くということを行うのは結局のところハードウェアでもなくソフトウェアでもなく人間の脳(ウェットウェア)であるとし、その働きをリファクタリングすることがよりよくプログラムを書いたりシステムを構築するのに役立つ、ということでウェットウェアをリファクタリングする方法について説明しています。
主に書籍内で扱っている主な概念としては、感覚的な部分をつかさどる右脳と言語的な部分をつかさどる左脳を使った思考でそれぞれRモードとLモードと呼んでいるものがあり、これらをうまく同調させて双方の機能を活用することで学んでいることが上達したりプログラミングについてうまくとらえられるとしています。
書籍内ではこれらをどうやって同調させるかといった方法論を主に3章以降で扱っていきます。

目次

1章 初心者から達人への道
2章 脳の構造
3章 Rモードへの転換
4章 アタマをデバッグ
5章 意識的な学び
6章 経験の積み重ね
7章 集中のコントロール
8章 達人になってから

脳の仕組みを理解してよりよく学ぶ

逆向きの絵を模写する話

脳の働きにはLモードとRモードがあるというお話がありましたが、特に感覚的なRモードは普段あまり使われていないとされています。
特にプログラミングにおいては、普段利用しているLモードに加えてRモードも利用することで、目の前のコードだけでなくその後ろの書くコードの構造やそれらの目的についても意識したコードも描けるようになり、プログラマとして上達できます。
そんなRモードの働きを実感する方法の一つとして、書籍内では逆向きの絵を模写する話が挙げられています。
これは、書籍内にあるとある絵を、別の紙に書き写す訓練です。
制限として、ページの向きは変えないこと、今描いている部分を認識しても、その名前を意識しないことを挙げています。
例えば、人のあごを書いているときも「あごがこうなってて・・・」とか考えるのは無し、ということです。
こうすることでLモードの機能を制限しつつ、見たままの感覚をフルに使って絵を描き、Rモードの働きを経験できます。
ちなみに私が描いたのはこんな感じになりました。↓
f:id:nam_yu_sql:20200427100345j:plain
Rモードを使って絵を描くことの元ネタは「脳の右側で描け」という本で、その書籍内ではこの考え方を核心に持ってきて絵画の上達法を説明しているそうです。
プログラミングにおいても、他に比喩を使ってプログラムを感覚的にとらえることや朝一番にプログラミングについて思いついた方法を書き出すこと(朝一番はLモードがまだあまり働かないのでRモードでモノを考えられやすいのではという考察あり)といった方法を挙げながら、普段利用しているLモードに加えてRモードの働きも使ってよりよくプログラミングする方法を説明しています。

業務でDBと付き合い始めたので久々に読む「失敗から学ぶRDBの正しい歩き方」書評

f:id:nam_yu_sql:20200331072906j:plain この記事はcloud.config tech blogにマルチポストされる予定です。

はじめに

DB、いいですよね。
個人的に以前からDBに興味があって、各種DBの最適化の方法を学んだり、去年は春のIPA試験でデータベーススペシャリストの試験を受けたり(落ちたり)、今年もまた受けようとしたりしています。
そんな中で去年と今とで変わった点が一つあって、それは自分がRDBを実務で弄り始めたことです。
.Net Coreを用いてアプリケーションを作る中で、ORMであるEntityFrameworkを用いてSQLServerにアクセスする部分を何度か実装し、そのアクセスする先のテーブルのスキーマ設計もいくらか経験してきました。
そこでそろそろデータベース周りのノウハウ系の本を読んでみようかという気になり、久々に読んだのが今回書評する本、「失敗から学ぶRDBの正しい歩き方」です。

どんな本なの?

この本の著者さんは2017年と2018年にData Platformの分野でMicrosoft MVPを受賞したデータベース分野でのスペシャリストで、ブログや登壇などを通してRDB、特にPostgreSQLのノウハウを共有しています。
特に、RDBのリファクタリングRDBアンチパターン対策について詳しく、れらに関する過去の登壇や記事などで触れられた内容が凝縮して纏められたような本です。
目次を見ると各章のタイトルはアンチパターンの内容となっており、それらの問題点とそれを起こさないようにする対策が章ごとに纏められています。
各章の繋がりはそこまで強くないので、気になったトピックから読み始められます。
テーマとして大雑把に分けると、見た感じ9章までがテーブル設計上の問題、10章以降が運用上で起きる問題について扱っている印象です。
現在設計、実装寄りのタスクをしている方は前半部、運用を行っている方は後半部が気になるのではないでしょうか。

目次

第1章 データベースの迷宮
第2章 失われた事実
第3章 やり過ぎたJOIN
第4章 効かないINDEX
第5章 フラグの闇
第6章 ソートの依存
第7章 隠された状態
第8章 JSONの甘い罠
DB9章 強過ぎる制約
第10章 転んだ後のバックアップ
第11章 見られないエラーログ
第12章 監視されないデータベース
第13章 知らないロック
第14章 ロックの功罪
第15章 簡単過ぎる不整合
第16章 キャッシュ中毒
第17章 複雑なクエリ
第18章 ノーチェンジ・コンフィグ
第19章 塩漬けのバージョン
第20章 フレームワーク依存症

気になったトピック

データベースというもの自体の性質の話

「データベースの寿命はアプリケーションより長い」という言葉がこの書籍の中で頻繁に出てきます。
この言葉は書籍内だけでなく著者のブログやスライドにおいても頻繁に出てくる言葉なのですが、データベースリファクタリングを考えるときの最も根底にあると個人的には考えている言葉です。
例えば、何かしらアプリケーションを作る際にはそのアプリケーションで扱うデータの保存先としてデータベースを使用するわけですが、そのアプリケーションがサービス終了するとして、そこで利用していたデータの全てをアプリケーションのシャットダウンと同時に削除するわけではないはずです。
既存のデータに価値を見出し、他のサービスでも利用しようと考えるのではないでしょうか。
そうした際、データベースの設計に問題がありパフォーマンスや拡張性に影響があったとしたら、その影響は新しいアプリケーションにまで及びます。
さらに、そんな問題を解決しようとすれば大抵の場合サービスを停止させて直す必要が出てくるので、顧客満足にまで悪影響が出ます。
なので、データベースを設計する際には後々のことまで考えて問題が起きないようにしようねという文脈ではこの言葉が頻繁に出てきます。

MENTORの原則の一つ、理論より計測の話

INDEXをどのように設定していくかという話の中で、MENTORの原則という言葉が出てきます。
これは、それぞれ"Measure"、"Explain"、"Nominate"、"Test"、"Optimize"、"Rebuid"の頭文字をとったもので、INDEX作成時の対応の考え方をまとめたものです。
"M"以外のものは各々調べていただくとして、この中のMeasureは読んでいて特に重要なのではないかと感じました。
というのも、理屈の上では「ちゃんと利用できる箇所でINDEXを張るとクエリが速くなる」ということを理屈では知っていますが、結局はそれを基にして本当にクエリが速くなったか確認する必要があるからです。
「このINDEXを張れば理屈の上では速くなるはず!」と考えていても実際にINDEXを張る前後で比べて変化がなければ、そのINDEXは意味がなかったことになります。
無駄なINDEXは容量を圧迫するだけなので作らないでおくべきという考えからするとこのINDEXは作らない方がよかったという結論になります。
その上で実際に有効なINDEXはどのようなものなのか実行計画を確認しながら考えて本当に有効なINDEXを張り直すということを通してクエリを速くできるので、まず最初にはその対応で本当にクエリが速くなるのか、計測して確かめることが重要であるといえます。

おわりに

・・・などと記事を書いていたら今年の春のIPA試験はコロナの影響で中止になったようです。
外に出るのも憚られるこのご時世なので、休日は家に籠ってDBを動かしてみるのもいいかもしれません。
DB周りをいじっていて面白いことを見つけたらまた何か書きます。