転職したらスマレジだった件

スマレジのエンジニアやまてのテックブログです。マジレス大歓迎です。

独学エンジニアの課題として、ログ解析システムを作った。 Step6. プログラムからのSQLの操作②

こんにちは!

スマレジ・テックファーム の Webエンジニア やまて と申します。

はじめに

「独学エンジニアの課題として、ログ解析システムを作った。」というタイトルで、課題の製作物完成までの道のりを投稿しています。

GitHub の Public リポジトリで閲覧できるようにしています。

github.com

独学エンジニア とは

『独学エンジニア』とは、Web開発(主にサーバーサイド)の動画学習教材です。

dokugaku-engineer.com

連載の目次

「独学エンジニアの課題として、ログ解析システムを作った。」の連載については、以下の順に投稿しています。

ryamate.hatenablog.com

今回は Step6. プログラムからのSQLの操作② です。

作成する以下の 2 つの取得機能のうち、今回は 2 について作成します。

  1. 最もビュー数の多い記事
  2. 指定したドメインコードの人気順

目次

環境

バージョン
macOS Big Sur 11.6
Docker Desktop 4.7.0
PHP 8.1.7
MySQL 8.0.28

インポートしたデータ形式の確認

domain_code page_title count_views total_response_size
ドメインコード ページタイトル 各時間のページ表示回数 合計レスポンスサイズ
aa Main_Page 4 0
aa Wikipedia 1 0

1. 処理の流れの確認

「指定したドメインコードに対して、人気順にソートし、ドメインコード名と合計ビュー数を提示する」という要件を満たすため、以下の流れで処理する。

という要件を満たすため、以下の流れで処理します。

  1. 入力値の受け取り
  2. SELECT 文の実行
    • Step4 で作成した SQL をプログラムから実行するように、 PHP ファイルを作成します。
  3. 結果の表示

2. ファイルの編集

2-1. popular_domain_codes.php の作成・編集

呼び出して処理を実行するプログラムを作成・編集します。

  • 作成・編集:popular_domain_codes.php
<?php

require_once 'lib/sql.php';

const MIN_NUM_OF_SEARCHES = 2;

// 1. 入力値の受け取り ['popular_domain_codes.php', 'en', 'de'] → ['en', 'de']
if ($_SERVER['argc'] > MIN_NUM_OF_SEARCHES) {
    $inputs = array_slice($_SERVER['argv'], 1);

    // 2. SELECT文の実行
    $data = getPopularDomainCodes($inputs);

    // 3. 結果の表示
    foreach ($data as $record) {
        echo '"' . $record['domain_code'] . '", ' . $record['total_count_views'] . PHP_EOL;
    }
} else {
    echo 'ドメインコードを 2 つ以上入力してください。' . PHP_EOL
        . 'ex: php popular_domain_codes.php en de ja';
}

2-2. lib/sql.php の編集

前回作成した sql.php ファイルにメソッドを追記します。

<?php

//省略

/**
 * 指定したドメインコードに対して、人気順にソートし、ドメインコード名と合計ビュー数を取得する。
 *
 * @param array $inputs コマンドラインで受け取った入力値 ex. en de ja
 * @return array $result ex. [0 => ['domain_code' => 'en', 'total_count_views' => '3556081'], 1 => ...
 */
function getPopularDomainCodes(array $inputs): array
{

    $inClause = substr(str_repeat(',?', count($inputs)), 1);

    $sql = <<<SQL
        SELECT
            domain_code,
            SUM(count_views) AS 'total_count_views'
        FROM
            page_views
        WHERE
            domain_code
            IN (
                {$inClause}
            )
        GROUP BY
            domain_code
        ORDER BY
            SUM(count_views) DESC
        ;
        SQL;

    $dbh = dbConnect(); // DB接続
    $stmt = $dbh->prepare($sql); // 実行準備
    $stmt->execute($inputs); // SQL実行
    $results = $stmt->fetchAll(PDO::FETCH_ASSOC);
    $dbh = null; // DB切断
    return $results;
}

$results の中身は、例えば以下のような配列です。

array (
  0 => 
  array (
    'domain_code' => 'en',
    'total_count_views' => '3556081',
  ),
  1 => 
  array (
    'domain_code' => 'de',
    'total_count_views' => '284178',
  ),
)
  • 参考:最初はバインドがうまくいかず詰まりました。
    • 編集:lib/sql.php(失敗)
      <?php
    
      // 省略
    
      function getPopularDomainCodes(array $inputs): array
      {
          $sql = <<<SQL
              SELECT
                  domain_code,
                  SUM(count_views) AS 'total_count_views'
              FROM
                  page_views
              WHERE
                  domain_code
                  IN (
                      :conditions
                  )
              GROUP BY
                  domain_code
              ORDER BY
                  SUM(count_views) DESC
              ;
              SQL;
    
          $dbh = dbConnect(); // DB接続
          $stmt = $dbh->prepare($sql); // 実行準備
          $conditions = "'" . implode("','", $inputs) . "'";
          $stmt->bindValue(':conditions', $conditions, PDO::PARAM_STR);
          $stmt->execute(); // SQL実行
          $results = $stmt->fetchAll(PDO::FETCH_ASSOC);    // DB切断
          $dbh = null;
          return $results;
      }
    

chaika.hatenablog.com

3. プログラムの使い方

下記コマンドを実行します。

docker compose exec app php popular_domain_codes.php en de ja
# r_yamate @ mbp in ~/Documents/code/wikipedia-log-analysis-tool on git:feature/create-program x [7:35:12] C:16
$ docker compose exec app php popular_domain_codes.php en de ja
"en", 3556081
"ja", 367924
"de", 284178

※ 入力がない場合、エラーメッセージが表示されます。

# r_yamate @ mbp in ~/Documents/code/wikipedia-log-analysis-tool on git:feature/create-program x [7:36:08]
$ docker compose exec app php popular_domain_codes.php
ドメインコードを 2 つ以上入力してください。
ex: php popular_domain_codes.php en de ja

おわりに

今回は「独学エンジニアの課題として、ログ解析システムを作った。」の Step6. プログラムからのSQLの操作② でした。

ログ解析システムを作成した目的は、ソフトウェアエンジニアリングにおいて実際によく登場するタスクの一つである、ログデータを解析を実際にやってみることで、データベースとSQL スキルの向上を目指す、という目的でした。まだまだではありますが、基礎がしっかり学べたと思います。

ありがとうございました。



前職の仕事は「やりたいこと」と思える部分がなかったけど、今は分からないこと多くてしんどくても楽しいと思えるし、やりたいことと思えているから、この調子で行きたいです。