WEB相談室

Webページ作成に関しての何でも掲示板です。

タイトル:索引ファイルについて

0:[投稿] 靴下カタオ [MAIL] [URL] [2002/02/26 01:59 ][環境:WIN+IE WIN系+Perl]

初めて質問させていただきます。どうぞよろしくお願いします。
Perl を勉強し始めてまだ間もないのですが、
複数のカウンタを管理するなどの目的で、
キーを指定して書き込み、読み出しするファイルを使うことを考えています。
現在手元にある三冊の解説書には、あまり詳しく載っていなくて、
Perl では単独では難しいように見えます。
NDBM というデータベースを用いる方法が取り上げられていますが、
既存のデータベースにアクセスするのではなく、
システムを最初から構築する場合、どのような方法が一般的でしょうか。
また、キーを使ったファイルを用いたサンプルスクリプトをご存じでしたら
お教えいただけないでしょうか。どうかよろしくお願いします。


1:[回答] R.M [2002/02/28 10:58 ]

$key = $ARGV[0];
$datafile = "$key.dat";
open(IN,"$datafile");
$count = <IN>;
close(IN);
$count++;
open(OUT,">$datafile")
print OUT $count;
close(OUT);
print $count;

こんな感じの処理で、以下のようにアクセスとか
counter.cgi?no1

dbmopen とかいう関数を使っても良いと思います。


2:[回答] 靴下カタオ [MAIL] [URL] [2002/03/01 00:24 ]

R.M さん、どうもありがとうございます。
自分のPCで Perl のプログラムをデバッグするには
R.M さんから教えていただいた方法でやりたいと思います。

実際のサーバでは、何十万件のデータを処理する必要があり
DBMを使うことを考えていますが、
超初心者なもので、いろいろわからないことがありますので、
できれば教えていただけないでしょうか。

DBMでは、ファイルの排他が完全ではないということですが、
これをうまく解決する方法はないでしょうか。

何十万件のデータをインタープリタ言語である
Perl で処理することは現実に行われていることでしょうか。

以上基本的なことですけど、できればまたお教え下さい。
どうかよろしくお願いします。


3:[質問] 靴下カタオ [MAIL] [URL] [2002/03/01 00:26 ]

すみません。前の書き込みは『回答』ではなく『質問』です。


4:[回答] 変人鬼人 [2002/03/01 15:53 ]

質問が、複数のカウンタの設置なのか、
キーを指定して書き込み、読み出しするファイルI/Oなのか、
DBMの排他なのか、
何十万件のデータをPerlで処理することの是非か、

わからんです...。


5:[回答] ふじ [URL] [2002/03/01 20:24 ]

扱うのが数十万件のオーダーになるのなら、(しかも仕事で、ということなら)
RDBMS を使うのが現実的だと思います。
ファイルの破損とかロックとか、そういうやっかいな問題は DB に任せられますから。

フリーで使える RDBMS としては、有名どころでは PostgreSQL や
MySQL などがあります。Perl からそれらを使えるインターフェース
(DBIモジュール)も揃っていますし。

> 何十万件のデータをインタープリタ言語である
> Perl で処理することは現実に行われていることでしょうか。
同時アクセスが起きなかったり、負荷を無視できる条件なら Perl のみでも
十分可能でしょう。例えばログの集計とか。

DBM でも、キーが一つであるようなデータなら、数十万件でも扱えると思います。
試しに DB_File モジュールを使って、
キーが 1..100*10000 、値の初期値は全て 1
な DBM を作成し、ランダムに読み出し、加算、減算などをしてみましたが、
「DBM ファイルをオープン。1レコード読み出し、加算、クローズ」
という操作は、0.1秒以下で実行できました。

# Athlon 1G, Mem 512MB, Linux(kernel2.4.4), Perl 5.6

検索に使用するキーが複数あったり、ロックに不安があるのであれば
RDBMS を使うことをお薦めしますが。

use DB_File;

tie %hash, 'DB_File', 'test.dbm', O_CREAT|O_RDWR, 0666, $DB_HASH;
$key = int(rand() * 100 * 10000);
print "key=$key value=", ++ $hash{$key}, "\n";
untie %hash;


6:[回答] ふじ [URL] [2002/03/01 20:35 ]

あ、でもたかがカウンタに RDBMS 使うってのもおおげさですね。

数十万個のカウンタを用意する必要があるのでしょうか?
それとも、カウンタのログが数十万件に達する可能性がある、ということなのでしょうか。

前者なら(どういう状況か考えにくいですが)、1ファイルで管理しないで
1カウンタ1ファイルで。(同じディレクトリに数万のファイルを置くと大変なことに
なるので注意)

後者ならログはテキストファイルに追記していけばいいのでは。
単に、Webサーバのログを集計する、という手もあります。
カウンタで独自にログを吐き出すよりも、そっちのほうが確実かも。


7:[質問] 靴下カタオ [MAIL] [URL] [2002/03/02 01:47 ]

変人鬼人さん、ふじさん、どうもありがとうございます。

変人鬼人さんのご指摘ですが、
何分にも、DBに関する知識がほとんどなく、
私の頭の混沌とした状態をそのまま
この掲示板にぶつけてしまった、という感じで、
読んでいただいた方に不快やとまどいを感じさせて、
本当に申し訳なく思います。すみません。

ふじさん、すみませんがまた色々教えて下さい。

『Perl 入門 第2版』エリー・クイグリー著 株式会社ピアソン・エデュケーション

の中のサンプル・スクリプトでは、

use AnyDBM_File;

でインクルードし、

