Rebuild.fm で、少し前に WEB+DB PRESS が休刊になったと知った。
ウェブにも感想を書いているひとがいた(g, ddg)ので、自分もなんか書いておきたい。
自分はいわゆる「ウェブ業界」では仕事をしていなかったけれどよく課外活動でプログラミング寄りのブログを書いていたため、その縁で一年くらい連載をさせてもらった。
ウェブの人々は WEB+DB PRESS に感謝の意を伝えている。自分もかなりの恩恵を受けた利権者だから、謝意を示さないわけには行かない: その連載をきっかけに米系ブラウザ業者の目にとまり、オープンソースの仕事をすることになった。本当にありがたいことです。
自分はウェブっぽい企業で働いていなかったので、WEB+DB PRESS の話題は割と他人事だった。他人事というと聞こえが悪いけれど、キラキラした憧れの世界の話題だったとも言える。昔は、そういう人は多かったんじゃないかな。
時は流れ、ウェブっぽい仕事をする人が増え、キラキラしていたテクノロジ(クラウドとかモダン言語とか)は多くの人にとって日常になった。そうやってウェブテクノロジのサブカル性・ニッチ性・キラキラ性が失われるのにあわせ WEB+DB PRESS のような雑誌も役目を終えたのかなと思う。紙媒体や雑誌というのものがインターネットにやられてしまったというマクロな傾向は、もちろんあるんだろうけれど。
自分はというと、そんなご時世だというのに大企業のオレオレフレームワークとレガシーコードベース相手にアプリのしょぼいバグを直すような保守仕事をしているので、モダンなウェブテクノロジには未だ憧れがある。ただキラキラしたものは目が疲れるので、最近はじっと見つめることもなくなった。
Data Warehouse について考える:
前はなんとなく DW の ETL というのはログからゴミをとってクリーンにするくらいなのかと思っていたが、いま仕事で触ってるデータはそれより随分色々やっている。
たとえば食堂にアクセスログがあるとしたら、店に入って席について注文して飯食ってデザートは断ってチェックして帰る、コーヒーは二回足してもらった・・・という「来店」のような単位がきちんとモデル化されている。一方、素のログは個々のアクションがフラットに入っているだけである。
SQL マスターであればそういうフラットなログからモデル化されたビューを作ることはできるかもしれないが、素人が正しくやるのはかなりムリである。なのでビューなのかマテリアライズするのかはともかく組織として統一されたモデルが必要。でないとエンドユーザである機能開発者や PM ちゃんが雑なクエリを書いてデータを読み間違えたりする。
たとえばトイレをきれいにするにあたり改築前と改築後でトイレの利用頻度や滞在時間の違いを調べたい、統一さえた「来店」モデルがあれば、そこにしかるべき形でトイレ情報を足すのはわりかし簡単である。つまり ETL のコードを git blame して一つ前の変更を特定し、それをインテリジェントにコピペすればよい。
クエリするときも、整備されたモデルがあれば SQL はシンプルで、PM ちゃんが適当にコピペ SQL しても大きな問題はない。一方で素のログしかないと、昔データサイエンティストにもらった SQL を適当にコピペ改変して使う、しかしその SQL は古すぎてデータバグの回避コードが抜けている、みたいなダサい失敗がおこる。
データサイエンティストから貰った SQL で素のログをクエリしていたのは(PM ちゃんではなく)何年か前の自分なわけだが、よくなかったね。ある種のレイテンシの調査が目的でカネが絡んでいなかったからいい(だから適当にやっていた)けど、やはりゴミの除去とかは必要で、正しいモデルがあってしかるべきだった。が、なかった。
その後、できるチームメイトが DW をつくってくれたのでその手の仕事はラクになった一方、今思うと採用されていたモデルはそんなに良くなかったね。だから統一モデルのを持つ良さには思いが至らなかった。最近仕事で触っている DW はモデルよくできており、なるほどなと思う。
つまり DW にはデータのクリーンアップというミクロな役割とモデル化というマクロな役割がある。自分は前者は理解していたが、後者の有り難みをわかっていなかった。
ところで勤務先の DW は protobuf-based でモデル化されており、めちゃデータがネストしている。前のチームの DW はモデルを proto にべったり寄せるのに慣れていない人がモデルした感じで、それが(相対的な)イマイチさにつながっていたのだろうな。ネストしてると JOIN とかしなくていいのでクエリ書くのもスキーマ足すのもちょうラク。
こういうフラットでない OLAP は、曖昧な記憶によれば Multidimensional OLAP というような名前で呼ばれていた気がする。こういうののモデリングって何を読めば勉強できるのだろうね。なんとなく伝統的な OLAP の教科書ではない気がするんだけれど、そうでもないのかな。
このシラバスからはこの book chapter? が参照されている。が、あまりニッチを攻めようとふつうに data warehouse / olap の data modeling の教科書を探すのがいいのだろうね。DW について勉強したい気持ちは何年かに一回やってくるので、そのうちやる気の波に乗りたい。今は心の奥に積読いたします。
Mercurial 版の git rebase -i
+ edit みたいなもの。Mercurial によくあることとして Git よりは全然使いやすい。hg-evolve という拡張の一部になっている。まったくドキュメンテーションがないが、対話的ツールなので起動すれば間違えようなく使えます。
Android Studio はいつの間にか platform のコード (View とか) をステップ実行できるようになっていた。実行しているデバイス・エミュレータのバージョンと一致するソースコードを事前に SDK Manager でダウンロードしておく。
過去数年はクラウドにある VM + 手元のデバイスという組み合わせで開発していたのでデバッガは諦めていたが、今の仕事はエミュレータが使えるので、それにあわせデバッガも再び使い始めた。便利ですねデバッガ。
RxJava で main thread になんかさせるコードが関与する場合 Observable#blockingFirst() を使うとデッドロックしてしまう。そこで以下のようなかんじで subscription と retrieval を分離し、その間でタスクを flush する。
AtomicReference<String> result = new AtomicReference();
Disposable unused = yourSubject.subscribe(result::set);
shadowOf(getMainLooper()).idle();
assertThat(result.get()).isEqualTo("Expected");
- RxJava のコードには BlockingObsever というのがあるのでこれを使わせてくれれば解決なのだが、使えないので雑に AtomicReference で済ます。
- unit test 内でスレッドのタスクキューを空にする方法は色々あるっぽい。上の例は Robolectric のこの資料をもとにしている。この方法では background threads は待てない。
- Coroutine だとどうするんだろうね?ていうかテストフレームワークがいい加減非同期対応してほしいもんだわ JS とか 10 年前から対応してんだぞ。
追記
Coroutine はサポートがあるらしい。