サーバー部の紹介

こんにちは、Da Vinci Studio サーバー部の黒澤です。 サーバー部のことをたくさんの人に知ってもらいたく発信していくことにしたので、Da Vinci Studio サーバー部はどんな構成なのか、どんな技術で開発しているのか紹介したいと思います。

サーバー部とは

まず初めに、Da Vinci Studioの立ち位置から説明します。 Da Vinci Studioの業務は大きく分けて3つです。

  • くふうカンパニーグループ企業への技術支援
  • グループ外企業のサービス開発
  • Da Vinci Studio内の自社サービス開発

グループ企業への技術支援は、各社サービスのみんなのウェディングやオウチーノ、ヨムーノなどの開発を行なっています。 グループ企業はメディア系のサービス開発が多いため、グループ外企業のサービス開発では、水族館のサイト及びチケットシステム、飲食店で使われるモバイルオーダーシステムなど、グループ内で取り扱わない種類の開発に挑戦しています。 自社サービスはKotorというRSSリーダーや、くふうグループで利用するドキュメントツールや音声通話ツールを作成しています。

開発例

o-uccino.com www.sevensignatures.com anymarry.mwed.jp www.mwed.jp zaim.net www.o-uccino.jp remotework-kufu.com oyako-kufu.com

Kotor

Kotor

  • Da Vinci Studio
  • ニュース
  • 無料
apps.apple.com

チーム体制

サーバー部はこれらのサービス開発で実装を行なっている部署です。 2022年3月現在、サーバー部の中には3〜5人の3つのチームが存在し、そのチームで各プロジェクトを担当しています。 プロジェクトを行う時はこのチームにデザイン部とSRE部のメンバーが加わり、プロジェクトチームが出来上がります。

サーバー部のメンバー

人数

13人 Da Vinci Studioの中では一番人数の多い部署です。

男女比

男性10人 女性3人

エンジニアの経験年数

11年以上 2人 、6~10年 3人、 4~5年 3人、 3年以下 5人、 新卒1人で、多くが20~30代です。

担当しているプロジェクトの進め方

サーバー部内のチームごとに大まかに開発を担当する会社が分けられています。 グループ企業の開発が多いチーム、外部企業の開発が多いチームなど。 また複数の企業のプロジェクトが並行して進行しているため、それぞれのメンバーもバランスは違えど2~3つのプロジェクトを担当している人が多いです。 並行して進行しているプロジェクトは、メインの開発プロジェクトと過去に開発したプロジェクトの保守や次のプロジェクトの準備などバランスを取っています。

多くの場合はサーバー部内のチームごとにプロジェクトを担当していますが、プロジェクトの規模や期間によっては他チームとの混成チームを作成してプロジェクトに取り組むこともあります。 2022年3月現在、私も混成チームでプロジェクトに取り組んでおり、チーム構成は臨機応変に対応しています。

サーバー部の技術スタック

サーバー部のエンジニアの多くは、グループ会社のみんなのウェディング(現エニマリ)やオウチーノ出身のエンジニアが多いため、技術スタックも引き継いでいます。 どちらの会社もRuby on Railsで開発されていたサービスなので、今のDa Vinci Studioでも開発されるサービスは新規開発も含めて多くがRuby on Railsで作られています。

多くのプロジェクトで使われている技術は - サーバーサイドはRuby on Rails - フロントはhamlとscssとバニラのJavaScript(Reactも増加中) - DBはMySQLかPostgreSQL

私が所属していたみんなのウェディングでは、新卒のエンジニアを多く採用しており、彼らの育成を行ないながら開発を行う必要があったことから、シンプルなRuby on Railsの構成になっていました。 Da Vinci Studioでも基本的な構成は変わらなかったため、シンプルで学習コストは低いというメリットはあったものの、新しい技術トレンドを追いづらいことや、各サービスがモノリシックにできていることからライブラリの更新等のメンテナンスに課題があるといったデメリットも見えてくるようになりました。

サーバー部の今後の展望

エンジニアメンバーが様々な経験を積んできたことにより、技術スタックの更新の余地が出てきたため、少しずつではありますがサーバー部で以下のの技術を取り入れていきたいと考えています。

React

すでにいくつかのサービスではフロントにReactを導入しているサービスがありますが、今後利用を増やして経験値を貯めていきたいと考えています。 今までのDa Vinci Studioで開発するプロジェクトはメディア系のサービスが多く、フロントの表現についてはあまりリッチなものが求められることが少なかったため、バニラのJavaScriptで事足りることが多く他の選択肢をあまり取っていませんでした。 その中で外部企業のプロジェクトにも開発するようになり始め、メディア以外のサービスの開発も行うようになり、少しずつフロントの要件も複雑化してきたためReactを使うプロジェクトも増え始めました。

マイクロサービス

各社のサービスをそれぞれRuby on Railsでモノリシックなアプリケーションとして開発しているので、同じ機能でも各リポジトリで個別に実装されていました。 個別の実装で工数がかかることはもちろんですし、機能によっては利用されるマスターデータの更新やライブラリの更新も個別に行う必要がありました。 そこで複数のサービスで利用できそうな機能はマイクロサービスとして切り出し、APIとして各サービスに提供するようにしていこうと考えています。 小さく実装できるものから取り組んでおり、現在はAmazon API GatewayとAWS Lambdaでサーバーレスアプリケーションとして実装を進めています。

