* 目次 [#sa2da016] #contents *概要 [#v3f94615] どのOSも(WindowsもLinuxも)バイト・ストリームによる -SAM(順次アクセス方式) --シーケンシャル・アクセス - Wikipedia~ http://ja.wikipedia.org/wiki/%E3%82%B7%E3%83%BC%E3%82%B1%E3%83%B3%E3%82%B7%E3%83%A3%E3%83%AB%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9 -DAM(直接アクセス方式) --ランダム・アクセス - Wikipedia~ http://ja.wikipedia.org/wiki/%E3%83%A9%E3%83%B3%E3%83%80%E3%83%A0%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9 程度はサポートしています。 -ファイル編成法 - Wikipedia~ http://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E7%B7%A8%E6%88%90%E6%B3%95 --汎用コンピュータ(メインフレーム)や一部のオフコンの専用OSでは、~ 各ファイル(データセット)内の、レコードの属性を定義する。~ (固定長/可変長/非定型、固定長の場合のレコード長、格納・検索方法など) --なお、いわゆるオープンシステムではバイトストリームが基本であり、~ ファイル編成法は存在しない(詳細は「レガシーシステムとオープンシステムの比較」を参照)。 本ページでは、これらを使用しての、大量データの処理方式を考えます。~ なお、メモリに保持可能なデータ量の場合の設計ディシジョンについては考慮しません。~ この場合、メモリの大量消費による同時実行性の低下が問題となります。 *アクセス方式とレコード長 [#w5371c88] **SAM(順次アクセス方式) - シーケンシャル・アクセス [#l7ad5ca9] -SAM(順次アクセス方式) - シーケンシャル・アクセスを~ 実現するにあたっては、特に問題となる点はありません。~ -READやWRITEのAPIによって自動的に~ ファイル・ポインタ(読み書きの開始点)が移動されます。 **DAM(直接アクセス方式) - ランダム・アクセス [#j7166bdf] DAM(直接アクセス方式) - ランダム・アクセスを実現するにあたっては、~ 特にファイル・ポインタ(読み書きの開始点)の制御が問題となります。 ***固定長 [#p19a0473] 固定長レコードの場合、 -ファイル・ポインタ(読み書きの開始点)の制御が容易です。 -Windowsでは、SetFilePointer関数を使用して、~ ファイル・ポインタ(読み書きの開始点)を、全て自分で制御して~ ランダム・アクセスを実現する必要があります。 --Win32 API でのファイルアクセス~ http://chokuto.ifdef.jp/urawaza/fileaccess.html -注意点 --4GB(32ビット)以上のファイルを扱う時は、~ 上位32ビットと、下位32ビットを64ビットデータ型に変換する必要があることでする。 --このため、レガシーVBではSEEKステートメントで2GB以上の~ ファイル・ポインタを指定することができないという制約があります。~ 4GB(32ビット)でないのは、signedの型を使用しているためと思われます。 ---VBA の 2 GB のファイル制限を超えてを移動する方法~ http://support.microsoft.com/kb/189981/ja --この制約は、Javaにもあるようです。 ---RandomAccessFileで2GB以上 JavaのQ&A【OKWave】~ http://okwave.jp/qa/q7022891.html --.NETでは、FileStream.Seek メソッドの引数が~ 64bit(long型)対応されたため、この問題は発生しなくなったようです。 ---FileStream.Seek メソッド (System.IO)~ http://msdn.microsoft.com/ja-jp/library/system.io.filestream.seek.aspx 余談になりますが、.NETで固定長レコードを処理する場合に便利な~ C構造体によるバッファ型抜きを.NET構造体とMarshalクラスを使用して実現できます。~ -Marshal クラス (System.Runtime.InteropServices)~ http://msdn.microsoft.com/ja-jp/library/system.runtime.interopservices.marshal.aspx なお、このバッファ型抜き処理は、aW棟梁の共通部品に実装されています。 ***可変長 [#a572f3f6] 可変長レコードの場合、 -ファイル・ポインタ(読み書きの開始点)の制御が困難です。 -理由は、簡単でレコード長が可変のためn番目のレコードの~ ファイル・ポインタ(読み書きの開始点)ができないためです。 -対応方法については、いくつか方法が考えられます。 --SAM(順次アクセス方式) - シーケンシャル・アクセスで、~ 事前に、全てのデータを読み取っておき、これにより、~ 全てのレコードの開始位置を配列などに記憶しておく。 ---初回の開始位置の配列作成の読み込みにI/O時間がかかってしまう。 --全てのレコードを読み取ることが困難な場合でも、~ レコード番号などがデータ中に含まれるようなら~ ファイル・ポインタ(読み書きの開始点)を推測して、~ 効率良くレコードにアクセスする事を試みるのは可能。 ---上手いアルゴリズムを考えだすのが難しい。 ---レコード番号などがデータ中に含まれる必要がある~ カスタム仕様であるため、汎用品は存在しない。 -CSVの場合 --可変長レコードの主要なフォーマットにはCSVがあります。 --CSVの問題は、CSVのフォーマットの仕様によってパーサが複雑になる事です。 ---Comma-Separated Values - Wikipedia~ http://ja.wikipedia.org/wiki/Comma-Separated_Values ---CSVファイルフォーマットの解説:CodeZine~ http://codezine.jp/article/detail/2364 --例えば、データ内に改行コードなどが含まれる場合は、~ 前述のファイル・ポインタ(読み書きの開始点)推測して、~ レコードにアクセスする等の方式の採用は困難です。 ---ただし、1フィールドの最大データ長が決まっていれば、可能と言えば可能です。 --このため、以下のどちらの方式を採用したとしても、 ---全てのデータを読み取っておき、全てのレコードの開始位置を配列などに記憶しておく。 ---ファイル・ポインタ(読み書きの開始点)を推測して、効率良くレコードにアクセスする。 ---※ FileStream.Seek、Positionと、StreamReader.ReadLineを併用する。 --結局の所、CSVパーサーの高速化が必要になるようです。 ---巨大なCSV(可変長)を効率よく読込む方法は? C・C++のQ&A【OKWave】~ http://okwave.jp/qa/q4410652.html --.NETには、VB 2005用の機能として、CSVパーサーが準備されているようです。~ しかし、APIの使用からも、ランダム・アクセスはサポートされていないようです。 ---CSVファイルを読み込むには?[2.0のみ、C#、VB] - @IT~ http://www.atmarkit.co.jp/fdotnet/dotnettips/487csvparser/csvparser.html ---TextFieldParser クラス (Microsoft.VisualBasic.FileIO)~ http://msdn.microsoft.com/ja-jp/library/microsoft.visualbasic.fileio.textfieldparser.aspx -その他 --ファイル編成法のないオープンシステムの~ バイト・ストリームのファイルシステムでは~ 可変長レコード・ファイルのレコード更新処理は不可能。 --固定長レコードの処理と同じように、~ C構造体によるバッファ型抜きでの処理することが不可能。 *実装上の考慮点 [#t4dc4474] **更新処理 [#iae27b1e] 固定長レコードの更新処理以外は、 -可変長レコードの更新処理(レコード長が変わる更新) -テキスト・ファイルの中間に文字やパラグラフを挿入する。 -.etc 更新差分情報のみをメモリに保持して、~ 最終的に全てのデータをバイト・ストリームで書き出し直す必要がある。 このため、I/Oのオーバヘッドが非常に大きくなってしまいます。 **MMFの使用ポイント [#m1928f42] メモリマップトファイル(MMF)を使用すれば、 -マップビューのマップ・アンマップによるランダム・アクセス -マップビューの範囲でオンメモリ処理(I/O回数の軽減) が可能になり、効率的に参照処理を~ 実装できるようになる可能性があります。 *余談 [#m510d724] **COBOL+VSAM [#f66b100a] -COBOLなどは、RDBMSが無い時代に、ホスト・UNIXのOSに実装される~ VSAMを内部的に使用して業務アプリケーションを開発することを~ 目的としていたため、この仕組みに適合した言語仕様になっている。 -このため可変長のランダム・アクセスであっても~ 実装が容易で、このような問題は発生しないようです。~ このため、昔は良く「Windowsはファイル・システムが弱い」と言われていました。 -VSAM、VSAMデータセット » 「メインフレーム・コンピュータ」で遊ぼう~ http://www.arteceed.net/?p=3164 -Virtual Storage Access Method - Wikipedia~ http://ja.wikipedia.org/wiki/Virtual_Storage_Access_Method **Unix、LinuxとWindowsのFS [#f4e3f15e] Unix、Linuxのファイルシステムでは断片化が発生し難いと言う話があったので、~ 簡単に技術的な背景を纏めているサイトをリンクしました。 -[[デフラグ>ファイルシステム#y622da50]] *DBを使用する場合 [#c682768a] RDBMS+SQLを使用することによって、~ アプリケーションはデータ・アクセスの際に~ -ファイル編成法(固定長/可変長/非定型、格納・検索方法)と -上記に対応するアクセス方法(APIの利用方法) を考慮せずに、論理データに直接アクセスできるようになりました。 **バッチ処理 [#ad349391] 大量データのバッチ処理は、基本的にストアドが高速です。 -ネットワークやプロセス間の通信処理が発生しないので、~ データ送受信のラウンドトリップが発生しない。 -カーソルによるフェッチが使用できるため~ 大量データの結果セットを取得した場合も~ メモリ消費量を抑えることができる。 Java、.NETで実装する場合は、性能的に~ 問題が無いかを事前に検証した方が良いでしょう。 -[[.NETでバッチは書けるか?]] **検索、結合、統合、集計機能 [#j5c66547] 大量データのバッチ処理で、~ 以下の様なDBMSの機構を使用したいケースもある。 -検索機能(Index Seek) -結合、統合、集計機能(Join、Union、Group By) 検索や結合機構にはインデックスが使用されているため -インデックスの構築・更新 -統計情報更新の構築・更新 等が必要になる。 -[[SQL Server 大量データ処理時の性能問題]] -[[SQL Server のアップグレードと移行]] **オーバーヘッド [#x52afce2] DBを利用可能にするまでのオーバーヘッドには以下のものがあります。 -インポート(インサート) -インデックス構築・更新 -統計情報の構築・更新 -必要であればエクスポート **無償で利用できるDB [#gc3a7f28] -MDB(accdb)、インストール不要で運用も楽。 --MS-Access を使わずに Jet Database Engine~ を使用する方法 YU-TANG's MS-Access Discovery~ http://www.f3.dion.ne.jp/~element/msaccess/AcTipsGnrHowToUseJetWithoutMSAccess.html -SQL Server Express Edition --インストールは必要だが、 --ファイルアクセスによるSQL処理が可能(*.MDF)。 --方法 .MDF ファイルを使用して AdventureWorksLT データベースに接続する~ http://msdn.microsoft.com/ja-jp/library/dd469575.aspx -SQL Server CE~ --インストールは必要だが、 --ファイルアクセスによるSQL処理が可能(*.SDF)。 --極小SQL Server Compactでデータベース・アプリをお手軽作成 - @IT~ http://www.atmarkit.co.jp/fdotnet/joyofprogram/20080701devssce/devssce_02.html -SQLite - Wikipedia~ http://ja.wikipedia.org/wiki/SQLite --パブリック・ドメインのOSS、ADO.NET対応 ---C#-.NET で SQLite を使う基本中のキホン うめつる開発室~ http://blog.ume108.mobi/?p=3378 ---「SQLiteをWindows Mobileで動かそう!!しかも.NETで!!!」 - verus diary~ http://d.hatena.ne.jp/verus/20080221/1203606584 -Oracle XE -その他OSSのDB **補足 [#j7c7a8bb] しかし、バッチ処理等で高性能なデータ変換処理を要求されるケースでは~ 未だにファイル・レベルでのデータ処理が必要になることもあります。 例:データのエクスポート → 変換処理(シーケンシャル) → データのインポート *ETLツールを導入する方式 [#z7fb9026] HULFT DataMagicなどを使用することで~ 可変長レコードの大量データも容易に処理できる可能性があります。 -HULFT-DataMagic 技術コラム Vol.17 【HULFT定義一括登録編】~ 技術コラム一覧 ファイル転送・データ連携 HULFTシリーズ セゾン情報システムズ~ http://www.hulft.com/column/datamagic17.html