- ベストアンサー
データベースを作るために必要な知識
データベースの方か迷ったのですが このジャンルでお願いします。 データベースというものを実際にプログラムで作ることによって理解を深めたいと思いました。 とはいっても、MySQLやPostgresSQLのようにそこまで本格的で膨大なものは作れないですから、 何か作れる範囲でのことでやれたら理想的です。 実際にMySQLのソースを見てみたのですが、やはりほとんど理解できませんでした・・・ トランザクションやらメモリやらそこらへんに対する知識が必要なのかなぁと個人的には思ったのですが、 参考になる書籍やサイトなどあれば何冊でも構わないので教えて頂けないでしょうか?
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
>データベースというものを実際にプログラムで作ることによって理解を深めたいと思いました。 データベースの基本は「ファイルの中に、どういう構造でデータが記録されているか」です。 例えば「1レコードが何バイトか」とか「1つのレコードの中に幾つのフィールドがあるか」とか「個々のフィールドのデータ型は何か」とか「特定のフィールドをキーにして検索する際の索引ファイルがどうなっているか」とか。 最も単純な「データベースもどき」のファイルは「C言語の構造体の配列を、そのままバイナリ保存しただけのファイル」です。 構造体配列の要素1個が、データベース内のレコード1個に相当します。 構造体の中のメンバ変数が、レコード内のフィールド1個に相当します。 しかし、構造体配列をそのまま保存しただけでは、レコードの形式が固定されているため、フィールドの追加・削除・変更が出来ません。 また、特定のレコードを編集する時は、そのレコードを探さなければなりませんが、構造体配列をそのまま保存しただけのファイルだと、レコードを探すのに手間取ります。 更に、レコードを追加したり削除したりする時も、構造体配列をそのまま保存しただけのファイルでは不充分です。削除したなら削除で空いた隙間を詰めないと困りますし、配列の要素数を超えるような追加は出来ませんので。 このように「構造体配列をそのまま保存しただけのファイル」に、上記に挙げたような色々な問題点を解決するための「色々な仕掛け」を施したのが「データベースファイル」です。 そして、この「データベースファイル」にアクセスする為のプログラム群(ライブラリ群)も含め「データベース」と呼びます。 「SQL」とか「トランザクション」などは、このデータベースファイルにアクセスする際に「人間が便利にアクセスする為の仕掛け」として用意された物で「データベースを作る」と言う場合は、余り重要ではありません。
その他の回答 (4)
- zwi
- ベストアンサー率56% (730/1282)
問題を出したzwiです。 >まずはこのような感じでいいのでしょうか? 私はC#は詳しくないので、ざっと見た感じですが。 ・カラムデータとしてカラム名は欲しかったですかね。 ・カラム固定長でも良いのですが、カラム長はカラムデータとして持ってください。 ・数値データがありませんが、データ型という概念も欲しいですね。これもカラムデータとして持って下さい。 ・将来のカラム数可変を考慮して、カラム数と言うデータは付けておいて欲しいですね。 ・今のstructでデータベースのレコード構造を決めてしまうやり方は、汎用データベースの設計としてマズイです。 ・ファイルに関してですが、検索のハッシュ情報等もファイルに書き出す必要があります。そういう意味でファイルはバイナリファイルが良いと思うのですが、仕様も固まらないうちからファイルフォーマットを決めてしまうのは辛いかと思います。なので、まずオンメモリだけで必要な機能を検討してください。 >それとC#ではやらない方がいいのでしょうか? >というのもよくC#は遅い(?)ということを聞きますので。 確かにネイティブなCやC++の方が速いですが、実験的なものであればC#でも問題ないと思います。将来的にフリーウェアとして配布したいとか、Linuxの人にも使って欲しいとか思うのであればC言語で組む事をお勧めします。 有名なデータベースのSqLite3←PHP5で標準採用。 http://ja.wikipedia.org/wiki/SQLite C言語で作成されていてアプリケーション組み込み型であり、目指しているものに近いかと思います。 public domainなのでソース公開されてますが巨大なのでMySQL同様に資料にするには困難かも。
お礼
ご返答ありがとうございます。 仰っていることはなんとなくイメージできてはいるのですが、 いくつか調べながら(そもそも言語の基本的なことすら理解できてないですから・・)やっているので、なにかと時間がかかりそうです。 SqLite3の方も参考にしていきたいと思います。
- tsuduki999
- ベストアンサー率35% (6/17)
対抗するわけではないのですが まずは、固定長テキストを扱うテキストデータベースがいいと思います。 もちろん、テキストも カマン区切りとかじゃなくて、固定長(列セパレータと改行なし)がよいです。 # こんな感じです # 鈴木 7田中12中村18 それで、検索・追加・更新・削除をレコード単位に処理できるものを 作成してみるといいんじゃないかなぁ。 この場合、ファイルを取り扱うので当然ながら、 ACID を意識する必要があります。 まぁ、最初から、実装はしなくてもいいと思いますけどね。 ACIDについては、データベースに限った話ではないので ノウハウを知っておいて損はないはずです。 そして最後に、余裕があれば、索引ファイルをつくって参照して、 効率のいい検索を実現してみるとか?
お礼
ご返答ありがとうございます。 なるほど、ACIDですか。 ちょっとネットで調べてみたのですが、 これもなんか本格的に実装するとなると大変そうですね・・・ >固定長(列セパレータと改行なし)がよいです。 参考になりました。ありがとうございます。
- zwi
- ベストアンサー率56% (730/1282)
>これは例えば、「索引ファイル」を用意して >鈴木,7←実際のデータがあるファイルの中の位置 >田中,12 >中村,18 >レコードを追加、削除したときは「索引ファイル」の内容も更新する というやり方で方向としてはあっているのでしょうか? これだどカラムの数だけ索引ファイルを用意しますか?って事になります。レコードのカラムと同じデータが索引ファイルに入っているのも無駄です。 理解のレベルから考えて、いきなり高度なデータベースは設計段階で挫折します。 とりあえず、ファイルを使わないメモリ常駐のデータベースを作ってみましょう。仕様は、こんな感じで。 (1)データベースはセーブとロード時だけファイルアクセスする形にします。メモリの情報をファイルに格納できる形にしてセーブ。同様に復元してロードします。全てのデータを出来れば1つのファイルにまとめます。最初のバージョンはセーブロードできなくても良いです。 (2)データはリスト構造などでメモリ上に置きます(ただの配列だと追加・削除が遅すぎます)。 (3)カラム追加・削除は最初は実装しなくてよいです。 (4)最初に必要な機能は、データの追加・検索・更新・削除です。 (5)検索は最初は単純でよいですが、どんどん高度な検索に変えて行きます(ツリー構造やハッシュなど)。 どうでしょう?
お礼
ご返答ありがとうございます。 なるほど、このように整理していただけると助かります。 C++はあまり(ほとんど)理解していないので 一応C#(こちらもそんなにです)で試してみたのですが、 ※補足を参照してください まずはこのような感じでいいのでしょうか? それとC#ではやらない方がいいのでしょうか? というのもよくC#は遅い(?)ということを聞きますので。
補足
class Program { struct Person { public string name; public int age; }; static void Main(string[] args) { List<Person> list = new List<Person>(); string fileName = "data.txt"; list = Load(fileName);//←データの読み込み //list.Add(new Person { name = "鈴木", age = 20 });//←データの追加 //list.Add(new Person { name = "三田村", age = 100 });//←データの追加 //list.Add(new Person { name = "田中", age = 25 });//←データの追加 //list.RemoveAt(1);//←データの削除 list[0] = new Person { name = "鈴木", age = 21 };//←データの更新 //TreeStructureSearch(list);//←データの検索 //HashSearch(list);//←データの検索 //Save(fileName, list);←データの保存 foreach (Person p in list) { Console.WriteLine("名前:" + p.name + " 年齢:"+ p.age); } Console.ReadLine(); } static void TreeStructureSearch(List<Person> list) { } static void HashSearch(List<Person> list) { } static List<Person> Load(string fileName) { List<Person> list = new List<Person>(); using (StreamReader r = new StreamReader(fileName)) { string line = r.ReadLine(); int recordLength = 7; for (int i = 0; i < line.Length; i += recordLength) { string row = line.Substring(i, recordLength); string name = row.Substring(0, 4); int age = int.Parse(row.Substring(4, 3)); list.Add(new Person { name = name, age = age }); } } return list; } static void Save(string fileName, List<Person> list) { string contents = ""; foreach (Person p in list) { contents += String.Format("{0,-4}", p.name) + String.Format("{0,-3}", p.age); } File.WriteAllText(fileName, contents); } }
- zwi
- ベストアンサー率56% (730/1282)
まずはじめに、本格的なものがいらないならトランザクションは不要では? で、それはそれとして一般的に使われているデータベースはリレーショナルデータベースと呼ばれるもので表形式でデータを持ちます。 wikipedia 関係(リレーショナル)データベース http://ja.wikipedia.org/wiki/%E9%96%A2%E4%BF%82%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9 ここを手がかりにいろいろ検索してみてください。 それと、SQLは必須じゃないので実装しなくてもよいと思います。
お礼
ご返答ありがとうございます。 >本格的なものがいらないならトランザクションは不要では? そうだとは思うのですが、自分としては本格的じゃないとはいっても 一通り一般にあるようなデータベースの機能を真似したいとは思ってるのですが、 でもそうなると(たぶん)膨大な量のプログラムになりそうなので、 どこから理解してどこから手をつければいいか迷ってるところです・・・ リレーショナルデータベースについては、 MySQL、PostgresSQLとPHPの方で利用して少しだけ扱ったことがある程度の理解です。
お礼
ご返答ありがとうございます。 なるほど、なんとなくですが全体的なイメージができたような気がします。 ところで >「特定のフィールドをキーにして検索する際の索引ファイルがどうなっているか」 これは例えば、「索引ファイル」を用意して 鈴木,7←実際のデータがあるファイルの中の位置 田中,12 中村,18 レコードを追加、削除したときは「索引ファイル」の内容も更新する というやり方で方向としてはあっているのでしょうか?