さいごに

今回は今のサーバー部はどのような構成でプロジェクトの開発をしており、技術面では今後どの様な方向に進んでいこうと考えているか紹介しました。

また、Da Vinci Studioデザイン部が発信するnoteやサービスの開発ストーリーもあるので、こちらも読んでみてください。

Da Vinci Studio では一緒に働ける仲間を絶賛募集中です。 興味のある方は こちらrecruit@da-vinci-studio.net までご連絡ください。

データの民主化推進のためのダッシュボード整備のススメ

インフラ基盤部データ分析チームの濱口です。最近わが家のキッチンにグリルが導入され、暇があれば魚ばかり食べています。
今回はグループ会社 Zaim での、データ民主化の推進のための Redash のダッシュボード整備に関してまとめていきます。

背景

現在 Zaim のデータ分析チームでは、分析環境の改善による分析効率向上やデータの信頼性向上に努めています。その中の活動の1つに「データ民主化の推進」があります。ここで挙げている「データの民主化」とは一般的に、一部の専門家のみが扱えていたデータの利活用を、データに関する詳細な知識を持たない人でも扱えるようにする環境を整備することを指します。
Zaim における「データ民主化の推進」の目的としては

  • データ分析チームへのデータ抽出依頼を減らしたい
  • 各チームやクライアントへデータや分析内容をより迅速に届けたい

などがあります。誰でも簡単にデータを使えるようにして、全体の分析効率を向上させたいということですね。

やっていること

現在、民主化の推進としては

  • Redash のダッシュボード整備
  • SQL勉強会の実施
  • BIサービスの導入の検討

などを行なっています。今回はその中でも Redash のダッシュボードの整備 についてまとめていきます。

Redash のダッシュボード整備

くふうグループでは、多くの会社がBIツールとして Redash を利用しています。Redash ではクエリでデータを抽出して、簡単に可視化まですることができ、可視化したグラフや表を組み合わせることでダッシュボードを作成できます。

f:id:da-vinci-studio:20211228112808p:plain
整備したダッシュボードの一例

ダッシュボードを整備する手順としては

  • ダッシュボードの目的や要件を利用想定ユーザーにヒアリングする
  • 必要なクエリを作成し、データを可視化する
  • ダッシュボードにまとめる
  • 利用想定ユーザーに実際に使用してもらい、フィードバックをもらう
  • フィードバックをもとに改善する

で進めています。

ダッシュボードの目的や要件をヒアリングする

目的や要件をヒアリングして、必要なデータを洗い出します。

  • データの切り口
  • どういう指標をみるか
  • 具体的な利用シーン
  • 利用発生頻度

などを確認し、要件をより具体的にしていきます。

必要なクエリを作成し、データを可視化する

目的や要件について具体的になったら、クエリを作成して必要なデータを集計していきます。日付など検索したい項目に関しては、以下のようにパラメーターにしておくことで任意の範囲でデータを集計できるようにします。

between '{{period_start}}' and '{{period_end}}'

追加するクエリ間で同じ属性がある場合、パラメータ名を揃えておくとダッシュボードに追加する際にパラメータをまとめることができて便利です。

また集計したデータは、必要に応じて適切なチャート表現で可視化します。棒グラフや折れ線グラフはもちろん、ピボットテーブルやヒートマップなど可視化の種類が豊富なので、用途に合わせて適切な表現を選びます。

ダッシュボードにまとめる

レイアウトにも気を配りつつ、表やグラフをダッシュボードに追加していきます。必要に応じて、使い方や注意点などをコメントとして残していきます。
またダッシュボードのパラメータ名なども分かりやすい名前に変更して追加します。クエリ上の表記のまま英語にしてしまうと、慣れていない人たちにとっては途端に使いづらくなってしまいます。

実際に使用してもらい、フィードバックをもらう

利用が想定されるユーザーに実際に使ってもらい、疑問点や使いづらい点などフィードバックをもらいます。作った側からすると使いやすい完璧なダッシュボードを作れたと思っていても、使う側からすると案外使いづらかったりします。これまでだと

  • 検索項目が分からない
  • どういうふうに日付を指定すればいいのか分からない
  • 指定しないといけないパラメーターが多すぎて、複雑でよく分からない

などのフィードバックがありました。1つのダッシュボードで色んなデータを出せるようにする(機能性を上げる)と、その分パラメーターが増えたり検索項目が複雑になったりして操作の難易度も上がります。利用想定ユーザーによっては、ある程度の機能性を保ちつつも、操作性を損なわないように気をつける必要がありそうです。

フィードバックをもとに改善する

上記のフィードバックをもとに改善していきます。例えば「パラメーターが多すぎて使いこなせない」という場合は、再度目的や要件をヒアリングし直して、データの切り口などを整理し、優先度の低いパラメータを削減したりします。

結果

結果として

  • 定期的に発生しているいくつかのデータ抽出依頼の工数がゼロになった
  • 分析チーム以外の人たちが、自分で Redash からデータを抽出する動きが増えてきた

などが見られました。まだまだ整備途中ですが、既に目に見える形で効果が出てきました。 ダッシュボードの整備以外の施策も進めることで、Zaim 全体のデータの民主化を進めていこうと思います。また Zaim で貯まった知見をくふうグループに展開することで、グループ全体のデータ民主化の推進にも繋げたいと思います。

