ホーム » t-saitoh の投稿 (ページ 206)

作者アーカイブ: t-saitoh

2025年5月
 123
45678910
11121314151617
18192021222324
25262728293031

検索・リンク

データベース・ガイダンス・内部スキーマ

初めて担当するデータベースの授業で、少し不安要素もあるけど、 まず最初にシラバス配布とデータベースシステムの重要性を解説する。 以下の話は、DBエンジンを使う利点の説明でもあり、 一方でDBの内部スキーマでどういう技術が必要となるかの説明でもある。 説明の中では、データベースに要求されるACID特性も交えている。

データベースエンジンを使わないなら

データベースの重要性を理解してもらうために、データベースエンジンを使わない場合は、 どういう方法を使っていたのかを解説。使用教科書には、データベースを使わない場合の直接ファイルを触る話が実例を交えて書いてないので、その辺をちょっぴり具体的に書いてみる。

データをまるごと読み込み

4年の情報構造論であれば、目的のデータを探す処理といっても、 ポインタや処理速度のオーダなどの理解を 深めるためにも、全データを最初に目的のデータ構造で一括読み込みをして、 リスト構造なり2分木なりハッシュという演習をしていた。 しかし、こういう方法は

  • データ件数が数万件を越えてきたら、主記憶がデータで埋め尽くされ、メモリが不足すれば仮想記憶が使われ性能低下といった問題や、
  • readonly でなければ、 途中でシステムダウンでデータ消失といった不安がつきまとう(耐久性:D)

といった問題がつきまとう。

シーケンシャルファイル

大量のデータを主記憶にすべて読み出しておくことは、 主記憶の浪費や、永続性記憶資源でないという点で、 問題がある。 であれば、必要に応じて読み出せばいいけど、 C言語初心者の fscanf() しか理解していなければ、 先頭から1件1件必要に応じて順次ファイル(シーケンシャルファイル)として 読み出すことになる。ただし、O(N)の時間がかかり、それこそン万件であれば、非現実的。

struct Data {
   char  name[ 10 ] ;
   int   age ;
} ;
struct Data data ;
while( ... ) {
   if ( fscanf( fp , "%s %d" ,
                     data.name , &data.age ) == 2 ) {
      // 読み込んだデータの処理
   }
}

ランダムアクセスファイル

先頭からアクセスを繰り返す時間が非現実的なのであれば、 配列のように、N番目のデータを一定時間で読み出せればいい。 こういう場合、データが固定長であれば、データサイズ×データ件数が、 そのまま並んでいるファイルをつくって、N件目を読み出したければ、 ファイル先頭から、fseek()などで先頭から、データサイズ×N[byte]目から、 データサイズだけ読み込めばいい。

// N番目アクセスを強調するために逆順アクセス
FILE * fp ;
fp = fopen( "filename.dat" , "rb" ) ;  // バイナリモードで開くこと
:
for( int n = SIZE - 1 ; n >= 0 ; n-- ) {
   struct Data data ;
   if ( fseek( fp , sizeof( Data ) * n , SEEK_SET ) == 0
        && fread( &data , sizeof( Data ) , 1 , fp ) == 1 ) {
      printf( "%s %d\n" , data.name , data.age ) ;
   }
}

fseek( fp , offset , SEEK_SET ) は、ファイル先頭から offset[byte] に、 読み書きの位置を移動させる関数。
fread( ポインタ , size , n , fp ) は、ポインタの先に、size[byte]のデータをn件分読み込む関数。 同様に書き込み版は、fwrite( … ) がある。

しかしながら、この方法は1件あたりのデータ長が一定だからできる方法。 また、途中でデータに追加や削除が発生したら、そのデータ領域を後ろに 移動させたり、前に詰めるといった処理をすることは、データ件数が巨大であれば、 非現実的。一般的には、追加ならファイル末尾に追加するなり、削除であれば 空き領域を詰めることはせずに、消えた無効データという目印だけつけておき、 利用者の少ない時間帯に、無効データの目印の場所を切り詰める処理を実行 することになるであろう。(トランザクション処理の一例) それに、N番目アクセスに fseek() + fread/fwrite のプログラムを書くのは、面倒だし、 複数の人が読み書きすると、一貫性:C , 隔離性:I のことを考え排他制御が必要。 また、書き込み処理の最中に、アプリケーションやOSなどが落ちた場合、 どこまでデータが書き込まれているのかという問題は、原子性:A,一貫性:C の 点でDBを使わない時には、極めて面倒な話となる。

ファイルシステムをデータベースの様に扱う

