データベースの方か迷ったのですが
このジャンルでお願いします。
データベースというものを実際にプログラムで作ることによって理解を深めたいと思いました。
とはいっても、MySQLやPostgresSQLのようにそこまで本格的で膨大なものは作れないですから、
何か作れる範囲でのことでやれたら理想的です。
実際にMySQLのソースを見てみたのですが、やはりほとんど理解できませんでした・・・
トランザクションやらメモリやらそこらへんに対する知識が必要なのかなぁと個人的には思ったのですが、
参考になる書籍やサイトなどあれば何冊でも構わないので教えて頂けないでしょうか?
No.2ベストアンサー
- 回答日時:
>データベースというものを実際にプログラムで作ることによって理解を深めたいと思いました。
データベースの基本は「ファイルの中に、どういう構造でデータが記録されているか」です。
例えば「1レコードが何バイトか」とか「1つのレコードの中に幾つのフィールドがあるか」とか「個々のフィールドのデータ型は何か」とか「特定のフィールドをキーにして検索する際の索引ファイルがどうなっているか」とか。
最も単純な「データベースもどき」のファイルは「C言語の構造体の配列を、そのままバイナリ保存しただけのファイル」です。
構造体配列の要素1個が、データベース内のレコード1個に相当します。
構造体の中のメンバ変数が、レコード内のフィールド1個に相当します。
しかし、構造体配列をそのまま保存しただけでは、レコードの形式が固定されているため、フィールドの追加・削除・変更が出来ません。
また、特定のレコードを編集する時は、そのレコードを探さなければなりませんが、構造体配列をそのまま保存しただけのファイルだと、レコードを探すのに手間取ります。
更に、レコードを追加したり削除したりする時も、構造体配列をそのまま保存しただけのファイルでは不充分です。削除したなら削除で空いた隙間を詰めないと困りますし、配列の要素数を超えるような追加は出来ませんので。
このように「構造体配列をそのまま保存しただけのファイル」に、上記に挙げたような色々な問題点を解決するための「色々な仕掛け」を施したのが「データベースファイル」です。
そして、この「データベースファイル」にアクセスする為のプログラム群(ライブラリ群)も含め「データベース」と呼びます。
「SQL」とか「トランザクション」などは、このデータベースファイルにアクセスする際に「人間が便利にアクセスする為の仕掛け」として用意された物で「データベースを作る」と言う場合は、余り重要ではありません。
ご返答ありがとうございます。
なるほど、なんとなくですが全体的なイメージができたような気がします。
ところで
>「特定のフィールドをキーにして検索する際の索引ファイルがどうなっているか」
これは例えば、「索引ファイル」を用意して
鈴木,7←実際のデータがあるファイルの中の位置
田中,12
中村,18
レコードを追加、削除したときは「索引ファイル」の内容も更新する
というやり方で方向としてはあっているのでしょうか?
No.5
- 回答日時:
問題を出したzwiです。
>まずはこのような感じでいいのでしょうか?
私はC#は詳しくないので、ざっと見た感じですが。
・カラムデータとしてカラム名は欲しかったですかね。
・カラム固定長でも良いのですが、カラム長はカラムデータとして持ってください。
・数値データがありませんが、データ型という概念も欲しいですね。これもカラムデータとして持って下さい。
・将来のカラム数可変を考慮して、カラム数と言うデータは付けておいて欲しいですね。
・今のstructでデータベースのレコード構造を決めてしまうやり方は、汎用データベースの設計としてマズイです。
・ファイルに関してですが、検索のハッシュ情報等もファイルに書き出す必要があります。そういう意味でファイルはバイナリファイルが良いと思うのですが、仕様も固まらないうちからファイルフォーマットを決めてしまうのは辛いかと思います。なので、まずオンメモリだけで必要な機能を検討してください。
>それとC#ではやらない方がいいのでしょうか?
>というのもよくC#は遅い(?)ということを聞きますので。
確かにネイティブなCやC++の方が速いですが、実験的なものであればC#でも問題ないと思います。将来的にフリーウェアとして配布したいとか、Linuxの人にも使って欲しいとか思うのであればC言語で組む事をお勧めします。
有名なデータベースのSqLite3←PHP5で標準採用。
http://ja.wikipedia.org/wiki/SQLite
C言語で作成されていてアプリケーション組み込み型であり、目指しているものに近いかと思います。
public domainなのでソース公開されてますが巨大なのでMySQL同様に資料にするには困難かも。
ご返答ありがとうございます。
仰っていることはなんとなくイメージできてはいるのですが、
いくつか調べながら(そもそも言語の基本的なことすら理解できてないですから・・)やっているので、なにかと時間がかかりそうです。
SqLite3の方も参考にしていきたいと思います。
No.4
- 回答日時:
対抗するわけではないのですが
まずは、固定長テキストを扱うテキストデータベースがいいと思います。
もちろん、テキストも
カマン区切りとかじゃなくて、固定長(列セパレータと改行なし)がよいです。
# こんな感じです
# 鈴木 7田中12中村18
それで、検索・追加・更新・削除をレコード単位に処理できるものを
作成してみるといいんじゃないかなぁ。
この場合、ファイルを取り扱うので当然ながら、
ACID を意識する必要があります。
まぁ、最初から、実装はしなくてもいいと思いますけどね。
ACIDについては、データベースに限った話ではないので
ノウハウを知っておいて損はないはずです。
そして最後に、余裕があれば、索引ファイルをつくって参照して、
効率のいい検索を実現してみるとか?
ご返答ありがとうございます。
なるほど、ACIDですか。
ちょっとネットで調べてみたのですが、
これもなんか本格的に実装するとなると大変そうですね・・・
>固定長(列セパレータと改行なし)がよいです。
参考になりました。ありがとうございます。
No.3
- 回答日時:
>これは例えば、「索引ファイル」を用意して
>鈴木,7←実際のデータがあるファイルの中の位置
>田中,12
>中村,18
>レコードを追加、削除したときは「索引ファイル」の内容も更新する
というやり方で方向としてはあっているのでしょうか?
これだどカラムの数だけ索引ファイルを用意しますか?って事になります。レコードのカラムと同じデータが索引ファイルに入っているのも無駄です。
理解のレベルから考えて、いきなり高度なデータベースは設計段階で挫折します。
とりあえず、ファイルを使わないメモリ常駐のデータベースを作ってみましょう。仕様は、こんな感じで。
(1)データベースはセーブとロード時だけファイルアクセスする形にします。メモリの情報をファイルに格納できる形にしてセーブ。同様に復元してロードします。全てのデータを出来れば1つのファイルにまとめます。最初のバージョンはセーブロードできなくても良いです。
(2)データはリスト構造などでメモリ上に置きます(ただの配列だと追加・削除が遅すぎます)。
(3)カラム追加・削除は最初は実装しなくてよいです。
(4)最初に必要な機能は、データの追加・検索・更新・削除です。
(5)検索は最初は単純でよいですが、どんどん高度な検索に変えて行きます(ツリー構造やハッシュなど)。
どうでしょう?
この回答への補足
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);
}
}
ご返答ありがとうございます。
なるほど、このように整理していただけると助かります。
C++はあまり(ほとんど)理解していないので
一応C#(こちらもそんなにです)で試してみたのですが、
※補足を参照してください
まずはこのような感じでいいのでしょうか?
それとC#ではやらない方がいいのでしょうか?
というのもよくC#は遅い(?)ということを聞きますので。
No.1
- 回答日時:
まずはじめに、本格的なものがいらないならトランザクションは不要では?
で、それはそれとして一般的に使われているデータベースはリレーショナルデータベースと呼ばれるもので表形式でデータを持ちます。
wikipedia 関係(リレーショナル)データベース
http://ja.wikipedia.org/wiki/%E9%96%A2%E4%BF%82% …
ここを手がかりにいろいろ検索してみてください。
それと、SQLは必須じゃないので実装しなくてもよいと思います。
ご返答ありがとうございます。
>本格的なものがいらないならトランザクションは不要では?
そうだとは思うのですが、自分としては本格的じゃないとはいっても
一通り一般にあるようなデータベースの機能を真似したいとは思ってるのですが、
でもそうなると(たぶん)膨大な量のプログラムになりそうなので、
どこから理解してどこから手をつければいいか迷ってるところです・・・
リレーショナルデータベースについては、
MySQL、PostgresSQLとPHPの方で利用して少しだけ扱ったことがある程度の理解です。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- MySQL 【投稿情報用データベース posts】は必要ないと思います。 1 2022/06/02 21:25
- MySQL [1000地域 × 10カテゴリー = 1万件のテーブル]!グループ化? 1 2023/06/14 23:56
- フリーソフト 色々な形式の個人情報を後で参照しやすいようWindow10で管理したいのですが、どんな方法があるの? 1 2023/04/29 16:46
- MySQL mysqlがインストールされているのかどうか 1 2023/06/05 14:19
- MySQL mysqlがインストールされているのかわかりません 1 2023/06/05 02:26
- その他(データベース) 業務用のデータベースサーバーの選び方について 4 2022/11/22 10:22
- MySQL PHPとMySQLを使った掲示板の作り方 1 2022/06/02 13:00
- MySQL 「utf8mb4_general_ci」はMAMPでは何に当たりますか? 1 2022/06/02 07:45
- MySQL MySQLでcreateが使えない MySQLを使ってデータベースを作ろうと思い、CREATE を使 3 2022/06/19 15:32
- JavaScript Q&Aの掲示板を作成していてヤフー知恵袋やgoo質問のように質問ごとにURLを生成したい 5 2023/08/04 01:22
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
【Excel】[Expression.Error] ...
-
共有フォルダに誰が何にアクセ...
-
Batch: フォルダ内の特定のファ...
-
特定のエクセルファイルを起動...
-
Access VBA を利用して、フォル...
-
VBAでCSVファイルが使用中かど...
-
(Excelマクロ)datファイルをエ...
-
月が変わったら自動でシートが...
-
相手のPCにVBAからメッセ...
-
tmpファイル なぜできる?削除...
-
Excel VBA 処理後データが重た...
-
【アクセス】「ほかのユーザー...
-
社内Excel共有ブックでの保存ト...
-
Dream weaverで、誤ってファイ...
-
httpの画像urlが作りたいんです...
-
特定のフォルダに入れたファイ...
-
ACCESSのDoCmd.TransferText
-
テキストファイルからデータを...
-
HTMLとデータベースの連携
-
大量のCSVデータを行列の変換を...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
共有フォルダに誰が何にアクセ...
-
【Excel】[Expression.Error] ...
-
特定のエクセルファイルを起動...
-
Batch: フォルダ内の特定のファ...
-
VBAでCSVファイルが使用中かど...
-
月が変わったら自動でシートが...
-
AccessVBAで作成したExcelファ...
-
tmpファイル なぜできる?削除...
-
Access VBA を利用して、フォル...
-
(Excelマクロ)datファイルをエ...
-
事務の派遣で働いています。多...
-
Excel VBA 処理後データが重た...
-
excelを共有ファイルにすると行...
-
【アクセス】「ほかのユーザー...
-
XMLデータを変換し印刷する方法
-
CSVの項目行を削除して一つのフ...
-
mdbファイル フォームを開くと...
-
社内Excel共有ブックでの保存ト...
-
ファイルの途中に文字列を挿入
-
拡張子が「cda」のファイルを聞...
おすすめ情報