落とし穴に立て札を立てるが如く

ハマりどころの解決が少しでも早くなることを願って書いていきます

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周りをいじっていて面白いことを見つけたらまた何か書きます。

Azureのメッセージングサービスに再入門 似ているサービスの違いを理解しよう

f:id:nam_yu_sql:20200228094745j:plain この記事は後ほどcloud.config techblogにマルチポストされる予定です。

はじめに

最近社内でMCP資格取得の機運が高まってきていて私の方でもAZ-203取得に向けて久々にAzureの学習を始めたところです。
AZ-203の試験範囲にはAzureのメッセージングサービスも含まれているのですが、これらのうちどういった時にどれを利用すればいいか迷ったりしませんか?
Azureのメッセージングサービスは大きく分けてQueue Storage、Service Bus Queue、Event Grid、Event Hubsの4つがあります。
今回はこれらのサービスについて特徴や使いどころについて纏めておきたいと思います。

MessageとEvent

まず、4つのメッセージングサービスを分ける大きな観点として、メッセージとして送るものがメッセージかイベントかというものがあります。
まず、メッセージとはその言葉のイメージ通り何かしら情報が入った小包のようなものです。
それ自体がデータとしてこれを受け取った側はその中に含まれるデータを使って処理を行います。
4つのサービスの中ではQueue Storage、Service Bus Queueがこれにあたります。
一方で、イベントはそのような送られた物自体を使って処理を行うものではなく、何かしらのイベントが起きたこと(例えば、Blob Storageにファイルが追加された、など)を伝えます。
付加情報として例えば追加されたBlob Storageのファイルに関する情報等が送られますが、そのファイル自体は送らず、その参照情報を送るので、イベントを受け取った側はそのファイルに対して直接操作を行うといった動作が可能になります。
4つのサービスの中ではEvent Gridと Event Hubsがこれにあたります。

MessageベースのQueue StorageとService Bus Queueの違い

Queue Storageの大きな特徴は、キューとしてAzure Storageを利用していることです。
Azure Storageは保存できる容量が莫大であるため、Queueに保持できるメッセージの合計容量の制限がほぼほぼありません。
一方でService Bus Queueは、キューのサイズに制限がありますが、メッセージをキューに入った順で確実に処理できるFIFOの仕組みなど、機能面で優れているという特徴があります。
キューのサイズは、パーティション分割の仕組みを利用して最大80GBまでで、その中に1メッセージあたり256kbのメッセージを送ることができます。
もしメッセージの合計容量がキューのサイズを超えると、後からやってきたメッセージはエラーとなってしまいます。
なので、基本的にメッセージの容量が合計で80GBを超えるならQueue Storageを利用し、それ以下であれば Service Bus Queueを利用するといった形になります。

EventベースのEvent GridとEvent Hubsの違い

Event HubsとEvent Gridの使い分けるシーンの大きな違いとしては、利用規模が挙げられます。
Event Hubsの主な利用用途はイベントの発行元が多数存在するようなビッグデータパイプラインです。
大量のイベントを高速で処理する必要がある際に利用され、Stream Analytics等を用いることでイベントを分析することもできます。
一方でEvent Hubsはよりシンプルで、イベント駆動のアプリケーションを作るのに向いています。
イベントの送信元には他のAzureサービスであるBlob Storage等を設定でき、イベントを受信したときに処理を行う側としてFunctionsなどを指定してやることで単純に○○が起きたら○○を行うといった動作の流れを作ることができます。

おわりに

今回の記事では自分のAZ-203対策も兼ねてAzureのメッセージングサービスであるQueue Storage、Service Bus Queue、Event Grid、Event Hubsとそれらの違いについて解説しました。
Azureのメッセージングサービスは大きく分けて4つあり、大きく分けるとメッセージを扱うものとイベントを扱うものがあります。
その中でさらに、メッセージの合計容量が大きい場合(80GBを越す)はStorage Queueを利用し、メッセージの容量が小さい場合やメッセージを受け取る側がFIFOでメッセージを受け取りたい場合はService Bus Queueを利用します。
イベントを扱うサービスにはEvent HubsとEvent Gridがあり、それぞれEventの発行元が多かったり分析用データの蓄積のために処理速度が必要だったりする場合はEvent Hubsを利用し、発行元が1箇所で決まっている場合等要件がシンプルな場合はEvent Gridを利用します。
それぞれのサービスの違いについてより詳しく知りたい場合はmsdnのドキュメントや、あるいはMicrosoft製品の学習サイトであるMicrosoft Learnでも取り扱っています。
Microsoft LearnではMicrosoft製品について分かりやすくて順を追って解説してくれているので入門の際の学習リソースとして便利なのでぜひ使ってみてください。
https://docs.microsoft.com/ja-jp/learn/modules/choose-a-messaging-model-in-azure-to-connect-your-services/index