dbmopen(%states, "statesdb", 0666) || die;

でオープンしています。解説文では
『関数 dbmopen が、DBMファイルをオープンするか、または新たに作成する。』
とありますので、私はこれ以外何もしないでできてしまうと思っていたんです。
しかし、どうも、ふじさんのご回答を読ませていただいて、
これ以前にDBのソフトをインストールしておかないといけなかったのか、
という気がしてきました。
逆に、やらないといけないことは、

次のスクリプトを実行する

#!/usr/local/bin/perl
use DB_File;

tie %hash, 'DB_File', 'test.dbm', O_CREAT|O_RDWR, 0666, $DB_HASH;
$key = int(rand() * 100 * 10000);
print "key=$key value=", ++ $hash{$key}, "\n";
untie %hash;

以外にどういうことがあるのでしょうか。

実は、この程度の非常に初歩的な問題を他のBBSで質問して、
何度か顰蹙(ひんしゅく)をかったことがありますが、
私にとっては、『入門書』という名目の本なのに、
どうして一番基本的なことをはしょってるんだろう、
と思います。もちろん、これで何年もコンピュータの
仕事をしてきて、マニュアルや解説書にあたってきましたので、
いいかげん、慣れないといけないんですが … 。

> 何十万件のデータをインタープリタ言語である
> Perl で処理することは現実に行われていることでしょうか。

は、全レコードに対するバッチ処理のときの処理速度の問題です。
コンパイラ言語の場合、ファイルの入出力に要する時間に比して、
メモリ上での処理はほとんど無視していいくらいでしょうが、
仮に、インタプリタ言語では、これとは逆に、
オープン、1レコード読み出し、加算、クローズ
のうち、オープン、クローズは最初と最後だけですので無視し、
加算にかかる時間が、読み出し、書き込みに比して
桁外れに処理時間が長いと仮定してみましょう。
ひつのレコードに対する『加算』だけで 0.1秒かかるとすると、
百万件で、十万秒、つまり約28時間かかってしまうということになり、
C等と比べると、問題にならないくらい
処理が遅くなるということになります。

このようなバッチ処理(一括処理)に
Perl のプログラムが使われることがあるのか、
もし使えないとしたら、
どのような代替案があるでしょうか。

以上、私の頭の混沌とした状態は
まだ続いていて、ご面倒をかけますが、
また教えていただけないでしょうか。
どうかよろしくお願いします。


8:[回答] ふじ [URL] [2002/03/02 02:35 ]

> 桁外れに処理時間が長いと仮定してみましょう。

> C等と比べると、問題にならないくらい
> 処理が遅くなるということになります。

仮定するのは結構ですが、その仮定が正しいのかどうかを検証するには
実験するしかありませんよ。
# よほど Perl や C や、OS や、その他すべてのことに付いて
# 精通していれば想像だけでもいいかもしれませんが、
# そういう人はこういう質問をしないでしょうし。

で、こういう場合、簡単なスクリプトを書いてベンチマークを取るなどして、
実験するのが手っ取り早いと思うのですが、どうでしょう。
Perl で処理速度のベンチマークを取るには、Benchmark モジュール
というのが使えます。

> このようなバッチ処理(一括処理)に
> Perl のプログラムが使われることがあるのか
私はよく使っていますが(ワンライナとかでちゃちゃっと)、
あなたの望むバッチ処理について Perl が向いているのか、それとも
C で書くべきなのか、そもそも何をやりたいのかが具体的に書かれていないと
「代替案」も出しようがないです。


> use AnyDBM_File;
>
> でインクルードし、
>
> dbmopen(%states, "statesdb", 0666) || die;
>
> でオープンしています。解説文では
> 『関数 dbmopen が、DBMファイルをオープンするか、または新たに作成する。』
> とありますので、私はこれ以外何もしないでできてしまうと思っていたんです。

これ、実際にやってみましたか?
AnyDBM_File が使える環境ならば、それでいけると思いますが、
できなかったんでしょうか。

・実際やってみたのか
・やってみた結果できなかったのか
・その場合どういうエラーや現象が起きたのか
・実行した環境 (OS, Perl のバージョン、状況を再現する最低限のスクリプト)

などの情報が提示されていないので、どう答えていいのか分かりません。

混乱されているようですので、まず何をやりたいのか具体的に。
自分が何をして、その結果どうなったのか。
それをどういうふうにしたいのか、をまとめてみたほうがよろしいかと。


9:[回答] しなのむし [2002/03/02 06:54 ]

>DBMでは、ファイルの排他が完全ではないということですが、
>これをうまく解決する方法はないでしょうか。

ダミーファイルにロックをかける処理を
挟みこめば間接的に排他出来ますよ。

DBMを使う時の概念ですが
一度の処理がkeyを元に少数のレコードしか操作しないようなタイプなら
レコード総数が百万件でも速度的には問題は無いと思います。
逆に全てのレコードを総なめにするような処理には向きません。
場合によってはテキストデータの方が速いくらいです。


10:[完了] 靴下カタオ [MAIL] [URL] [2002/03/03 02:27 ]

ふじさん、しなのむしさん、どうもすみません。

しなのむしさんから教えていただいた中で、

>場合によってはテキストデータの方が速いくらいです。

という記述は意外でしたが、

>逆に全てのレコードを総なめにするような処理には向きません。

という言葉で、全てが言い表されていると思いました。
やはり、DBM を使うことは、あっさりあきらめることにします。

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

回答(必須): 状態:

お名前(必須):

e-mail:

URL:




[戻る]

ChaichanPAPA's World