最後に

Da Vinci Studio では一緒に働ける仲間を絶賛大募集中です!募集職種と詳細に関しては、以下のリンクからそれぞれ確認できます。

一緒にデータ分析してくれる方はもちろん、コードをゴリゴリ書いて開発したい、マネジメントでチームの成果を最大化したい、多種多様なサービスのインフラ構築に携わりたいなど興味のある方はお気軽にご連絡ください。
また、以下は弊社エンジニア・デザイナーのインタビュー記事になります。

kufu.co.jp

www.wantedly.com

AWS GameDayに参加してきた話

Da Vinci Studio インフラ基盤部の井手です。 いよいよ re:Invent2021 が始まりましたね!

11/3(土)に AWS GameDay という最高に楽しいイベントに参加してきました。 チームで参加して手を動かしながらワイワイして、さらに学びにもなるという素晴らしいイベントだったので、参加の報告と感想をまとめようと思います。

参加の経緯

概要については AWS Japan の記事にもありますが、ざっくり言うとお題に沿ってシステムを構築しつつ、ゲームをこなして得点を競うコンテストです。 例年 re:Invent の現地会場では開催されているようですが、他社の技術ブログを見る限り国内でも定期的に催されているようです。 今回は AWS Japan の方よりお誘い頂いたインターネットメディア系の企業数社(約40名11チーム)のみのクローズドなイベントだったようでした。 ゲームのネタバレ禁止とのことなので、具体的なサービス名やどういう対応をしたかには触れない形で書いていきます。

ゲームについて

ゲームの流れをざっと説明します。 クエストと呼ばれる AWS のサービスに関するクイズやお題に回答して、まずトークンを稼ぎます。 そのトークンを消費して、ユニコーンを育てる設備をアンロックして、設備(クラウドインフラ・Web システム)構築をしていきます。 設備を沢山構築出来ると、稼働するユニコーンの数が増えてコイン稼げます。 そうやって育成したユニコーンはポロリーグという競技に参加して他チームのユニコーンと戦ってきて、勝利するとコインをさらに稼げるという感じでした。 育てたユニコーンは売買することも可能でした。 最終的にはコインの合計で順位が決まります。

また、コインの合計の総合順位の他に、

  • ポロリーグでの最多勝利
  • 売買による利益
  • 最短時間で最も多くのクエストをクリア
  • Well Architected Framework に沿っている度合い

等のいくつかの目標が提示されていたので、そのどれかの目標で入賞することを狙ってゲームをプレイすることも出来ました。

やったこと

事前準備

インフラ基盤部から SRE 2名、サーバー部からサーバーサイドエンジニア2名の合計4名の有志を募って参加しました。 サーバーサイドエンジニアはそれぞれ、私と同期の19卒1名と20卒1名が参加してくれました。 参加前の準備は社内の Slack にチャンネルを用意して、ルール説明の資料に目を通したのみでした。 チーム名すら開始直前にノリで決めました。 当日は各自自宅からの参加で、Slack のハドルで通話・画面共有をして進めました。 可能な場合はオフィスに集まってホワイトボードなどが使える環境にしておくと、限られた時間で密にコミュニケーションを取り、ゲームを進めていく上では便利だと思います。構築作業を分担する場合はネットワーク構成をお互いに理解していないと思わぬタイムロスを生んでしまうと感じました。

ゲーム序盤

30分程度のルール説明のあと、3時間半程度ゲームに取り組みました。 私達のチームは普段 AWS を触っていないメンバーもいたので、序盤は最も慣れている SRE メンバーが画面共有をしてクイズの解説・補足や構築の説明などをしながら、ゲームをどう進めていくかの共通認識を醸成していきました。 ゲーム中盤から分担して各自でタスクをこなしていきました。

ゲーム中盤〜終盤

出題範囲は幅広く、EC2・RDS・S3・VPC・CloudWatch のような基本的なサービスからコンテナ・サーバーレス・ML・IoT まで様々でした。 分担し始めてから、集中して作業しているとあっという間にタイムアップを迎えたので、もう少し長くゲームをしたかった!とチームで惜しんでいました。

結果

私が構築を担当したものは、サービス自体はサクッとデプロイまでいけました。しかし、コストまたはセキュリティ面で修正点がある、という警告メッセージを1つ解決出来なかったものがあり悔いが残りました。 最終スコアは例年の平均程度に達していたようなので、エンジョイ勢としては健闘したと思っています。

感想

私は実務での AWS 経験は1年少しなので、参加前は触ったことのないサービスでのインフラ構築や障害対応などにうまく対処出来るだろうか?と不安でしたが、杞憂に終わりました。 ゲームについては、設定が作り込まれ過ぎていて事前に資料を読んでも正直内容の想像がつかなくて不安でした。しかし、当日の説明を聞けば分かるのでほとんど準備なしで参加して問題ないと思います。 全員が AWS のサービスを触り慣れている場合は、序盤に戦略と各自の担当範囲を決めて、分担してタスクをやり込んでいけば上位を目指せると思います。時折罠が仕掛けられていますが、脚注まで丁寧に README を読めば大体解決しました。また、IaC に慣れ親しんでいる人は手動構築に戸惑うこともあるかもしれません。日頃の業務と違ってじっくり調査せず、ゲームのためにラフに構築していって、コンピューティングリソースを無駄遣い出来てしまうのが背徳感があって個人的には楽しかったです。使ったことのないサービスに触れて勉強になる場面も有りました。

