Saturday, October 13, 2007

ある関数従属性をもつ属性に対してどのようなリレーションを作成すべきか?

この投稿、近いうちに削除します。もう少し、うまくまとめて再度アップするつもり。

正規化の議論は、あるリレーションが正しい構造か?更新異常がない構造になっているか?という観点からのもの。ここでは逆に属性をどのように組み合わせていけば正しい構造のリレーションになるかを考えてみる。

まず、2つの属性 A, B は次の3つの関係(リレーションシップ)を持ちうる。

  • 1対1のリレーションシップ。このとき、A → B かつ B → A の関係である。
  • 多対1のリレーションシップ。このとき、A → B かつ B NOT → A の関係である。
  • 多対多のリレーションシップ。このとき、A NOT → B かつ B NOT → A の関係である。


1対1のリレーションをもつとき。

この場合、A と B は少なくとも1つのリレーション R 上に共存しなければならず、A または B が R のキーとなる。A が B を決め、B が A を決めるということは、A と B がそれぞれ何らかのエンティティ・インスタンスを決定していると捉えて、そのリレーションをつくるわけだ。そして、ある属性 C をこの R に追加するには、A → C または B → C が成立しなくてはならない。また、データの不要な重複を避けるために複数のリレーションに A, B が共存することは避けるべき。リレーション間のリレーションシップを作るために A または B が他のリレーションシップに存在する場合はあるが(いわゆる外部キーであろう)、その場合、あるリレーションには A、もう1つのリレーションには B というようにはせず、A または B の1つのみを使うようにした方がいい。

多対1のリレーションをもつとき。

この場合、A と B はリレーション内で共存でき、そのときは A がそのリレーションのキーになる。ある属性 C をそのリレーションに追加できるのは A → C が成立する場合だけ。

多対多のリレーションをもつとき。

この場合、A と B はリレーション内で共存でき、そのとき、(A,B) がそのリレーションのキーになる。(A,B) → C が成立するときだけ C をそのリレーションに追加できる。ただ、(A,B) NOT → C でも、C NOT → (A,B) だとすると、この関係は (A,B) と C との多対多のリレーションシップである。したがって、C をリレーションに追加して、(A,B,C) をキーとできる。ただし、こうしてしまうと、もはやこのリレーションは違う主題を表していることになるので、リレーションの名前を変えた方がよいということになる。

ちなみに、上で C → (A,B) が成立としたら、関数従属性の性質から C → A かつ C → B が成立する。この場合、多対1のリレーションということで、C,A,B が共存することは可能であり、C がそのリレーションのキーということになるだろう。

このように属性を組み合わせてリレーションを作っていけば、それらは DK/NF を満たすようになるだろう。

上の多対多のリレーションで (A,B,C) をキーにする場合だが、こうできるのは、多値従属性 A →→ B | C または B →→ A | C が成立しない場合に限られる。そうでないと 4NF にならず、当然 DK/NF も満たさないから更新時異常が起こってしまう。

たとえば、R{ 教授名, クラス } というリレーションがあって、教授とクラスの組み合わせがキーだとする。授業をする教室が教授の気まぐれで決まるとしたら、使用教室、という属性と (教授名, クラス) とは多対多のリレーションシップをもつ。そして明らかに、ここには多値従属性はないので、{ 教授名, クラス, 使用教室 } をキーとした新しいリレーションをつくることができる。

ドメイン/キー正規形(DK/NF)

この投稿、近いうちに削除します。もう少し、うまくまとめて再度アップするつもり。

リレーションの更新時異常を解消していく過程で、1NF, 2NF, 3NF, BCNF, 4NF, 5NF と正規化が進んでいく。5NF まで正規化されると更新時異常は起こらなくなるので、5NF がある意味究極の正規形である。

この正規形の系列とは別にドメイン/キー正規形(DK/NF)がある。この DK/NF でも更新時異常は起こらず、また更新時異常が起こらないリレーションは DK/NF であることが示されている。リレーションが DK/NF であるための条件は以下のとおり。

「リレーション上のすべての制約条件がキーとドメインの定義の論理的な帰結である場合にそのリレーションは DK/NF となる」

制約条件とは、「属性の静的な値を決定するためのルールで、真か偽かを明確に決定できるもの」である。したがって、関数従属性や多値従属性、リレーション間・リレーション内の制約条件などが該当する。なお、「静的な値」なので時間に依存する条件は含まない。たとえば、セールスマンの給料を表す属性値を変更するときは前の値より多くなければならない、などだ。

ドメインとは、属性の定義域のことだ。物理的定義と意味的定義の2つの側面があるが、DK/NF では物理的意味だけを考えればいい。

DK/NF の利点は、ドメインとキーというデータベース実務者にとって基本的な概念のみに関連していること。リレーションのすべての制約条件がこの基本的な概念の論理的な帰結になっているかどうかをチェックすればいいので、1NF から 5NF の正規化よりもずっと理解しやすくなっている。

直感的には、リレーションが1つの主題のみをもつようにすれば、DK/NF になるだろう。

Tuesday, October 09, 2007

多値従属性と 4NF

この投稿、近いうちに削除します。もう少し、うまくまとめて再度アップするつもり。


多値従属性(MVD)とは関数従属性(FD)を一般化した概念。したがって、FD は MVD でもあるということになる。

A, B, C, X をそれぞれ属性の集合としたとき、リレーション R{A,B,C,X} 上で、値 (A値,C値) に対応する B の値の集合が A値によってのみ決まり、C値とは独立しているとき、B は A に多値的に従属する、または A は B を多値的に決定する、という。これを A →→ B と書く。

「A の値によってのみ決まり C の値とは独立」とはどういうことかというと、ある A値をもつタプルの集合における B値、C値の集合を考えたとき、その「B値の集合」と、「C値の集合のそれぞれの C値に対応する B値の集合」が一致することをいう。このことから、A →→ B であるとき、かつそのときに限り A →→ C でもあることが分かる。そこで、この関係を A →→ B | C とも書く。

ここで X が空集合だとしてみる。すると R{A,B,C} はすべての属性の組み合わせをキーとする BCNF なるだろう。このとき、関数従属性と更新時異常で述べたように、R には FD を原因とする更新時異常は起きないが、A →→ B | C の MVD を原因とした更新時異常が発生する。

これを解消するために R{A,B,C} は2つのリレーション {A,B} と {A,C} に無損失分解することができる。結局、BCNF であるリレーション R をさらなる正規形に分解できたことになるのだが、この新しい正規形を第4正規形(4NF)と呼ぶわけだ。

4NF とは、「BCNF であり、かつそこにおけるすべての MVD が候補キーからの FD であるリレーション」と定義できる。

ちなみに無損失分解とは、分解してできた新たなリレーションを結合したときに元のリレーションに戻せるような分割のことだ。結局、正規化とは、更新時異常を避けるためにリレーションを無損失分解することだといえる。

Tuesday, October 02, 2007

1NF, 2NF, 3NF and BCNF