特定のキーで、データベースを検索する必要があって、削除データの切り詰めや、 可変長データのデータの取り扱いが必要であれば、ファイルシステムを データベースのように扱うプログラムを書く場合も多い。 例えば、名前から個人情報を探すプログラムであれば、名前自身をファイル名に して1件1ファイルで保存すれば、データ削除はファイル消去=unlink() になるし、 1件1ファイルであれば、データの追加で後続データを 後ろに移動させるといった手間もない。 可変長のデータであっても問題ない。

char fname[ 1024 ] ;
char* filename( char* s ) {
   sprintf( fname , "DataDirectory/%s.txt" , s ) ;
   return fname ;
}
void data_write( char* name , int age ) {
   FILE* fp ;
   if ( (fp = fopen( filename( name ) , "wt" )) != NULL ) {
        fprintf( fp , "%s\n%d\n" , name , age ) ;
      fclose( fp ) ;
   }
}
int data_read( char* name ) {
   FILE* fp ;
   char n[ 100 ] ; int age = -1 ;
   if ( (fp = fopen( filename( name ) , "rt" )) != NULL ) {
        && fscanf( fp , "%s%d" , n , &age ) == 2 )
      return age ;
   } else {
      return -1 ;
   }
}

こういった方法は、アプリケーションプログラムが無くても、OSの命令で 簡単にデータを作ったり消したりができるため、データの取り扱いが楽なのが特徴。 しかしながら、この方法には、以下のような問題がある。

  • nameに"../../../"といった文字が含まれていれば、目的ディレクトリ以外を触れるかも…
  • また、一般的なシステムでは、1つのディレクトリ内に保存できるファイル数には、上限があり、1万件以上は書き込めないかもしれない。
  • それにディレクトリ内のファイル情報は、配列的な単純テーブルだったり、単純線形リストだったりするため、ファイル数が巨大になれば、データ検索速度はO(N)で遅くなる。最近は、こういう問題に対応するために、ディレクトリ内のファイルをBTreeなどで保存するファイルシステムも開発されてきている。

RDBでない、古くから使われているDB

データベースで古くから使われているデータベースの1例は、 "Berkeley DB"が有名。 SQLなどのデータ操作言語を使うことなく、関数呼び出しで追加検索などを行う。 トランザクションや排他制御などが実装されているので、単純なデータベースであれば、 以前は、Berkeley DB を使うことが多かった。

循環リストと双方向リスト

前期授業がどこまで進んでいたか、学生&自分が忘れているので、 単純リスト構造の復習から説明を行う。

リストによるQueue

リスト構造によるstackの実現方法の説明が終わっているので、 次にリストを用いた待ち行列Queueの説明を行う。 最初に、top,tail の2つのポインタを使う事例を説明し、 その後に、循環リストにすればポインタが1つにすることができることを説明する。 特に、この循環リストは、プロセスキューのようなループするデータを表現するのに 向いていることを紹介する。

毎年ながら、このネタの説明の時には、図を書き間違え、トッチらかった説明をしてしまう。反省。

双方向リスト

エディタのカーソル移動を例にしながら、次のデータ参照と同様に前方データ参照が 必要な事例として紹介する。 そして、このような時に使われるのが、双方向リスト。

struct BDList { // 双方向リストの宣言
int    data ;
struct BDList* prev ;  // 1つ前のデータへのポインタ
struct BDList* next ; // 次のデータへのポインタ
} ;
// 双方向リスト生成の補助関数
struct BDList* bdcons( struct BDList*p ,
int x , struct BDList* n ) {
struct BDList* ans ;
ans = (struct BDList*)malloc( sizeof( struct BDList ) ) ;
if ( ans != NULL ) {
ans->prev = p ;
ans->data = x ;
ans->next = n ;
}
return ans ;
}
void main() {
// リスト生成のサンプル
struct BDList* top ;
top = bdcons( NULL , 1 , NULL ) ;
top->next = bdcons( top , 2 , NULL ) ;
top->next->next = bdcons( top->next , 3 , NULL ) ;
// リスト順次参照のサンプル
struct BDList* p ;
for( p = top ; p != NULL ; p = p->next )
printf( "%d" , p->data ) ;
for( p = top->next->next ; p != NULL ; p = p->prev )
printf( "%d" , p->data ) ;
}
// 指定データの後ろに、データを挿入する処理
void bdinsert( struct BDList* p , int x ) {
struct BDList* n = bdcons( NULL , x , NULL ) ;
if ( n != NULL ) {
n->prev = p ;       // (1)
n->next = p->next ; // (2)
p->next->prev = p ; // (3)
p->next = n ;       // (4)
}
}

これらの説明の後、循環双方向リストを解説する。

Robot Watch の記事に歯みがきロボコンの記載

