TIM Labs

今回のあらすじ

SICP3.3.4 A Simulator for Digital CircuitsRepresenting wires を読んで Exercise 3.32 まで演習問題を解きます。

悩んでる図

皆様、Spec(コードベースの単体、機能、結合テスト)書いてますか? 私はあんまり書いていません。

「テスト書かないとかありえない!」と怒られそうなので一応弁解しておきますが、C0レベルのテストは、そこそこ書いているつもりです。 プロジェクトでカバレッジはXX%以上!(XXの部分は95だったり100!だったりします)という決まりがあるため、書いてます。消極的な理由ですね。

時としてカバレッジを満たすためのテストを書く、という意味の分からない事をしてしまったことは、反省しております。

しかし、C0は所詮C0であり、このレベルのテストをいくら一生懸命書こうが、バグがでるときはでるものなのです。 だからといってC1、C2、またはそれ以上を満たすようなテストを一生懸命かけばバグが無くなるか?という話でもありませんが、バグ発生率が少しは下がるかと思います。

さて、最近お固い業務システムで、そこそこ致命的なバグをやらかしてしまいました。 今後もC0レベルのSpecを書いてて良いのか? という話題がプロジェクト内から湧き上がったので、いろいろ考えてみることとしました。

今回のあらすじ

SICP3.3.4 A Simulator for Digital Circuits を読んで Exercise 3.30 まで演習問題を解きます。

悩んでる図

今回のあらすじ

SICP3.3.3 Representing TablesExercise 3.26Exercise 3.27 を解きます。

悩んでる図

今回のあらすじ

SICP3.3.3 Representing Tables を読んでExercise 3.25まで解きます。

二次元テーブルと戦う前準備の図

これまでのあらすじ

弊社では新入社員の技術的な基礎体力向上を目的として SICP の読書会を一年半程前から毎週行っています。

毎回のまとめは参加者用のMLに流していたのですが、 よくよく考えると後から一覧したり検索したりし辛いので、 今後はこちらにポストしようと思います。

かなりスローペースで進めているため、 一年半経ってようやく3章に突入したところです。

前回は 3.3.2 Representing Queues を読んでExercise 3.21を解き、Exercise 3.22とExercise 3.23は宿題ということにしました。 という訳で宿題の答え合わせをしましょう。

前回までのあらすじ

シェフィの実装を始めた俺達はゲームを快適にプレイする為の機能を作り込んでいる最中。しかしまだやるべき事は山積み......

(※ソースコードはGitHubで公開されておりすぐに遊ぶこともできます)

こんな感じにデータを持ってる sample_table があるとする。

+----+----------+------------+---------+
| id | group_id | updated_at | comment |
+----+----------+------------+---------+
|  1 |        1 | 2013-12-01 | C       |
|  2 |        2 | 2013-12-01 | A       |
|  3 |        1 | 2013-12-02 | B       |
|  4 |        2 | 2013-11-30 | D       |
+----+----------+------------+---------+

MySQL で同じデータを作成したければ、以下の SQL で再現できる。

CREATE TABLE sample_table (
    id int(11) NOT NULL,
    group_id int(11) NOT NULL,
    updated_at date NOT NULL,
    comment varchar(60) NOT NULL
);
INSERT INTO sample_table VALUES
    (1, 1, '2013-12-01', 'C'),
    (2, 2, '2013-12-01', 'A'),
    (3, 1, '2013-12-02', 'B'),
    (4, 2, '2013-11-30', 'D');

こんなデータのとき、同じグループ内であるフィールドが最大(あるいは最小)のレコードを取得したい、ということがたまにある。例では、group_id それぞれについて、 updated_at が最新のレコード、即ち comment が A および B のレコードを取得したいとしよう。

さて、どんな SQL を書けばよいだろう?

DBのスキーマ、皆様どのように管理されているでしょうか。

Railsを利用されている方の多くは、ActiveRecordのマイグレーションを利用して管理をされているかと思います。

私もいままでいくつかのRailsプロジェクトに関わってきましたが、 ほぼ全てのプロジェクトでActiveRecordのDBマイグレーションを利用してきました。 (一部のプロジェクトはActiveRecordを使っていないため、マイグレーションも独自のものを利用しています)

ActiveRecordのマイグレーションでは、DBスキーマ変更の差分情報をマイグレーションスクリプトとして保存しておきます。例えば、新しいテーブル「users」を作成する場合は、下記のようなマイグレーションスクリプトを作成します。

class AddUsers < ActiveRecord::Migration
  def up
    # ここにマイグレーション適用時の操作を書く
    create_table :users do |t|
      t.string :name
      t.datetime :created_at
      t.datetime :updated_at
    end
  end

  def down
    # ここにマイグレーション破棄した時の操作を書く
    drop_table :users
  end
end

テーブル作成/削除やカラム変更を行う際には、マイグレーションスクリプトを1つ作成します。 このように変更を管理することによって、DBスキーマを最新版へ移行させたり、任意の時点のスキーマに戻したりすることが可能です。また、スキーマの一貫性を保つことができます。

便利な機能なのですが、プロジェクトが始まったばかりの初期開発フェーズで、このマイグレーション運用をするのはかなり辛いです。

プロジェクト初期の段階では、DBの設計もちゃんと固まっていないため、スキーマ変更が頻繁に発生します。 スキーマ変更のたびにマイグレーションスクリプトを書かないといけないのは手間がかかるもので、DB修正を気軽に行うことができなくなります。

何か楽できる手立てはないものでしょうか。

前回までのあらすじ

シェフィの実装を始めた俺達はゲームを快適にプレイする為の機能を作り始めたばかり。しかしまだまだやるべき事は多い......

(※ソースコードはGitHubで公開されておりすぐに遊ぶこともできます)

最近のコメント