この投稿、近いうちに削除します。もう少し、うまくまとめて再度アップするつもり。

関数従属性に関する正規形の種類。関数従属性と更新時異常 で書いたように、BCNF までいくと関数従属性に起因する更新時異常がなくなる。じっさい、1NF, 2NF, 3NF は BCNF までの踏み台にすぎない。

BCNF の上に、多値従属性に関する正規形 4NF と結合従属性に関する正規形である 5NF がある。

まず、1NF。すべてのリレーションは 1NF になる。つまり、属性は単一の値(スカラ値)を持ち、同一のタプルは存在しないといったリレーションの定義を満たすものはすべて 1NF である。

2NF とは、キー以外のすべての属性がキー上で既約従属(キーの一部の属性に従属しない)であるリレーションをいう。これは候補キーが1つだけの場合の定義になるが、上で述べたように BCNF までの踏み台にすぎないのであまり形式的にやる必要もないだろう。

3NF とは、2NF であり、かつキー以外のすべての属性がキーに推移的でない従属をしているリレーションのこと。推移的な従属とは、A → B かつ B → C ならば A → C のような従属のことだ。このとき C は A に推移的に従属している。3NF とはこの推移的従属がないものをいう。ここでも候補キーが1つしかない場合の定義になっている。

BCNF とは決定項がすべて候補キーになっているリレーションのこと。つまり、R 上のすべての関数従属性の決定項が候補キーでもある場合、R は BCNF である。

Monday, October 01, 2007

関数従属性と更新時異常

この投稿、近いうちに削除します。もう少し、うまくまとめて再度アップするつもり。

リレーション R 上の属性で、A が決まると B も決まるとき A → B と書く。このとき A を決定項、B を従属項という。決定項、従属項は属性の組み合わせでもよく、A → {B,C}、{A,B} → C、{A,B} → {C,D,E} もある。

A → {B,C} と A → B かつ A → C は同じことである。が、{A,B} → C と A → C かつ B → C とは同じではない。

A → A および {A,B} → A は自明。従属性を考えるときは自明な従属性は除いていい。

すべての属性が従属するような決定項をキーという。キーが複数の属性から成り立つ場合、その一部がそれ以外の部分に依存することがあってはいけない(既約)。キーでない、またはキーの一部でない属性を非キー属性という。キーは複数存在することもあるので、候補キーともいう。

ここで、関数従属性と更新時異常との関係について考えてみる。

データベースというのは「モデルのモデル」すなわち、現実のビジネスに対するユーザの見方(ユーザのデータモデル)のモデルであった。したがって、リレーション上の関数従属性もユーザのデータモデルを反映している。

更新時異常とは、更新したときにユーザのデータモデルと不整合を起こす、または不整合を防ぐために何らかの異常な操作をしなくてはならないことだと定義できそう。

候補キーでタプルを識別し、更新・削除することは、結局ユーザデータモデル上で対応するインスタンスを更新・削除することに対応する。リレーション上で更新・削除されるのも1つのタプルだけであり、異常はない。

しかし、キーでない関数従属性の決定項でタプルを更新しようとすると、ユーザモデルでは更新されるべきインスタンスが1つに決まるはずだが(ユーザの頭の中にあるビジネスの見方に矛盾がない限りそうであるはず)、リレーション上では1つに決まらず複数のタプルを更新しなくてはならない場合がある。挿入しようとしても、決まらない属性があるのでタプルが決まらず、リレーションに挿入することができない。

したがって、このような更新時異常は、リレーション上の関数従属性の決定項がすべて候補キーになっていれば起こらない。こういうリレーションが、Boyce-Codd 正規形であり、ここまで正規化されると、関数従属性に起因する更新時異常は発生しなくなる。

Friday, September 28, 2007

vim で文字コードを指定するには?

たとえば次のように設定すればいい。

set encoding=utf-8
set fileencodings=utf-8,iso-2022-jp,euc-jp,cp932,latin1

encoding で vim 内部で使う文字コードを指定する。vim 内部とはバッファやレジスタ内の文字列、.viminfo ファイル内のテキストなどに使用されるという意味らしい。

fileencodings ではファイルを読み書きするときに考慮する文字コードのリストを指定する。ファイルを読み出すときに、このリストの順に文字コードを試していき、該当するものがあれば、それを使う。もし、その文字コードが encoding に指定しているものと異なる場合は文字コードの変換がなされるが、書き込むときは元のコードに再変換して書き込まれる。一致するものがリストにないなら encoding の文字コードで読み出される。

ファイル編集時に

set fileencoding?

とすると、ファイルの文字コードと判定された文字コード名が示される。上に書いたことから分かるように、これは fileencodings に指定したリスト内のいずれかになる。リスト内に一致したものがない場合は、この fileencoding は空になる。

fileencodings の設定で、latin1 (ISO_8859-1) を先頭に指定すると、UTF-8 や EUC-JP のファイルでも Latin1 と判定されてしまった。これは、それらのファイル内の少なくとも最初の部分の文字を構成するバイトが Latin1 でコードポイントを与えられているからだろう。

Windows の gvim の設定で(gvimrc ファイル) encoding に CP932 以外を指定すると、メニューなどの文字が文字化けした。冒頭で書いたように、テキストだけではなく vim 内部で使用する文字コードが設定されることが原因だろう。


参考サイト: vim の全オプション

vim の自動インデントで余分にインデントされてしまう件

vim でタブに対応する空白数はデフォルトで8のようだが、ホームディレクトリ直下の .vim ファイルに

set tabstop=4

と定義しておくことで、対応する空白数を4にセットできる。だが、こうすると C や Java のソースファイルを編集するときの自動インデントが余分に入るようになってしまった。つまり、1回インデントして空白が4つ入るはずなのに、2回インデントして8つの空白が入るようになってしまう。

この原因は、タブの空白数の設定と自動インデントによる空白数の設定とは別であるところにある。デフォルトでは自動インデントにおける空白数が8に設定されているようで、このためタブの空白数が4だと、8つの空白を入れるためにインデントが2回実行されてしまうというわけだ。


参考サイト: vim の全オプション


これを直すには、自動インデントの空白数をタブの空白数に合わせてやればいい。次のように設定する。

set shiftwidth=4

.vimrc に先の tabstop の設定と同様に定義しておけば、問題は解決する。

Monday, September 03, 2007

JDBC で SQL の LIKE 文を使うときの書き方

次のように書く。

String keyword = "富";
PreparedStatement st = con.prepareStatement("SELECT name FROM tbl_names WHERE name LIKE ?");
st.setString(1, "%" + keyword);

これにより、富、という文字で始まる名前が検索できる。つまり、LIKE 演算子に使う % や _ などのワイルドカードも含めた検索文字列を setString メソッドで、? にセットするということだ。

ではワイルドカードをエスケープするときは、どうするか?Oracle ではエスケープ文字は特に決まっておらず、ESCAPE オプションで指定する。たとえば、

SELECT id FROM tbl_names WHERE id LIKE '\%%' escape '\';

