データベースとSQLに関する私の知識は、ほとんど大学のクラスに基づいています。とにかく、私はデータベースで作業していた会社で数ヶ月(ほぼ1年)過ごしました。
私は数冊の本を読んでいると私は、次のようなデータベースに関するいくつかの研修に参加したMySQL
、PostgreSQL
、SQLite
、Oracle
ともいくつかnonSQL
db
のように、私たちMongoDB
、Redis
、ElasticSearch
など
私が言ったように、私は初心者であり、多くの知識が不足していますが、今日、誰かが私の初心者の知識に完全に反することを話しました。
説明させてください。SQLデータベースを使用Person
して、内部にレコードがほとんどない単純なテーブルを作成しましょう。
id | name | age
-----------------
1 | Alex | 24
2 | Brad | 34
3 | Chris | 29
4 | David | 28
5 | Eric | 18
6 | Fred | 42
7 | Greg | 65
8 | Hubert | 53
9 | Irvin | 17
10 | John | 19
11 | Karl | 23
今、それは私が焦点を当てたい部分です- id
ですINDEX
。
これまでのところ、私はそれがこのように機能すると思った:テーブルが作成されているときINDEX
は空です。テーブルに新しいレコードを追加するINDEX
と、いくつかのアルゴリズムに基づいて再計算されます。例えば:
1つずつグループ化する:
1 ... N
N+1 ... 2N
...
XN+1 ... (X+1)N
だから、私の例ではsize = 11 elements
、次のN = 3
ようになります:
id | name | age
-----------------
1 | Alex | 24 // group0
2 | Brad | 34 // group0
3 | Chris | 29 // group0
4 | David | 28 // group1
5 | Eric | 18 // group1
6 | Fred | 42 // group1
7 | Greg | 65 // group2
8 | Hubert | 53 // group2
9 | Irvin | 17 // group2
10 | John | 19 // group3
11 | Karl | 23 // group3
したがって、クエリを使用しているときSELECT * FROM Person WHERE id = 8
は、いくつかの簡単な計算が行わ8 / 3 = 2
れるため、このオブジェクトを検索する必要がgroup2
あり、この行が返されます。
8 | Hubert | 53
このアプローチは時間内O(k)
に機能しk << size
ます。もちろん、グループで行を整理するアルゴリズムは確かにはるかに複雑ですが、この単純な例は私の視点を示していると思います。
それで、今日、私に示された別のアプローチを提示したいと思います。
もう一度この表を見てみましょう。
id | name | age
-----------------
1 | Alex | 24
2 | Brad | 34
3 | Chris | 29
4 | David | 28
5 | Eric | 18
6 | Fred | 42
7 | Greg | 65
8 | Hubert | 53
9 | Irvin | 17
10 | John | 19
11 | Karl | 23
現在、このidの行にHashmap
マップid
する(実際には、それはハッシュマップです)に似たものを作成していますaddress
。まあ言ってみれば:
id | addr
---------
1 | @0001
2 | @0010
3 | @0011
4 | @0100
5 | @0101
6 | @0110
7 | @0111
8 | @1000
9 | @1001
10 | @1010
11 | @1011
だから今、私が自分のクエリを実行しているとき: SELECT * FROM Person WHERE id = 8
id = 8
メモリ内のアドレスに直接マップされ、行が返されます。もちろん、これの複雑さはですO(1)
。
だから今、私はいくつかの質問があります。
1.両方のソリューションの欠点と欠点は何ですか?
2.現在のデータベースの実装で人気があるのはどれですか?たぶん異なるDBは異なるアプローチを使用していますか?
3.非SQLデータベースに存在しますか?
前もって感謝します
比較
| B-tree | Hash Table
----------------------------------------------------
---------------- one element -------------------
----------------------------------------------------
SEARCHING | O(log(N)) | O(1) -> O(N)
DELETING | O(log(N)) | O(1) -> O(N)
INSERTING | O(log(N)) | O(1) -> O(N)
SPACE | O(N) | O(N)
----------------------------------------------------
---------------- k elements -------------------
----------------------------------------------------
SEARCHING | k + O(log(N)) | k * O(1) -> k * O(N)
DELETING | k + O(log(N)) | k * O(1) -> k * O(N)
INSERTING | k + O(log(N)) | k * O(1) -> k * O(N)
SPACE | O(N) | O(N)
N-レコード数
私は正しいですか?各挿入/削除後にBツリーとハッシュテーブルを再構築するコストはどうですか?Bツリーの場合、いくつかのポインターを変更する必要がありますが、バランスの取れたBツリーの場合は、より多くの努力が必要です。また、ハッシュテーブルの場合、特に操作で競合が発生する場合は、ほとんど操作を行う必要がありません。
Of course, an alghoritm to organise rows in groups is for sure much more complicated but I think this simple example shows my point of view.
もちろん、それははるかにはるかに複雑であることを知っています。だから最後に、コードINDEX
で私のソリューション(1stまたは2nd)のどれがこの実際のソリューションに近いと言っていますか?そして、に基づいてレコードにアクセスするのに必要な時間はどうでしょうかINDEX
。本当にO(1)
?Bツリーインデックスを使用すると、のように聞こえますO(log2(N))
。私は正しいですか?
O(1)
あなたについての部分はそれを正しくしました!最初の方法では、Bツリーインデックスを記述しているように見えますが、誤解があります。何の計算(3除算か何か)がありませんツリーは、より多くのレベル(それは木だ、それは大きな、小さな、小さな枝を持っている、...、その後、葉:)があるとして、それはより複雑だ