AWS をあまり触ったことのないサーバーサイド・アプリ等のエンジニアの方も、業務と違って壊しても全く問題ない環境で手を動かせる良い機会だと思います。 序盤の画面共有しながら構築をしていたところを見ていたサーバーサイドのメンバーから、どうやってインフラが構築されていくのかを見ることが出来て刺激になったという声もありました。 興味があれば是非参加して、楽しみながらAWSを学んでみて下さい!

久々のこういったコンテスト形式のイベントでしたが、Slack や表彰式でワイワイしていた GameDay 参加経験のあった企業や複数チーム参加していた他社のエンジニアの方々から触発されて、本当に良い場でした。 次の機会があれば、インフラ経験者をもっと誘ったり、複数チーム参加したりして、上位を狙っていきたいと思います。

さいごに

Da Vinci Studio では一緒に働ける仲間を絶賛大募集中です!募集職種と詳細に関しては、以下のリンクからそれぞれ確認できます。

【エンジニアリングマネージャー】

【サーバーサイド】

【SRE】

【データ分析・機械学習部門マネージャー】

【データサイエンティスト】

【機械学習エンジニア】

マネジメントでチームの成果を最大化したい方、コードをゴリゴリ書いて開発したい方、多種多様なサービスのインフラ構築に携わりたい方、GameDay のようなイベントに一緒に出てくれる方をお待ちしております。

また、グループの持株会社である(株)くふうカンパニーでは、新卒エンジニアの採用も行っています。興味のある方はご連絡ください。

【23卒エンジニア】

分析チームで技術ブログを更新し続けるために最初にやったこと

Da Vinci Studio 分析チームの濱口です。
Da Vinci Studio の分析チームでは、少し前から定期的にブログを書いて、チームに溜まった知見を社外に公開しています。継続してブログを更新するためにやったことをまとめようと思います。

背景

分析チームの方針として

  • 社外の新規案件を獲得したい
  • 将来的には仲間を増やしたい

の2つがありました。そのためには分析チームがどんな活動をしているのかをあらゆる手段で発信して、もっと社内外にアピールする必要がありました。その手段の1つとして、分析チームがどんな技術を使っていて、どんな工夫をして日々アウトプットを出しているのかを技術ブログで発信すると良いのではと考えていました。

ブログを更新していくためにやったこと

「ブログを更新していくためにやったこと?技術ブログなんて書いて公開するだけでは?」と思う方もいるかもしれません。
弊社の技術ブログ(2021年4月時点)を確認してみると

f:id:da-vinci-studio:20210930155201p:plain
2021年4月当時のブログの最新記事

2020年7月3日が最後の更新となっており、9ヶ月くらい放置されている上に2記事しか投稿されていませんでした。ブログ開設当初は「書きたい人が主体的に書いていこう!」という感じで始まった技術ブログでしたが、ほとんど投稿されず幽霊ブログになってしまっていたのでした。
というわけで、これまでと同じような運用だと続かないと思い、分析チームで技術ブログを投稿し続けるために以下のことをやりました。

  1. 技術ブログの運用事例を集める
  2. 執筆計画を立てる
  3. 率先して自分から書き始める

ブログが更新されていないのは全社的な問題ですが、とりあえずは分析チームとして小さく切り込んでいくことにしました。

1. 技術ブログの運用事例を集める

世の中の多くの企業が技術ブログをやっていて、同じように技術ブログの運用に苦労しているところもあるのではないかと思い、まずは他社の事例をいくつか集めました。

調べてみるとほとんど多くの企業が、何かしらの運用の仕組みや計画をしっかり立てて技術ブログを運用していることが分かりました。その中でも

社内技術ブログのはじめかた - Gunosyデータ分析ブログ

の記事が、チーム内ですぐに実践できそうで、最初のステップとしてはとても参考になりました。

2. 執筆計画を立てる

というわけで、上記の事例をもとに運用計画を立てていきます。具体的には

  1. ブログを書く目的を確認する
  2. 目的に沿って、読者のペルソナを考える
  3. ペルソナごとに記事のネタを洗い出す
  4. 執筆担当を決める
  5. どれくらいの頻度で出していくかを決める

の順番でやっていきました。今回は記事ネタを洗い出して担当を決めるところまでやって、スケジュールに関しては厳密に定めませんでした。

1. ブログを書く目的を確認する

目的は背景でも挙げましたが

  • 社外の新規案件を獲得したい
  • 将来的には仲間を増やしたい

の2つです。上記をもとに読者のペルソナを考えたいと思います。

2. 目的に沿って、読者のペルソナを考える

2つの目的に対してそれぞれペルソナを考えました。

  • 社外の新規案件を獲得したい

    • サービスとかのグロース担当
    • 日本在住
    • 分析の知識あんまりない
    • 日本の企業とか行政で、グロース、マーケティング、分析担当のいずれか
  • 将来的には仲間を増やしたい

    • 中途
    • 23~32歳
    • 日本在住
    • 企業や行政で分析担当、機械学習担当、データインフラ担当
    • データ分析、分析基盤の保守・運用、BIツールの利用経験有

あまり難しく考えすぎず、どんな人から案件を獲得して一緒に仕事をしたいか、どんな人が今のチームにいたら助かるかなどから想像してざっくりで出していました。