という SQL 文は、\ をエスケープ文字に指定しており、% という文字で始まる id を検索している。もし、\ がなかったなら、すべての id がヒットする。

JDBC の場合も同様にすればよい。

PreparedStatement st = con.prepareStatement("SELECT id FROM tbl_names WHERE id LIKE ? escape '\\' ");
st.setString(1, "\\%%");

こうすれば、% で始まる id を検索できる。念のため言っておくと、\\ のように二重になっているのは、Java の文字列中では \ はエスケープ文字であるため、二重にすることで \ そのものを表現している。

ただ、このエスケープ文字の指定は Oracle 固有であるので、違う RDBMS では通用しないかもしれない。そこで、JDBC はエスケープ構文が用意している。次のように書く。

PreparedStatement st = con.prepareStatement("SELECT id FROM tbl_names WHERE id LIKE ? escape {'\\'} ");
st.setString(1, "\\%%");

結局、Oracle との違いは、エスケープ文字を {} で囲っていることだけだ。


Oracle、PostgreSQL 等でこれを実験してみる。
そして
http://www.nilab.info/zurazure2/000740.html
このページも参考にしながら、続きを書く。

Monday, August 27, 2007

Windows に Active Perl, Apache, Tomcat のセットアップ

仕事でローカルマシンに HTTP サーバを立て、そこでテスト用 CGI を実行する必要があったためセットアップした。この CGI はリクエストを受けると、別のサーバにリクエストを送信し、結果を整形して返すということをする。この別のサーバにアクセスするためにはローカルマシン上で VPN クライアントを実行してトンネリングする必要があるため、この作業が必要になった。

Active Perl

ActiveState 社 のサイトからインストーラをダウンロードして実行すればいい。PATH の設定も自動でなされるので、DOS 窓から普通に実行できる。Cygwin を入れていれば Perl は元から入っているだろうが、当然、その Perl は Active Perl とは別のものだ。-v オプション付きで双方を実行すれば分かる。


Apache

http://www.y2sunlight.com/ground/?Apache2 を参考にセットアップ。インストーラをダウンロードして実行するだけでいい。個人的な実験用であり、サービスとして起動する必要はないなら、8080 ポートで手動実行という選択をすればいい。

スタートメニューの 『すべてのプログラム』 から Apache HTTP Server をたどっていき、Start Apache in Console をクリックすれば Apache が起動する。ブラウザで localhost:8080 にアクセスして起動を確認する。

CGI を動かすには、conf/httpd.confScriptAlias ディレクティブの設定が有効になっていなくてはならない。localhost:8080/cgi-bin/$APACHE_HOME/cgi-bin/ の中にある CGI スクリプトにアクセス、実行できるようになっているはず。

CGI が Perl で記述されているなら、冒頭にある Perl へのパスを次のように、インストールした ActivePerl にあわせて設定する。


#!c:/Perl/bin/perl.exe


テスト用 CGI もこのようにしてうまく動かすことができた。


Tomcat

Windows で Tomcat で 5.5 をインストール済み。CGI を有効にするには、少々追加設定が必要なようで、次のページを参考にさせてもらった。

http://muimi.com/j/jakarta/tomcat55/
http://www005.upp.so-net.ne.jp/burubon/epc/java-homepage/015.html

しかし、テスト用 CGI を実行することはできなかった。どうやら、CGI がサーバにリクエストを出すのに失敗しているようだった。Apache ではうまくいったから、Tomcat の問題なのだろう。

ちなみに、Tomcat インストール後に Java をアップグレードすると起動に失敗してしまうことがある。原因は、Tomcat に指定していた JVM のパスが変わってしまったことによる。Monitor Tomcat を起動し、それの Configure をクリックし、Java タブで JVM のパスを指定しなおせばいい。たとえば、次のように。


C:\Program Files\Java\jre1.5.0_11\bin\client\jvm.dll


これは JDK1.4 から 1.5 にアップグレードしたので、このように変更した。

Sunday, August 26, 2007

SonicMQ 7.0 インストール

Sonic の CD にある setup.sh を実行してインストール。root 権限は必要ない(むろん、インストールする場所による)。インストールに X-Window は必須。ライセンスキーを入力し、ほぼデフォルトのままインストールしてよい。

管理コンソールを使うこともできるが、$SONIC_MQ_HOME/bin/startcontainer.sh を実行すればすぐ使うことができる。screen で実行しておき、止めたくなったら Ctl-C で終了させてもいい。

SonicMQ を起動すると、デフォルトでは 2506 ポートをオープンしてクライアントを待つ。クライアントは、


progress.message.jclient.TopicConnectionFactory conFactory = new progress.message.jclient.TopicConnectionFactory();

conFactory.setConnectionURLs("<ホスト名 or IP アドレス>:2506");
conFactory.setFaultTolerant(true);

TopicConnection connection = conFactory.createTopicConnection();


のようにすれば TopicConnection を作成できる。TopicConnectionFactoryTopicConnection 同様に javax.jms パッケージで定義されているインターフェースだが、setConnectionURLssetFaultTolerant は Sonic 固有のメソッドだ。

冗長化構成をとることもできるが、これは調査中。

Tomcat5.5 で Web アプリケーションの配備

Web アプリケーションを配備するために、$CATALINA_HOME/webapps/ に war ファイル(ベース名はコンテクストルート名になる)をおくか、コンテクストルートそのものを置く。もしくは、$CATALINA_HOME/conf/server.xml に次のような XML を記述してもいい。


<Context path="/LoaderSide" docBase="/home/kazu/ContextCommunication/LoaderSide/build/war/loader.war"
debug="0" privileged="true" crossContext="true">
</Context>

<Context path="/StoreSide" docBase="/home/kazu/ContextCommunication/StoreSide/build/war/store.war"
debug="0" privileged="true" crossContext="false">
</Context>


ここでは、コンテクストルート名が LoaderSideStoreSide という2つの Web アプリケーションを配備している。LoaderSide は crossContext 属性を true に設定しており、他の Web アプリケーションのコンテクスト情報にアクセスすることができるようになっている(Web アプリケーションにおけるコンテクスト間通信)。

ここまでは、Tomcat4 と同じ。だが、Tomcat4 では可能だった、コンテクストフラグメント XML を $CATALINA_HOME/webapps/ に置く方法はうまくいかなくなった。

Tomcat5 では、コンテクストフラグメント XML ファイルのベース名をコンテクストルート名と同じにして(4 ではベース名は何でもよかった)、$CATALINA_HOME/conf/Catalina/localhost/ に置かないといけない。先の例だと、LoaderSide.xml と SoreSide.xml ファイルをそれぞれ作って、配備してやることになる。path 属性はあってもいいが、XML ファイルのベース名に指定したコンテクストルート名と食い違っているとまずいから、書かない方がいいだろう。

Sunday, July 29, 2007

RPM で screen をインストールするときに手間取った件

screen というのは、UNIX ライクな OS で動く仮想端末管理プログラム。SonicMQ をフォアグラウンドで起動してそのままにしておき、落としたいときに Ctl-C で終了させるということが仕事で必要になったので導入することにした。

