JavaScriptでデータベースを作りたい
ホームページでデータベース機能がついているといいなぁ、、、と思ったことはありませんか?趣味のコレクションをつづったデータの一覧などを必要なものだけ表示したい、、、こういうのってサーバー側にデータベースを持っていてPerlなどでCGIを利用しないとなかなか実現できない機能です。
この検索して表示、という働きをクライアントサイド、つまりJavaScriptでしてしまおう!という実験です。ページを見ているパソコンだけでデータベース的な動きができるということは、一度全てのデータをパソコンに取り込む必要があるので、データのサイズはあまり大きなものはできません。
ですが、100件~300件程度のリストなら十分動く仕組みをつくることは可能です。(もちろん1件のレコードのサイズにもよりますが、、、)
検索とは ~アルゴリズムの検証
ここで、検索の基本を考えてみたいと思います。
検索は大量のデータから自分が意図した条件に合致するデータだけを取り出すことを言います。どのようにして取り出すか、というプログラム上の仕組みを検索アルゴリズムといいますが、このアルゴリズムによって検索のスピード等効率がかなり変わってきます。
ただ、一番単純な検索方法というのは、一つ一つのデータを順番に比較していく方法です(線形検索・シーケンシャルサーチといいます)。条件に合致したものを順次表示なり保存なりすることで、検索結果を抽出することが可能になります。
ただ、この方法の欠点としては、全てのデータを比較することになるので、時間が非常にかかるということです。もしも1万件のデータがあった場合には1万回の問い合わせをデータベースにするわけで、目的のデータにたどり着くために、平均で5000回の比較が必要になります。
この他、検索アルゴリズムには有名なものではバイナリ検索などがありますが、ここでは、とりあえず線形検索(シーケンシャルサーチ)を試すことにします。(仕組みが簡単なので)。全てのデータを検索するので大量データには向きません。
JavaScriptの文字列比較
(アルゴリズムを除いて)検索で一番重要なのは比較の方法です。この文字列の比較をする関数がJavaScriptにはあります。
indexOf();
これは、文字列を比較して、もしその文字列に合致するものがあれば、その合致した場所の数字を返します。
例えば、検索される文字列を「DATA」、検索したい言葉を「sword」だとすると、
check = DATA.indexOf(sword,0);
というように使います。
DATA="ABCDEFGHIJKLMN";
sword = "G";
だとすると「check」には「6」が入ることになります。(Aは1番ではなく0番目なので、Gは7番目ではなく6番目の文字となります。) もし、sword="Z";で一致するものがない場合には「-1」が返されることになります。下にサンプルを用意したので、適当な文字を入れて試してみてください。
indexOf()のサンプル
これ以外にも文字列検索をする関数がJavaScriptにはありますが、単純な検索を実行するにはこの命令で十分でしょう。
これをひとまとまりのデータとして検索可能にするためには次のようなJavaScriptを書くことになります。
ちょっとだけJavaScript解説
原理は簡単ですし、上のサンプルのソースをコピーするだけでOKなので、それでもいいのですが、JavaScriptの解説が必要かなぁ、、、とも思うので、一応解説です。(^^;
最初に、データベースに格納するデータの定義からです。詳細なJavaScriptの解説は省略させてください。
// 配列
db = new Array;
// カンマ区切りでデータを用意
db[0] = "データ01,データ02,データ03";
db[1] = "データ11,データ12,データ13";
・・・
db[100] = "データ101,データ101,データ101";
まず最初にデータを配列として格納しますので、配列の宣言をしています。「db = new Array;」という部分がそうですね。
その後、準備された配列にカンマ区切のデータを順番に入力しています。ここでカンマ区切にしたのは、その方がデータが準備しやすいかな、、、と思ったからです。データの格納方法については他にも配列ではなく、オブジェクトを定義してそこに格納する方法もあります(こちらの方がJAVAのオブジェクト指向っぽいですね、、、いずれ紹介します。)
次に、検索ボタンを押されたときに検索を実行する関数を定義します。
function searchDisp(){
ここに、実行内容を記述・・・
}
この「searchDisp()」という関数を、検索ボタンが押されたら実行するのですが、この関数の処理の中で、データベースから検索したい言葉を探し出す処理を見てみたいと思います。
*左の行番号は便宜的につけていますので、実際のスクリプトの行と一致しません。
01: var cnt = 0;
02: /* 検索 */
03: for (var i = 1; i < dbLength; i++){
04: /* 検索する */
05: var check = db[i].indexOf(sword,0);
06:
07: if (check >=0 ){
08: cnt++;
09: /* テーブルタグ */
10: document.write("<tr>");
11:
12: /* 個別データをカンマ区切りで配列に */
13: result = db[i].split(",");
14: /* 個別データの個数をカウント */
15: var resultLength = result.length;
16:
17: document.write("<td>"+cnt+"≶/td>");
18: for (var j = 0; j < resultLength; j++){
19: /* 検索結果表示 */
20: document.write("<td>");
21: document.write(result[j]);
22: document.write("</td>");
23: }
24: document.write("</tr>\n");
25: }
26: }
この検索して表示する部分を少しだけ詳細に解説したいと思います。まず、3行目~26行目の繰り返し(FOR)で配列に格納したデータを順番に検索しています。「dbLength」で配列の大きさ、つまりデータの数を取得しているのでその回数だけ5行目でチェックしています。
03: for (var i = 1; i < dbLength; i++){
04: /* 検索する */
05: var check = db[i].indexOf(sword,0);
06:
07: if (check >=0 ){
・・・
25: }
26: }
もしも5行目の文字列比較で検索したい文字と一致するものがあれば変数「check」には0以上の数字が入るので、それを7行目でチェックします。
一致しなければ変数「check」は「-1」が代入されるので、7行目からの条件分岐(IF)は実行せずに次のデータを比較することになります。
12行目(下のソース)は一致した場合、データを表示する処理です。
12: /* 個別データをカンマ区切りで配列に */
13: result = db[i].split(",");
14: /* 個別データの個数をカウント */
15: var resultLength = result.length;
16:
17: document.write("<td>"+cnt+"≶/td>");
18: for (var j = 0; j < resultLength; j++){
19: /* 検索結果表示 */
20: document.write("<td>");
21: document.write(result[j]);
22: document.write("</td>");
23: }
13行目で配列に格納されたデータをカンマ(,)で区切って新たな配列変数「result」に代入します。15行目では区切られたデータの個数を数えています。
18~23行目でレコードにあるデータの数だけ、つまりさきほどの配列変数「result」の配列に入力されたデータの数だけ内容を繰り返し表示させます。
以上で、検索して一致したデータだけを表示させることが可能になります。原理はとっても簡単ですよね。
この方法の問題点
JavaScriptだけではないのですが、利用者側のパソコンでこのようなデータベースを実現させる場合の問題点として、データを隠すことができないということがあります。
通常、CGIなどを利用した検索ページなどでは、生のデータというのはデータベース内に隠ぺいされています。データを利用者に全て持っていかれないようにしているのです。
CGIなどを利用するサーバーサイドプログラムの場合には、サーバー内にあるデータの一部必要な部分だけを切り取って検索の対象としていますし、その部分だけを結果として表示します。
ですが、利用者の端末でデータを検索するということは、データはいったん全て利用者のパソコンに取り込まれなくてはならないのです。(JavaScript内にデータがかかれることになります。)
つまり、完全に取られても(見られても)OKなデータしかデータベースとして実装できません。ですが、もともと公開する目的で利用者に検索させているのですから、200~300件程度のリンク集とかならCGIを利用して難しいプログラムを設置するよりも手軽かもしれません。