3. ペルソナごとに記事のネタを洗い出す

続いて、上記をもとに記事のネタを洗い出していきます。

  • 社外の新規案件を獲得したい

    • 分析基盤整備の話
    • サービスグロースの話
    • データドリブンな施策の話
  • 将来的には仲間を増やしたい

    • BIツールの話
    • 分析SQL運用についての話
    • チームでの取り組みの話

社外の新規案件を獲得したい向けには案件や施策実施についての全体の話を、将来的には仲間を増やしたい方向けには具体的な技術の話やチームでの取り組みの話などをできると良さそうという風に考えて洗い出しました。
このタイミングでとりあえず思いつく限りを出していますが、新しく思いついたら随時リストに加えています。

4. 執筆担当を決める

ネタを洗い出した後は、誰がどの記事を書いていくのかを決めました。
執筆スケジュールに関しては各々に任せた運用になっていますが、その代わりにチームとしてどれくらいの頻度で記事を投稿していくかを決めていて、現状では 1~2 投稿/月をノルマとしてブログを更新しています。分析チームのメンバーは3名なので、それぞれのリソース配分を気にしながら書ける人が書くような流れができています。

3. 率先して自分から書き始める

執筆計画を立てたら、あとはひたすら書いていきます。チームメンバーにもしっかり書いて欲しかったので、旗振り役の自分が率先して書きました。

結果

半年ほど運用してみた結果、分析チームとしては、1~2 投稿/月 のノルマを大方クリアできており、継続的に社外へ発信できています。また分析チーム以外の他のチームでもブログを書いて発信する動きが少しずつ出てきています。
具体的に採用や案件獲得という結果には繋がっていませんが、継続的にブログの更新を続けていくことで中長期的に結果として表れるのではないかと考えています。

次にやること

正直なところ、現状の投稿頻度をデータ分析チームだけで維持するのは結構大変です。また先にも述べましたが、ブログが更新されていないこと自体は全社的な問題です。なので次にやることとして

  • 分析チーム以外の投稿も活発にする
  • 活発な状態を全社的に継続する

の 2 点が必要だと思っています。 現状の技術ブログは分析チームが率先して投稿しているので、多くの投稿がデータ分析に関連する内容になっています。しかし Da Vinci Studio にはデータ分析以外にもサーバーサイドやアプリ、インフラ、デザインなどの部署が存在し、サービス開発を行っています。データ分析に関連する投稿だけでなく、他の部署の投稿も活発にできれば、どんなことをやっている会社なのかをちゃんと知ってもらえるようになります。また投稿が活発な状態も継続することができ、技術ブログをよく書いている会社と認知されて、会社全体の技術ブランディングも良い方向に進み、採用や案件獲得に繋がるのではないかと思っています。
他の部署の活動も発信されるように、ブログ等の社外へのアウトプットの啓蒙であったり、会社全体の投稿を活発化させる仕組みの構築が必要だということが見えてきました。

まとめ

分析チームでのブログ運用についてまとめました。
分析チームの方針だけでなく会社全体の技術ブランディングも含め、今後は全社的に技術ブログでの発信を活発化させていく必要があると感じました。他部署のメンバーへのヒアリングなどを行い、施策の実施や仕組みを構築していきたいと思います。

さいごに

Da Vinci Studio では一緒に働ける仲間を絶賛大募集中です!募集職種と詳細に関しては、以下のリンクからそれぞれ確認できます。

コードをゴリゴリ書いて開発したい方、マネジメントでチームの成果を最大化したい方、多種多様なサービスのインフラ構築に携わりたい方、それ以外の方でも興味のある方はご連絡ください。

GitHub リポジトリに貯めていく分析 SQL 運用

リポジトリにためていく分析SQL運用

Da Vinci Studio 分析チームの濱口です。
分析チームでは各々が書いた SQL をドキュメントにまとめて GitHub リポジトリに貯めて共有しています。この試みを始めてから1年ほどたったので、運用してみて感じたことや気づいたことについて紹介しようと思います。

背景

SQL を GitHub リポジトリに貯め始めたのは、以下のような問題意識からでした。

レビューの枠組みがなかった

ちゃんとした枠組みがなく、タスク管理ツール上で雑に行われていたり、そもそもレビューが行われていなかったりという状態でした。このような状態が続いてしまうと、SQL のミスやデータの誤りに繋がってしまい、データの信頼性が損なわれてしまいます。

書いた SQL が集約されていなかった

様々なところでレビューされていたりされていなかったりで、それぞれの書いた SQL がどこにあるのかがわかりづらい状態でした。他の人が書いた SQL を参考にしたり再利用したりするのにも一苦労で、とても非効率です。

GitHub リポジトリに貯めるまでの流れ

貯めるまでの流れですが、特に特別なことはなく

  1. プルリクエストを作成する
  2. レビューをもらう

という手順になります。

1. プルリクエストを作成する

マークダウン形式のファイルに作成した SQL の概要、実際に書いた SQL などを記載したプルリクエストを作成します。ディスクリプションには、データ抽出の目的と SQL を実行して抽出したデータを記載し、データの数値についても確認できるようにしています。

2. レビューをもらう

チームメンバーからレビューをもらい、SQL やデータに誤りがないかチェックします。
ディスクリプションにレビューのチェック項目を設けており、その項目に沿ってレビューを行うことで漏れが出ないように対策しています。最低でも1人から Approve もらって問題なさそうであればマージします。