まず、自宅の Ubuntsu に導入してみた。これは

# apt-get install screen

で一発。簡単に完了。

次に、本番環境となっているデータセンタの RedHat Linux へのインストールに取り掛かる。Web 上の RPM リポジトリ から screen-4.0.2-1.i686.rpm を取得して、rpm コマンドを下のように実行してインストールしたが、

# rpm -ivh screen-4.0.2-1.i686.rpm

これに対し、libelf と libtinfo というライブラリに依存しているというエラーメッセージが出た。Web 上の RPM リポジトリ でも依存しているパッケージがリストされており、そこにもこれらが表示されていた。そこから libelf-0.8.2-4.i686.rpm と ncurses-5.2-34.i686.rpm を取得して、rpm コマンドでインストールを試みた(libtinfo は ncurses パッケージに含まれるということだった)。

しかし、libelf の方はうまくいったが、ncurses の方は、もっと新しい ncurses パッケージがすでにインストールされているというエラーが出てしまった。

これには困った。問題は、なぜインストール済みの新しい ncurses パッケージには libtinfo が含まれていないのかということだ。先に screen をインストールした Ubuntsu マシンを調べてみると、libtinfo というライブラリは存在していない。

そこでもっと新しい screen のパッケージ screen-4.0.2-48.2.i586.rpm を取得して、

# rpm -ivh screen-4.0.2-48.2.i586.rpm

を実行すると、今度はうまくインストールできた。このパッケージは libtinfo にも libelf にも依存していないので、先にインストールした libelf も

# rpm -e libelf

で削除した。

おそらく古い screen では libtinfo ライブラリを使用しており、それが最新だった頃の ncurses パッケージにも libtinfo が含まれていたのだろう。しかし、新しい screen では libtinfo は必要なくなっており、ncurses パッケージにもそれは含まれなくなってしまった。そういうわけで、新しい ncurses パッケージがインストールしてあるマシンに古い screen をインストールしようとした結果、こういう問題がおきたということなのだろう。

Friday, June 08, 2007

Web アプリケーションにおけるコンテクスト間通信

crossContext 属性は、getContext() で取得する側を true に設定する。そうしないと、null が返る。

共通するクラスは WEB-INF/lib/ や WEB-INF/classes/ においては駄目。ClassCastException が発生する。Tomcat5 ではそういうクラスは、CATALINA_HOME/shared/lib/ や CATALINA_HOME/shared/classes/ に置けとある。Tomcat4 だと CATALINA_HOME/lib/ か CATALINA_HOME/classes/ に置けとあったがうまくいかなかった。見つけられずに NoClassDefFoundError が発生する。そこで、CATALINA_HOME/common/lib/ に置いたらうまくいった。

http://tomcat.apache.org/tomcat-4.0-doc/class-loader-howto.html
http://www.jajakarta.org/tomcat/tomcat5.0/ja/docs/tomcat-docs/class-loader-howto.html
http://www-06.ibm.com/jp/software/websphere/developer/j2ee/strategy/


http://www.fortunefield.com:8080/StoreSide/Store?data=fuckYou
http://www.fortunefield.com:8080/LoaderSide/Loader

$CATALINA_HOME/shared/lib/ を有効に使えるのは、$CATALINA_HOME/webapps/ に war ファイルを置いた場合のみのようだ。ただ、これだと crossContext 属性を設定できないので、コンテクスト間通信には使えない。。。

Thursday, June 07, 2007

Web アプリケーションのコンテクストパスを多重化する方法はあるか?

webapp1 という Web アプリケーションがあるとしよう。Tomcat ならば、CATALINA_HOME/webapps/ に webapp1.war というファイルがあるものとする(むろん、配備の仕方はこれ以外にもあるが)。

このとき、

http://www.fortune.com/webapp1/SomethingServlet

のようなパスでこの Web アプリにアクセスできる。これに /packman というコンテクストパスでもアクセスできるようにするには、CATALINA_HOME/webapps/ に次のような内容の XML フラグメントファイルをおけばいい。


<?xml version="1.0" encoding="EUC-JP" ?>
<!--
ファイル名は packman.xml でも hoge.xml でも何でもいい。
-->
<Context path="/packman" docBase="./webapp1.war"
debug="0" privileged="true">
</Context>


こうしてから、

http://www.fortune.com/packman/SomethingServlet

によるアクセスが成功する。ただし、この方法には重大な欠陥がある。これだと、webapp1 というアプリケーションが二重に起動されてしまうのだ。つまり、アプリケーションのインスタンスが2つできてしまう

一方の Web アプリから他方の Web アプリにリクエストを転送することで1つの Web アプリを共用化することはできる。ただ、いろいろ調べてみたが、Unix のシンボリックリンクのようにパスを多重化しつつ、ファイルの実体は1つだけにするというようなことはできないようだ。

検索をかけてみると、日本語のページはヒットしなかったが、英語では1つだけヒットした。

How to configure multiple context path for a webapps

Saturday, May 12, 2007

CPU 使用率 100% になって Windows がフリーズしてしまう件

タスクマネージャ で見ると、svchost.exe というプロセスが CPU リソースをバカ食いしている。これを思い切って終了させてみると正常に戻った。が、オーディオデバイスが使えなくなってしまう。

svchost.exe というのは重要なシステムプロセスだそうで、いくつかある同じ名前のプロセスを終了させるとシステムがシャットダウンしてしまう場合もある(他の svchost.exe を強制終了したら実際そうなった)。

そこで

http://gigazine.net/index.php?/news/comments/20061009_svchost/
http://www.microsoft.com/technet/sysinternals/utilities/ProcessExplorer.mspx

Process Explorer なるものをインストールして詳しく調べると、100% 近くなっている svchost.exe のプロセスツリーの下には、wuauclt.exe というのがある。これは、Windows の自動更新を司るプロセスだ。どうやら、これが原因らしい。

したがって、コントロールパネルから自動更新を OFF にすると問題は解決したが、この自動更新の不具合を修正するための更新プログラムが(いまごろ)発表されていたのでそれをインストールした。

http://gigazine.net/index.php?/news/comments/20070511_windows_update_patch/
http://support.microsoft.com/kb/937383/ja

これでこの問題は完全に解決。ただ、svchost が短い間 CPU 使用率100% になることはあるということで実際そうなっている。

この件、ググってみたら結構ヒットして、オーディオデバイスが使用不能になるなど、まさに同じ目にあっている人もいた。

Tuesday, May 08, 2007

Oracle SQL*Plus メモ


SELECT
'INSERT INTO tbl_alert_cond(user_id, meigara_code, alert_type, last_update)
values (''' || b.user_id || ''', ''' || a.meigara_code || ''', ' || to_char(a.alert_type) || ', SYSDATE);'
FROM tbl_alert_cond a, tbl_users b
where a.user_seq_no = b.user_seq_no;