先日、個人的に子供を連れて富山ロボットフェスティバルに行ってきた。 そこで歯みがきロボコンの出展をしていたのであるが、 Impress の Robot Watch の記事のロボットフェスティバルの記事で、 歯みがきロボコンのネタも記載されていた。

『会場内で一際異彩を放っていたのが「歯みがきロボコン」の体験ブースだ。 これは福井県歯科医師会が主催しているロボコンで…』という説明にて 紹介されている。 ひとまず、全国的なRobot Watch にてほんの一部とはいえ、 紹介されてちょっとうれしいのであった….
# へへっ、画像処理のロボットも1枚だけ写真が掲載…

機械工業会自律ロボット講習会

さすが機械加工が、お得意の方々の製作途中の車体。 私達ではこういう加工ができない…

0909291950_240x320.jpg

JABEE受審説明会

本校は、5年前にJABEEを受審し認定され、 途中で中間審査を経て、 今年は再び新規審査となる。

そして、夏の間に審査書類を提出し、10/25,26,27の3日間には実地審査が行われる。 これに合わせて、受審にあたっての説明会が開催された。 JABEEの趣旨の再確認のあと、JABEE委員の方により本校の受審プログラムの、 前回受審時からの改善点とその内容の説明をうける。 以前、JABEE委員をしていたので準備の大変さを理解しているからこそ、 その大量の情報を必要最小限にまとめて説明され、 改めて現在のJABEE委員の先生に『ご苦労様』と言いたい。

2009-後期-時間割

2009年後期の時間割。画像ファイルにして携帯に送っておくと、いつでも確認できるので、作ったファイルだけど、保護者の方で知りたい人もいるだろうから、日記にも掲載しておく。

0909290925_318x340.GIF0909290925_320x339.GIF

ファイル名は「左から右に読む」とは限らない?!

学生さんと話していると、相変わらず何人かの人が、 「ウィルス対策ソフトは重いから使っていない」 ということを平気で言う人がいる。 これに記載されている方式[※]は、ある意味序の口なんだけど、 こういうテクニックがあることさえも知らないんだったら、 「自分はパソコンに詳しいから、ウィルスにはひっかかりませんよ!」 ということは、決して言ってはならない….

[※] : アラビア文字などを代表とする文字は、右から左に文字を書いていく。 こういう文字を正しく表示するための、 Right-to-Left Override という機能を使ったファイル名偽装のテクニックの紹介記事。

公開講座:初めての簡単プログラミング

簡単なプログラミングを、小学校・中学校の生徒さんにも体験してもらうための、 公開講座が電子情報工学科にて開催されます。

  対象定員: 小学5年生~中学2年生(保護者同伴可) 定員10名
  実施日時: 2009/10/10(Sat) 9:30~16:30
  受 講 料: 無料
   場 所 : 電子情報工学科棟

緊急連絡システムの遅配&イメージ戦略

遅配についての説明

緊急連絡システムについて、小学校からの問い合わせに対応した。 内容は、『メールの発信から1時間ほどの遅配があったことについて保護者の方からの質問』 であった。

丁度、複数校が関係する学校行事の日程変更の連絡で、遅配の影響があったとの内容であった。 もともと、携帯電話での迷惑メール対策で携帯電話会社は、 大量のメールを送ってくるコンピュータを迷惑メールの発信者と疑うため、 一定時間内のメール送信数に制限があることを説明させて頂いた。

福井高専のイメージ戦略

ちょうど、この話と同じく、高専より「イメージアップ戦略」のために、 緊急連絡システムの末尾につけていた、『** supported by 福井高専』の文字を、 もう少し分かりやすくしようとの提案であった。 個人的には、めざといPR表示というのは性格的に合わないので、消したいところではあるが、 少子化で学校PRも重要な業務ということで、 『** 本システムは福井高専により運営されています』との表示に変更を行った。

技術相談:プログラムの日本語化

共同研究などでお世話になったことのある企業から、 技術相談としてとあるソフトウェアの日本語化について質問をうける。

よくできたソフトであれば、多言語化のための設定ファイルを書き加えるだけだろうが、 そうでなければ2byteコードなどの取り扱いが手間といった一般的な説明を行った。 実際に、そのソフトの体験版があったので、確認をすると、Delphi にて開発されている ようであった。どちらにしろ大変そう。

その際に協力できそうなアルバイトをできる学生さんについても質問されるが、 最近は Delphi のプログラマーは少ない。 しかし、確認すると1人だけ学生さんに経験者が…ということで、 その際は『バイト紹介します!!』

システム

最新の投稿(電子情報)

アーカイブ

カテゴリー