レビューのチェック項目

運用してみて

  • クエリのミスやデータのエラーに気づけるようになった
  • 他の人が書いた SQL を再利用しやすくなった

といったように、当初抱えていた問題は解消できました。
しかし、運用する上でまたいくつか別の課題が出てきました。

参考にしたいファイルが見つからない

最初のうちは良かったのですが、ファイルがどんどん増えていくうちに参考にしたいファイルを見つけるのが困難になってきました。
解決策として、全てのファイルを同じ 1 つのフォルダに貯めていたのを、外部と内部の案件別で分割した上で、さらにデータマートごとにクエリを分けるようにしました。

レビューが滞る

データの抽出内容によってはかなり長い SQL になることもあり、とにかくレビューが大変でした。 レビューが大変だと後回しにされがちで、レビューが滞るという問題が出てきました。
この問題に関しては

  • SQL のコーディングスタイルを定める
  • 再利用できる箇所は切り出して共通化する

などを行っており、現在も改善を続けています。 上記2つの改善についてはいくつか別のブログにもまとめています。

blog.da-vinci-studio.com

blog.da-vinci-studio.com

まとめ

  • プルリクエストによるレビューを実施することで、データの信頼性向上につながった
  • GitHub のリポジトリに集約することで他の人が書いた SQL を再利用しやすくなった

運用していて出てきた新たな課題についても、さらに改善していきたいと思います。

We are hiring!!

Da Vinci Studio では一緒に働ける仲間を絶賛大募集中です!募集職種と詳細に関しては、以下のリンクからそれぞれ確認できます。

Core Web Vitals 数値の改善

Da Vinci Studio 第 2 サーバー部、社会人 2 年目の吉延です。 今回は最近開発してリリースしたばかりの 『ごっこランドTimes』で行った Core Web Vitals(CWV) 数値、その中でも First Contentful Paint(FCP) と Largest Contentful Paint(LCP) 数値の改善に焦点を当てた施策について紹介します。『ごっこランドTimes』は子どもの興味・関心を伸ばし、親子で一緒に楽しめる情報が満載のメディアです。Web フレームワークとして Ruby on Rails を用いて開発しています。

背景

SEO 対策はサイトへの集客アップのため重要なのは既知の事実かと思いますが、2021 年 6 月から CWV も Google の検索ランキングの要因となります。 ( 詳しくは Google 検索セントラルブログ を参照してください。) CWV はユーザー体験をより良いものにするために Google が提唱しているコンセプトで、表示速度、反応速度、表示の安定性の 3 つ要素に焦点が当てられています。そのため、表示ズレやサイトスピード改善はより重要となります。これらのスコアや細かな指標は PageSpeed Insights で測定することができます。

改善前の状態

対象のサイトは表示ズレに関わる Cumulative Layout Shift(CLS) のスコアは良かったので、表示速度に関連する FCP と LCP に焦点を当てて改善を行いました。 改善前のスコアを計測してみたところ、 FCP の良好とされるスコアは 1.8s 未満、 LCP は 2.5s 未満とされているのでかなり悪いことがわかります。現状は広告も入っていない状態にも関わらずこの状況なので、将来的に広告が入った場合さらにスコアが下がることが予想されます。

  • TOP ページ
    FCP : 6.7s
    LCP : 9.2s
  • 記事ページ
    FCP : 7.1s
    LCP : 9.5s

f:id:da-vinci-studio:20210702122623p:plain:w640
改善前のTOPページのスコア
f:id:da-vinci-studio:20210702120809p:plain:w640
改善前の記事ページのスコア

改善の方針

ではどんな施策をすればよいのだろう?となるのですが、それについては PageSpeed Insights の「改善できる項目」が参考になります。どの項目に対する施策を打つのかについては各サイトの性質によって異なると思うので、そちらを考慮した上で項目を選択してください。対象のサイトでは

  • レンダリングを妨げるリソースの除外
  • 使用していない JavaScript, CSS の削除

に対応した施策を打ちました。

施策一覧

検討した施策は以下となります。

  • Web フォントを除外する
  • 表示処理に関係のない JavaScript の読み込み順番の変更
  • 使用していない JavaScript の削除
  • 表示サイズが小さい画像の Retina 対応をやめる
  • オフスクリーン画像の遅延読み込み
  • ページごとに CSS を分割する

各施策の詳細

Web フォント ( Google フォント) の使用をやめる

こちらが一番効果があると思います。 Web フォントを使用しているのであれば一番に検討すべき施策です。 Web フォントを外すだけで対象サイトの記事ページでは以下のようにスコアが改善されます。

  • FCP : 7.1s → 1.7s
  • LCP : 9.5s → 2.7s

f:id:da-vinci-studio:20210702122842p:plain
Web フォントありのスコア
f:id:da-vinci-studio:20210702122905p:plain
Web フォントなしのスコア

しかし、 Web フォントを外すとサイトの印象がガラリと変わってしまうので、そのあたりを十分に考慮した上で Web フォントを使用するかどうか検討すべきです。一部の固定の文字のみに Web フォントを使用したい場合は URL に &text= を付けて当てたい文字を記入すればサブセット化されるので、少量のフォントの呼び込みで済みます。