この SQL は、テーブルから SELECT した結果を組み合わせて SQL 文を作成している。文字列はシングルクォートで囲むのだが、文字列中でシングルクォートを使いたいときは、シングルクォートをシングルクォート自身でエスケープする。つまり、シングルクォートを2つ並べるということ。

また、文字列連結演算子 || を使っているが、これに渡すために整数カラムは、to_char 関数でいったん変換してから渡しているのがわかる。

Thursday, March 29, 2007

Windows のコマンドラインで実行される Java

アプレットやアプリケーションで使用される JRE は Windows コントロールパネル中の Java コントロールパネルで切り替えることができる。

http://fortunefield.blogspot.com/2005/12/thinkpad-r1-eclipse-311.html

ここでの変更は、コマンドラインや Cygwin で実行される java コマンドには影響しない。ユーザ環境変数 PATH での指定も効果がなかった。この理由は、設定した PATH の前に Windows が勝手にパスを付け加えてしまい、付け加えられる PATH の1つである

C:\WINDOWS\system32

には java.exe が存在しているからだ。そして、この java.exe は、レジストリに登録されている情報から使用する JRE の位置を取得するというわけだ。

Microsoft Windows プラットホームでの Java2 Runtime Environment

なお、javac コマンドは、system32 フォルダ中に存在しないので、ユーザ環境変数 PATH に設定したとおりに実行できた。

Monday, March 12, 2007

Windows で "STOP 0x0000007B" エラーが出ちまった!

職場の Windows 2000 サーバを起動しようとしたら、Blue Screen になって止まってしまった。ブートボリュームが破損していると判断し、復旧を試みる。

ドライブを取り外して、他の Windows マシンにつなぐのは面倒なので、Windows XP の OEM ディスクで CD-ROM ブートし、自動で実行されるコマンドプロンプトから


CHKDSK C: /F


を実行。これにより、ハードディスクの不良セクタが修正され、元通りハードディスクから起動できるようになった。ちなみに、CHKDSK に指定する引数の順番に注意。オプション、ドライブ名の順でも実行できたが、復旧には失敗し、ハードディスクからのブートはできないままだった。

Wednesday, February 21, 2007

信用取引メモ(買い方と売り方の関係、逆日歩など)

信用買いした株は証券会社に担保としてとられるわけだが、証券会社はその株を売り方にレンタルすることができる。

つまり、売り方にレンタルできる株は、証券会社が自分で持っている株と信用取引の買い方が担保としている株だ。トレーダーが現物買いしている株はレンタルにまわすことはできない。

買い方は、お金を借りて株を買い、その株をレンタルに出していることになる。したがって、借りた金の金利を支払い、レンタルに出した株のレンタル料を受け取ることができる。金利は必ずレンタル料より大きくなるようで、その差額が買い方が証券会社に支払う金利になる。

一方、売り方は、レンタルした株を売り、その代金を証券会社に預けているということになる。したがって、レンタルした株のレンタル料を支払い、預けた金の金利を受け取れる。買い方とは逆に、金利がレンタル料より小さくなることはなく、売り方は証券会社から支払いを受け取ることになる。金利が低い状況だと、これが 0 になることもある。

証券会社から見ると、買い方が買った株を売り方にレンタルし、買い方に貸した金は売り方が空売りした売却代金で穴埋めできることになる。全体として、買い方から売り方へ金が流れており、そこから証券会社は仲介手数料を抜き取る。先に述べたように、金利が低いと、買い方からの金を証券会社が全部とってしまうことになる。

このように、原則として、買い方から売り方へと金は流れる。ただし、例外が2つあって、それは

  • 株の配当が支払われるとき
  • 貸し株の需給が逼迫してるとき
である。企業が支払う配当金は、株を現物買いしている人に支払われるので、信用買いで株をもっている人には、売り方が配当金を支払うという約束になっている。したがって、権利確定日をまたいでショート・ポジションをもっていると、買い方への配当金を支払わねばならない。

貸し株の需給が逼迫していると、売り方は追加のレンタル料を支払わねばならなくなる。これを逆日歩とよび、買い方に対して支払われる。

貸し株の需給状況を表すのが、信用倍率(貸借倍率)であり、信用買い残÷信用売り残、で計算される。

Sunday, February 11, 2007

PostgreSQL 8.1.5 の設定

先日、インストールしたので、設定を進めてみた。昔 7.2 をセットアップしたときのメモや Web 上でのオンラインドキュメントを参考に

  • ユーザとデータベースの作成
  • クライアント接続とセキュリティの設定
  • JDBC ドライバのセットアップ
をやってみた。

ユーザ、データベースの作成は、7.2 の頃と同様にできた。PostgreSQL 管理者ユーザで


$ createuser user_name


のようにすればいい。このとき、7.2 のときと同様にデータベース作成の権限、ユーザ作成の権限を与えるかどうかが聞かれるが、新しく superuser の権限を与えるかどうかも聞かれた。

このままだとクライアント認証のときにパスワード認証ができないので、PostgreSQL 管理者ユーザで template1 データベースに psql コマンドで接続し、ALTER USER 文でパスワードを設定した。template1 データベースというのは、もともとある管理用のデータベース。7.2 と同じようにできた。

オンラインマニュアルにしたがい、pg_hba.conf を編集することでクライアント認証(ホストベースのアクセス認証)をセットアップした。

Unix ドメイン経由の接続だけでなく TCP/IP 経由の接続を認めるには、pg_hba.conf を設定するだけでなく、postmaster を起動するときに -i オプションをつけなければならない。これにより、TCP/IP 接続を受け付けるようになる。もちろん、TCP/IP 接続が成功してはじめて、サーバがクライアント認証をチェックすることができるようになる。

7.2 のころはソースからビルドしたときに JDBC ドライバが作成されたはずだが、今回はそうではなかった。PostgreSQL の JDBC サイトから、PostgreSQL と JDBC のバージョンにあったものをダウンロードした。JDBC 3 のドライバを入手した。ここで作成されているドライバは Type4 だ。つまり Pure Java であるから、どのプラットホームでも使うことが可能だ。

Saturday, February 10, 2007

信用取引メモ(委託証拠金率)

信用取引では、証券会社に担保となる委託証拠金を差し入れ、信用買い、または空売りをすることができる。空売りのことをショート・ポジション、信用買いや現物買いをロング・ポジションをとるという。株価が上がると利益になるポジションをロング、下がると利益になるポジションをショート、というわけだ。

委託証拠金は最低でも100万から200万程度を用意しなければならない。金額は証券会社によって異なる。昔は2000万円ほど必要だったりしたようだ。

ポジションをとるとき、建玉の総額に対する証拠金の比率が委託証拠金率となる。たとえば、100万円の証拠金に対し、200万円信用買い(つまり、200万円分の株を買う)か200万円空売り(つまり、200万円分の株を借りてきて売る)すると、100 万/200万 = 0.5 = 50% となり、証拠金率は 50% ということになる。逆に見れば100万円しか用意していないのに200万円の取引をしていることになり、2倍のレバレッジを効かせていることになる。すなわち、委託証拠金率の逆数がレバレッジ率ということになる。

委託証拠金は現金で用意してもいいが、利息はつかないので、不利である。そこで現金の代わりに債券や株式で用意してもいい。これらを代用有価証券という。ただし、値下がりのリスクがあるので有価証券の時価そのままで評価することはせず、いくらか割り引いた価格で評価される。何割で評価されるかということを掛目とよぶ。国債などは90から95%、東証上場株式などは80%程度で評価される。

委託証拠金率 = 委託証拠金の評価額 / 建玉総額

であった。いったん信用取引をしたらポジションを変更しない限り、建玉総額は変わらない。ただし、委託証拠金の評価額は変わりうる。

まず、委託証拠金を有価証券で差し入れている場合は、価格の変動によって評価額が変わってくる。

また、建玉の損益によっても評価額が変わる。たとえば、ロング・ポジションとして200万円もっていて、それが10%値下がりしたとすると、20万円の損失である。同様にショート・ポジションとして200万円もっていたとして、その銘柄が10%値上がりしたとすると 20万円の損失である。委託証拠金からこの損失分を引いたものが評価額となる。

ということは、建玉で利益が出たなら委託証拠金の評価額が上がるはずだが、オンライン証券会社ではそうはしないことが多いようだ。まとめると、

委託証拠金の評価額 = 委託証拠金の時価 + 建玉の損益 - 取引手数料

となる。

さて、前述したように委託証拠金率の逆数がレバレッジ率であった。そこで、証券会社では委託証拠金率の最低ラインを決めることによって顧客のレバレッジ率の上限を定めている。証拠金率を50%にするということは、顧客が2倍までレバレッジを効かせることを認めるということだ。40%にしたなら、2.5倍までのレバレッジを認めることになる。顧客の委託証拠金率がこのラインを下回ると証券会社は新たな建玉を認めなくなる。

証拠金率があまりに下がり過ぎると、証券会社はリスク回避のために顧客に委託証拠金の増額を求めてくる。これが追証(Margin call)である。この証拠金率を最低証拠金維持率と呼ぶ。制度信用取引では 30% に定められている。

さらに、顧客が追証にも応じず、証拠金率が下がり続け、20% を下回ったとき、証券会社は顧客のポジションを強制的に解消することができる。買い玉だったら、そのときの株価で売ってしまい、金を返してもらうことができる。売り玉なら、そのときの株価で株を買ってきて、レンタルしていた株を返してもらうことができる。

たとえば、委託証拠金として 125万円の株を差し入れれば掛目 80% として 100万円相当になる。そして、200万円の株を信用買いしたとする。このとき委託証拠金率は 50% である。その後、証拠金として差し入れていた株が20%下落し、信用買いした株も 20% 下落したとする。

このとき、委託証拠金の評価額は (125万 * 0.8 * 0.8) - (200万 * 0.2) = 40万 となり、委託証拠金率は、 40万 / 200 万 = 0.2 = 20% になってしまう。すなわち、証券会社に強制的に建玉を決済されてしまう。

この例だと、買玉をすべて売り払って 160万 を確保する。40万足りないから(証券会社は最初に 200万貸している)、代用有価証券も売り払って 100万を新たにつくり、そこから 40万円回収する。

したがって、証拠金率を一定以上に維持しなければならないのだが、そのためには、

  • 建玉総額とその損益の管理 = 建玉管理(ポジション・コントロール)
  • 委託証拠金の時価の管理 = 資産管理(アセット・マネジメント)

の2点が絶対に必要になる。

ここで少し考えてみたのだが、委託証拠金率が 0 にならない限り、証券会社が貸した金やレンタルした株を回収できなくなることはないはずである。

なぜなら、証拠金率 > 0 ということは、

委託証拠金の評価額 = 委託証拠金の時価 - 建玉の損失 > 0

ということである(取引手数料は捨象)。回収しなければならないのは、建玉総額であり、建玉を処分しても足りない部分、すなわち、建玉の損失分は、委託証拠金の評価額でまかなえることが分かる。

つまり、委託証拠金率というのは、建玉をすべて決済し、貸した金やレンタルした株を回収した後に残る金額が建玉総額に占める割合だということもできる(証拠金が有価証券なら掛目だけ割り引いているので、決済後に残る金額が建玉総額に占める割合は委託証拠金率よりも高くなる)。

今までは金利のことは考えなかったが、当然、信用取引には金利がかかる。

一般信用取引では、証券会社が顧客と相対取引する。制度信用では、証券会社は顧客と証券金融会社との間を仲介するだけである。したがって、制度信用では、金利の他、返済期限や信用取引可能な銘柄(貸借銘柄)は証券金融会社や取引所が一律に決めている。一般信用の場合は、証券会社ごとに決めることができる。

Saturday, January 20, 2007

PostgreSQL 8.1.5 をインストール

Ubuntsu 6.06.1 にインストール。サーバガイドにあるように apt-get でインストールしようとしたのだが、「使用できるパッケージがない」 というようなことを言われた。

そこで、ソースをダウンロードしてきてビルドしたのだが、下にあるようにいろいろ問題が発生した。なんとか解決したけど。。。


./configure --prefix=/opt/pgsql

を実行。7.2 のときとは違って、--with-mb=EUC_JP オプションは指定しなくていい。7.3 以降からデフォルトでマルチバイト文字対応がなされている。

configure を実行中、libreadline.so がないというエラーが出た。これは linker name が定義されていないためだと分かったので、/lib/libreadline.so というシンボリックリンクを /lib/libreadline.so.5 に張ってやった。

しかし今度は、readline/readline.h がないというエラーが発生。仕方ないのでヘッダファイルのためだけに libreadline ライブラリ を /usr/local/lib/ に新たにインストールした。/lib/ に作った linker name は消して、/usr/local/lib/ に新たに linker name をつくったが、今度もエラーになった。config.log を見ると