<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@500&display=swap&text=フォントをあてる文字" rel="stylesheet">

表示処理に関係のない JavaScript の読み込み順番の変更

JavaScript を外部ファイルとして HTML で読み込む場合、記述順に呼び込まれます。なので表示処理に関係のないファイルはなるべく最後に呼び出したほうが良いです。そうすることでファーストビューの描画が早くなり、 FCP や LCP のスコア改善につながります。対象のサイトで表示に関係ないものをなるべく body 要素に近い場所で呼び出すようにしました。

使用していない JavaScript の削除

余計な JavaScript を読み込むと表示に時間がかかる場合があります。なので使用していないものは気づいたら削除しておくのが良いと思います。不要なファイルの見つけ方として Google Chrome の検証モードを用いるのが良いと思います。 検証モード内の Network 項目を見ると、呼び出されいる js ファイルのサイズや処理時間の一覧を見ることができるので、不要な js ファイルや処理に時間がかかっているファイルを見つけることができます。また、ネットワークスピードを Fast 3G にしておくと、 PageSpeed Insights のネットワーク環境に近づけることができます。対象サイトでは active storage や action cable を使っていませんでしたが、 rails new 時に skip し忘れていたので残っていました。

f:id:da-vinci-studio:20210702123127p:plain

表示サイズが小さい画像の Retina 対応をやめる

サイトで使用している画像は Retina ディスプレイ対応させるため、元の画像サイズを表示されるサイズの 2 倍の大きさにしていることが多いと思います。もちろんこの対応すると読み込むデータ量が増えるため、表示スピードが遅くなる可能性があります。なので比較的 Retina 対応の影響が少ない、表示サイズの小さい画像の元サイズを表示サイズと同じにすると速度改善する場合があります。

オフスクリーン画像の遅延読み込み

オフスクリーン画像を最初のロード時に読み込む必要がないので、それらの画像を遅延読み込みするのが良いです。 JavaScript で遅延読み込みを行う方法もありますが、 HTML5 の標準仕様の loading 属性を使って画像に loading=lazy を付与するだけで HTML だけで遅延読み込みを行うことができます。

<img width="116" height="116" alt="" loading="lazy" src="image.png">

ページごとに CSS を分割する

  • app/javascript/packs/application.js
require("stylesheets/application")
  • app/views/layouts/application.html.haml
= stylesheet_pack_tag "application"

上記のようにとすべての CSS ファイルと一度に読み込んでいませんか?このようにすると当然、無駄な CSS も多数読み込むようになります。そこで各ページごとで読み込む CSS を分割する方法があります。各ページに対応したエントリーポイントとなる js ファイルを用意してそのファイルの中で必要な CSS のみを呼び込むようにします。

  • app/javascript/packs/article.js
import "../stylesheets/article.css"

そして各ページに対応する view ファイルから対象の js ファイルを呼び出します。

  • app/views/articles/show.html.haml
= stylesheet_pack_tag 'article', media: 'all'
= javascript_pack_tag 'article'

このようにすることで無駄な CSS 読み込みを避けることができます。規模が大きなサイトほど効果がある施策だと思いますが、大きくなってからだと対応が大変になるので、規模が小さいうちから対策しておくことをオススメします。

結果

対象のサイトでは開発環境でスコア改善が見られた以下の施策を実施しました。

  • 表示処理に関係のない JavaScript の読み込み順番の変更
  • 使用していない JavaScript の削除
  • オフスクリーン画像の遅延読み込み
  • ページごとに CSS を分割する

対象のサイトでは Web フォントを除外してしまうとサイトの印象が大きく変わってしまうため、 Web フォントは除外しませんでした。以下が対策後の数値です。良好なスコアにすることはできませんでしたが、 LCP は対策前と比べると TOP ページでは約 13% 、記事ページでは約 22% ほどスコア改善することができました。

TOP ページ

  • FCP : 6.7s → 6.5s
  • LCP : 9.2s → 8.0s

f:id:da-vinci-studio:20210702122623p:plain:w640
改善前のTOPページのスコア
f:id:da-vinci-studio:20210702122512p:plain
改善前のTOPページのスコア

記事ページ

  • FCP : 7.1s → 7.1s
  • LCP : 9.5s → 7.4s

f:id:da-vinci-studio:20210702120809p:plain:w640
改善前の記事ページのスコア
f:id:da-vinci-studio:20210702120418p:plain
改善前の記事ページのスコア

まとめ

ごっこランドTimes』 で行った CWV 数値、中でも FCP と LCP 数値の改善に焦点を当てた施策について紹介しました。サイトによって効果がある施策、ない施策は異なると思うので、まずは試してみると良いと思います。

コーディング規約を定めて SQL の可読性を上げる

Da Vinci Studio データ分析チームの濱口です。
現在データ分析チームで運用されている SQL のコーディング規約について紹介します。

なぜコーディング規約を定めるのか

SQL のコーディング規約を定める主な理由として、 可読性を上げるというのがあると思います。 スタイルを統一せず、書き手によって異なるスタイルで書いていると以下のような弊害が発生します。

レビューしづらい

他の人が書いた別の作業の SQL というだけでも読みづらいですが、コーディングスタイルが揃っていないとさらに読みづらくなってしまいます。 そうするとレビューにも時間がかかってしまい、他の作業に割ける時間が短くなってしまいます。

再利用しづらい