/usr/local/lib/libreadline.so: undefined reference to `tgetnum'
/usr/local/lib/libreadline.so: undefined reference to `tgoto'
/usr/local/lib/libreadline.so: undefined reference to `tgetflag'
/usr/local/lib/libreadline.so: undefined reference to `BC'
/usr/local/lib/libreadline.so: undefined reference to `tputs'
/usr/local/lib/libreadline.so: undefined reference to `PC'
/usr/local/lib/libreadline.so: undefined reference to `tgetent'
/usr/local/lib/libreadline.so: undefined reference to `UP'
/usr/local/lib/libreadline.so: undefined reference to `tgetstr'
collect2: ld returned 1 exit status

というメッセージがある。どうも、新たに入れた libreadline が依存しているライブラリがあるようなのだ。仕方ないので、新しく入れた libreadline は使わずにヘッダファイルだけ使うことにして、linker name は /lib/ にもう一度作り直した。

しかし、

configure:7805: ./conftest
./conftest: symbol lookup error: /usr/local/lib/libreadline.so.5: undefined symbol: BC
configure:7808: $? = 127
configure: program exited with status 127

というエラーが出た。どうも /usr/local/lib/ のを見に行っている。ldconfig をやり直してみたがうまくいかない。仕方ないので、/usr/local/lib/libreadline.so.5 を削除したら、うまくいくようになったが、ldconfig をルートで実行すると、また同じエラーになる。仕方ないので /usr/local/lib/libreadline.* はすべて削除した。ヘッダファイルは、/usr/local/include/readline/ 内に残っているので、これでうまくいくようになった。


libz でも同じ問題が出たので、/usr/lib/ に linker name を作成し、ヘッダファイルがないのは、ダウンロードしてきてビルドすることで /usr/local/include/ にヘッダファイルが作成されて解決した。このとき/usr/local/lib/ にも静的ライブラリが作成された。ま、害はないので放置。

これでうまくいったので、

make
su
make install

でインストール。 --prefix=/opt/pgsql で指定したディレクトリは自動で作成された。

管理用ユーザ postgres を作成。PGDATA 等の環境変数も設定した。

そして、

# mkdir /opt/pgsql/data
# chwon postgres /opt/pgsql/data

のようにして、データベースクラスタとなるディレクトリを作成。その後、postgres ユーザで

$ initdb -E EUC_JP

としてデータベースクラスタを作成。デフォルトの文字セットとして EUC_JP を指定している。これは、createdb でデータベースを作成するときに同じオプションを使って文字セットを変更することもできる。initdb にはロケールも指定できるが、ここでは指定していない。

postgres ユーザで

$ postmaster -S

としてデータベースサーバを実行。これでデータベースクラスタに接続できるようになる。この後、postgresql-8.1.5/src/test/regress/ に移動し、

$ make installcheck

でリグレッションテストを行い、すべて OK であることを確認した。この際、ソースは別ユーザで展開してビルドしたので、postgresql-8.1.5/ 以下の所有者を一時的に postgres に変更してリグレッションテストを実行した。

Tuesday, January 16, 2007

Windows で Tomcat

Tomcat 5.5 をインストールしてみた。サイトから Windows 用の Installer ファイルをダウンロードしてきて実行するだけなのでインストールは簡単にできる。

インストール時に admin 用のパスワードが聞かれるのでそれに答える。

「スタート」 から Tomcat をインストールしたディレクトリを開いて、bin\tomcat5.exe をダブルクリックすると Tomcat が起動し、インストール時に指定したポートでリクエストを待つようになる。この後、同じように 「スタート」 からアクセスできる Tomcat Manager をクリックすると、Web アプリケーションマネージャという管理用の Web アプリケーションを実行することができる。この際、admin 用のパスワードが聞かれる。

Tomcat の起動は、「スタート」 からアクセスできる Monitor Tomcat をクリックしてもいい。そうすると、ステータスバーにアイコンが表示される。ここを右クリックすることで、Tomcat 起動、その他の操作をすることができる。exe ファイルをダブルクリックするよりもこの方がいい。

Tomcat Manager における配備のところで、Web アプリケーションを配備することができる。いくつかやり方はあるが、Context Path で /hogehoge のように任意のパスを指定する。そして、「War ファイルまたはディレクトリのパス」 で war ファイル、またはWeb アプリケーションのルートとなるディレクトリのパスを指定すればいい。

Eclipse 上で Web アプリケーションをビルドできるようにプロジェクトを構成してやれば、上のようにしてテストすることができる。

Wednesday, January 10, 2007

memcached インストール

memcached 1.2.1 をインストールしてみた。

http://www.danga.com/memcached/

ダウンロード・解凍し、README を読んでみると、libevent というライブラリが必要であり、libevent は epoll を実装したカーネルに依存するとある(Linux の場合)。epoll は必須というわけではなく、libevent は通常の select システムコールを使っても動くらしいが、その選択はいいとはいえないらしい。

http://www.linux.or.jp/JM/html/LDP_man-pages/man7/epoll.7.html

Linux カーネル 2.6 以降なら epoll は実装されているようで、これは問題なかった。


libevent 1.2a をダウンロードして、インストール。

http://www.monkey.org/~provos/libevent/

README にしたがい、

$ ./configure && make
# make install
$ make verify

でインストール。最後のは、Regression テスト。これで /usr/local/lib/ にインストールされた。また、/usr/local/bin/ に event_rpcgen.py という Python スクリプトもインストールされる。

この後、memcached も次のようにインストール。

$ ./configure --with-libevent=/usr/local/lib/
$ make
# make install

これで /usr/local/bin/ に memcached と memcached-debug というコマンドがインストール。

以上が済んで、

$ memcached -m 256 -l 127.0.0.1 -p 11211

とすると、

memcached: error while loading shared libraries: libevent-1.2a.so.1: cannot open shared object file: No such file or directory


というエラーメッセージが出た。どうも先にインストールした libevent を見つけることができないようだ。実際、

$ ldconfig -p

とやっても、libevent は出てこない。/usr/local/lib は /usr/lib, /lib と違って、常に検索されるライブラリではないからだ。そこで、/etc/ld.so.conf を作成し、そこに ld.so.conf を記述し、ldconfig を実行した。こうすると、/etc/ld.so.cache に登録されるので、検索されるようになる。実際、ldconfig -p で確認できた。

その後、

$ memcached -m 256 -l 127.0.0.1 -p 11211

とすると、起動できた。-d オプションをつけるとデーモンになる。

$ telnet localhost 11211

で接続はできることを確認。後はクライアント API をセットアップしていろいろ試そう。

Tuesday, January 09, 2007

Eclipse でワークスペースにデフォルトの文字コード、改行コードを設定するには?

Window メニューから 「Preferences」 を選び、そこで Workspace を選択する。そこにある Text file encoding と New text file line delimiter でワークスペースデフォルトにしたいものを選択する。

Eclipse 上のエディタで、ファイルの内容すべてをコピーし、その後、そのファイルの Preferences で文字コードを変更し、オープンし直してから、ペーストするとファイルの文字コードを変換することができる。しかし、うっかり改行コードのことを忘れていると、Unix のシェルスクリプトの改行コードを Dos/Windows 風にしてしまい、いざ実行しようとして実行できない現象に悩まされたりするので要注意。今日は、まさにこれにはまってしまった。

改行コードが Unix 風でないとシェルスクリプトが動かない件について

Unix の改行コードは LF(\n)、Dos/Windows の改行コードは CRLF(\r\n) になるのが普通だが、改行コードが LF でないと Unix のシェルスクリプトがうまく動かない場合がある。改行コードが CRLF だと vi で開いたときに行末に ^M という文字が出ることが多いが、そうならずにきれいに表示される vi もあるので、そのために原因が分かりにくいときがあるので要注意。

今日はそれではまってしまった。シマリンによると Perl スクリプトでも改行コードが原因でうまくいかないことが多いらしい。

同じことは、文字コードの食い違いでも発生する場合がある。慎重を期すなら、スクリプト実行前にシェルの環境変数を設定するなどして文字コードをスクリプトで使っている文字コードにあわせるべきだろう。

Sunday, January 07, 2007

Subversion でのマージについてのメモ

マージには、次の3つのものが関係してくる。
  • マージの始点となるブランチのリビジョン
  • マージの終点となるブランチのリビジョン
  • マージ結果を保存する作業領域
始点となるリビジョンと終点となるリビジョンの差分を取るのは当然だが、同時に始点と作業領域との差分も取る。そして、始点と終点の差分と始点と作業領域の差分をマージしたものを始点に適用したものを作業領域に置くのだ。

マージがうまくいけば、マージ結果だけが作業領域に残る。しかし、うまく2つの差分がコンフリクトして、うまくマージできなかったときは、マージが適用されたファイル中に衝突マーカーが挿入されるとともに次の3つのファイルができる。
  • *.merge-left.r{リビジョン番号}
  • *.merge-right.r{リビジョン番号}
  • *.working
最初のファイルは、始点となったファイルであり、2番めは終点となったファイルであり、3番目はマージ前の作業領域のファイルである。コンフリクトをマニュアルで解消し、svn コマンドで衝突の解消を実行すれば、この3つのファイルは消え、Commit ができる状態になる。

通常の更新(Update)もマージの一種である。更新の場合は、始点となるのが作業領域の BASE であり、終点となるのがリポジトリの HEAD であり、現在の作業内容が冒頭の 「マージ結果を保存する作業領域」 に相当する。この場合も、コンフリクトしてうまくマージできなかったときは、次の3つのファイルができる。
  • *.r{BASE のリビジョン番号}
  • *.r{HEAD のリビジョン番号}
  • *.mine
*.mine というファイルがマージする前の作業ファイルの内容を保存したファイルだ。残り2つがそれぞれ始点、終点に相当する。結局、更新(Update)というのは、BASE を始点、HEAD を終点にしてのマージ作業に他ならないのだ。

Friday, January 05, 2007

diff の出力の見方

Unix の diff コマンドは、 ファイルを1行ずつ比較していって、その差分を出力する。その出力の見方を今まであいまいにしてきたので、ひとつ調べてみた。

まず、1.txt を次のように作る。

1:Jan
2:Feb
3:Mar
4:Apr
5:May
6:
7:Jun
8:
9:Jul
10:Aug
11:Sep
12:Oct
13:Nov
14:Dec


数字とコロンは行番号を示すためのもので、ファイルには実際に書き込まれていない。もう1つ 2.txt として


1:Jan
2:Feb
3:Mar
4:4
5:four
6:May
7:6
8:six
9:sex
10:
11:Jun
12:
13Jul
14:Aug
15:Sep
16:Oct
17:Nov
18:Dec


この2つのファイルを diff に渡して

diff 1.txt 2.txt

とすると、その出力は、


4c4,5
< Apr
---
> 4
> four
5a7,9
> 6
> six
> sex


となる。これはどういう意味かというと、1つめのファイルの4行目を change して2つ目のファイルの4行目から5行目にする。さらに1つ目のファイルの5行目の直ぐ下に2つ目のファイルの7行目から9行目を Add する。こうすると1つ目のファイルが2つ目のファイルと等しくなる、ということだ。

< で始まる行が1つ目のファイルの対応行であり、> で始まる行が2つ目のファイルの対応行だ。Add の場合は、1つ目のファイルの対応行は示されていないが、これはとくに必要ないからだ。

diff に渡すファイルの順序を入れ替えて

diff 2.txt 1.txt

とすると、さっきの出力と論理的に反対の結果が得られる。


4,5c4
< 4
< four
---
> Apr
7,9d5
< 6
< six
< sex


7,9d5 というのは、先ほどの 5a7,9 とちょうど逆の操作なのだが、うまく文章にできない。要するに7行目から9行目を Delete しろということだ。

Thursday, January 04, 2007

RUP とは

Rational Unified Process(ラショナル統一プロセス)のこと。いわゆる Unified Process の原型はこれだろう。オブジェクト指向ソフトウェアエンジニアリングのベストプラクティスをまとめたものといえる。

UP は、ウォーターフォールプロセスと異なり、反復的で段階的な開発プロセスである。これは、プロジェクトの進展につれて、次のようなフェーズをたどり、

  • 方向フェーズ
  • 推敲フェーズ
  • 作成フェーズ
  • 移行フェーズ
各フェーズは1つ以上の反復から構成される。反復とは、時間を区切って、その中で達成すべき目標を明らかにしたものである。各反復終了後に、完了したものについて評価し、必要ならばプロジェクト計画を調整し、次の反復のための詳細な計画を練る。

各反復でおこなわれる作業は次のような分野に分けられる。

  • ビジネスモデリング
  • 要求
  • 分析・設計
  • 作成
  • 移行
  • 構成と変更管理
  • プロジェクト管理
  • 環境
この中で最後の3つは、各反復の評価期間になされるようなことだろうか。これらの作業はフェーズによって重みが違ってくる。たとえば、ビジネスモデリングや要求などは、方向付けフェーズ・推敲フェーズで比重が大きいだろうし、分析・設計などは推敲フェーズでの比重がもっとも大きいだろう。もちろん、要求作業が作成フェーズに入るような場合もある。要求漏れや要求の変更に対応できるようにするためであり、これがウォーターフォールと違い、反復・段階的なプロセスの利点である。

RUP では、誰が(役割)、何を作成するために(成果物)、何をするのか(作業)ということが決められている。

4つのフェーズの各々は、その終点を特徴付ける目標とマイルストーンをもっている。各マイルストーンは、次のフェーズに進むときのリスクを軽減するために達成する必要があり、それを評価するために作成しなければならない成果物が決められている。

方向付けフェーズの終点では、

  • プロジェクトの範囲(開発すべきもの)・予算・高水準のスケジュールについて、利害関係者(ユーザ、買主、開発者、プロジェクト管理者など)が合意していること。
  • 要求(製品に対する期待と優先度)を利害関係者が理解していること。
  • 気がついたリスクについて合意し、それに対する対処策が考えられていること。
が求められる。推敲フェーズでは、

  • 主要なアーキテクチャの決定がなされ、それを実装した実行可能なアーキテクチャ(プロトタイプ)が完成する。
  • それが製品に対する要求を満たしていることを確認すること。
  • 作成フェーズの全体的な計画と各反復計画が立てられていること。
  • 適切な支援環境と開発基盤が確立されていること。
が求められる。作成フェーズでは、

  • 製品の α ヴァージョン(最初のユーザへリリースできる程度の成熟度をもっている)が完成していること。
  • ユーザがテストや使用の準備が整っていること。
が求められる。そして、移行フェーズでの成果物は、

  • 開発された製品
  • リリースノート
  • 導入および設定手順書、スクリプト
  • エンドユーザ支援資料
ということになる。

RUP で定義されている作業や成果物をすべて作成しなければならないということではない。プロジェクトの性格にあわせて柔軟に取捨選択すればいい。

Blog Archive