Da Vinci Studio の分析チームでは、過去に書いたクエリを GitHub のリポジトリに貯めており、他の人も再利用できるようにしています。 しかし SQL が読みづらいとバグも発生しやすくなり、かえって作業効率を悪くしてしまいます。

どんな SQL に適用すべきか

他の人が読む可能性がある SQL は全て、定めたコーディング規約に則って書くことにしました。具体的には

  • 他チームからの依頼の SQL
  • アプリケーション内で利用される SQL

などを指します。個々人のアドホックな分析に関しては、必ずしもスタイルガイドに沿わなくてもいいというルールにしました。

コーディング規約

以下で定めているコーディング規約をいくつか紹介します。
なお、今回は分析チームで主に利用されている BigQuery の利用を前提としたコーディング規約になっています。

予約語は小文字で書く

# NG
SELECT
  name,
  comment,
FROM SAMPLE.table
WHERE
  name = 'name1'

# OK
select
  name,
  comment,
from SAMPLE.table
where
  name = 'name1'

SQL の予約語は大文字で書く文化が広く浸透しており、大文字で書く人はかなり多いかと思います。 しかし上記を踏まえた上でも、小文字で書く方が良いと思った理由として

  • 予約語だけ大文字で書くのめんどくさい
  • 予約語だけ大文字で書いても可読性は変わらない

の2点でした。可読性が変わらないのであれば、予約語だけ大文字で書くメリットはないという結論に至りました。

select 句のカンマの位置は行末

# NG
select
  name
  , comment
  , date
from SAMPLE.table

# OK
select
  name,
  comment,
  date,
from SAMPLE.table

このルールは可読性というよりは、試行錯誤の効率の観点で決められました。

  • 行頭にカンマを書くと、一番上のカラムをコメントアウトの際にエラーになってしまう
  • BigQuery は select 句の最後の行にカンマがついていてもエラーにならないので、一番最後の行をコメントする際もカンマの削除が不要

の2点が主な理由です。より少ない労力で各行をコメントできる書き方を採用しました。

where 句の and と or は先頭に置く

# NG
select
  name,
  comment,
from SAMPLE.table
where
  date between date('2021-04-27') and date('2021-05-05') and
  name = 'name1' or
  comment = 'comment1'

# OK
select
  name,
  comment,
from SAMPLE.table
where
  date between date('2021-04-27') and date('2021-05-05')
  and name = 'name1'
  or comment = 'comment1'

条件が複雑で長くなっている際に and や or が行末についていると見づらいというのがありました。 先頭に書いておけば、条件のかたまりの切れ目が分かりやすく良いのではという議論がありました。

サブクエリではなく、 with 句を使う

# NG
select
  name,
  sum_price
from (
  select
    name,
    sum(price) sum_price,
  from SAMPLE.table
  where
    date between date('2021-04-27') and date('2021-05-05')
  group by name
)
where
  sum_price >= 10000

# OK
with
  t_base as (
    select
      name,
      sum(price) sum_price,
    from SAMPLE.table
    where
      date between date('2021-04-27') and date('2021-05-05')
    group by name
  )
select
  name,
  sum_price
from t_base
where sum_price >= 10000

主な理由としては

  • 一つのクエリが大きくなりすぎない
  • ネストが深くなりすぎない
  • 同じクエリを何度も再利用できる

の3点が挙がりました。可読性だけでなく、再利用性の観点からも with 句を使うようにしています。

ビフォーアフター

以下、全ての規約を適用したときのビフォーアフターの一例です。

# 適用前
SELECT
  date,
  target_name,
  SUM(price) sum_price,
  AVG(price) avg_price,
FROM (
  SELECT
    date,
    CASE
      WHEN regexp_contains(name, r'regexp1') THEN 'name1'
      WHEN regexp_contains(name, r'regexp2') THEN 'name2'
    ELSE null
  END target_name,
    price,
  FROM DataBase.table1
  WHERE date BETWEEN DATE('2021-01-01') AND DATE('2021-01-31'))
WHERE target_name IS NOT NULL
GROUP BY date, target_name
GROUP BY date, target_name

# 適用後
with
  t_base as (
    select
      date,
      case
        when regexp_contains(name, r'regexp1') then 'name1'
        when regexp_contains(name, r'regexp2') then 'name2'
        else null
      end target_name,
      price,
    from DataBase.table1
    where date between date('2021-01-01') and date('2021-01-31')
  )
select
  date,
  target_name,
  sum(price) sum_price,
  avg(price) avg_price,
from t_base
where target_name is not null
group by date, target_name
order by date, target_name

紹介した規約以外にも、インデントに関する規約などが適用されており、読みやすくなりました。 規約通りにかけているかのチェックは、現状は目視で確認しています。最低限レビューや後で読み返すときに困らない程度の可読性を保てたら良いので、そこまで厳密にはチェックしていません。

まとめ

分析チームで運用している SQL のコーディング規約についてまとめました。カラム名や with 句における命名規約なども定めていますが、それはまた別の記事で紹介しようと思います。
このコーディング規約はあくまでも一例で、状況によって規約の内容や運用方法は変わると思います。その時のチームの課題や状況に応じてアップデートしていきたいと思います。

We are hiring!!

Da Vinci Studio では一緒に働ける仲間を絶賛大募集中です!募集職種と詳細に関しては、以下のリンクからそれぞれ確認できます。