インデックスは木によって実現されている、あなたは知っていますか?

オリジナルリンク: http://www.justdojava.com/2019/08/13/java-Index/

インタビューの中で私たちは今日、友人がインデックスについて多くの質問をし、単語のインデックスは、我々ははるかに開発で最も一般的であったものですが、また、コードの最適化中の時間の多くは一つのことを行います前に、それは、インデックスについて何かすることをインタビューで語りました。

指数

インデックスとは何ですか?

インデックス用語は、実際にデータベース、リレーショナルデータベースであり、インデックスは、データベーステーブルの別個の物性値は表または複数で規則構造を格納する1つ以上の列になりますです論理データ・ページ・ポインタ・リストと物理的識別のテーブル列の値の対応するセットポイント値。インデックスの役割は書籍カタログに相当し、あなたはすぐにあなたがディレクトリページに基づいて必要なものを見つけることができます。

インデックスは、テーブルの指定した列に格納されたデータ値を指すポインタを提供し、その後、これらのポインタご指定のソート順を並べ替えます。特定の値を見つけるためにインデックスを使用してデータベースは、次に時計回りの値を含む行を見つけます。これは、SQL文のテーブルに対応するデータベーステーブル内の特定の情報をより速く、迅速なアクセスを実行します。

しかし、インタビューでは、一般的にインデックスが何であるかを尋ねていないのだろうか?しかし、お願いしたいと、なぜインデックスを使用して移動し、その底部には、達成するためにどのように?そのデータベースとどのようにそれをする必要があり、最適化するには?ここでは、インタビューの中で、これらの情報ポイントにこれらの三つの側面を説明します。

インデックス基本となる実装

一般的に、インデックスBツリーとB +木の品種を達成するために使用されます。

Bツリーデータ構造は、最も一般的に索引付けに使用されます。彼らは低い時間が複雑、検索、削除されているので、挿入操作は、数時間以内に完了することができます。Bツリーに格納されているさらに重要な原因のデータが順序付けられています。

インデックスは通常、ハッシュインデックスと呼ばれている - ハッシュテーブルを使用すると、データ構造を指標として使用されて表示される場合があります別です。ハッシュインデックスを使用する理由は、効率のハッシュテーブルの検索では非常に高いです。だから、あなたは、ハッシュインデックスを使用している場合、クエリ文字列に等しい猛烈取得した値を比較することができるかどうか。

一例として、GoogleのインデックスMySQLデータベース。

今すぐ実現インデックスはBツリーとB +木の品種を介して行われています、そして、私たちは何をBツリーとB +ツリーを言います。

Bツリー

私たちは、マップを見てください。図に示すマルチフォーク、Bツリーは、実際にはm個のフォーク(M> = 2)まで開くことができるバランスの取れた検索ツリー、である、私たちは、私はあなたに引き分けより少しあげる、m次のBツリーを呼び出します内容は、これは、レコードの自分の経験のいくつかのビデオを見て、私の特別な時間です。

 

実際には、人物画は比較的簡単ですが、私たちは三次を描く場合は、この時点では、このようにすることができます

 

それは3つのフォークまで開くことができるが、ほとんどのカウントをフォークするために、2本のフォークがあるかもしれません。

m次のBツリーは、以下の条件を満足します

  • 各ノードは、m個のサブツリーまで持つことができます。
  • ルートのみ少なくとも二つのノードを有するように(ルートのツリーのいずれかの極端な、単細胞生物は、それがルートであるだけでなく、葉だけでなく、木)。
  • 非ルート非リーフノードCEILの少なくとも一部(M / 2)のサブツリー(CEIL図面三次Bツリーを切り上げ、各ノードは、少なくとも二つのサブツリー、すなわち少なくとも二つのフォークを有することを示します)。
  • 非リーフノードの情報を含む[N、A0、K1、A1、K2、A2、...、Knと、アン] ,, nはノードに格納されたキーワードの数を表し、Kはキーワードであり、およびKi <Kiを+ 1、A子を指すルートノードポインタです。
  • 葉へのルートから各パス同じ長さを有し、それは、同一層内のリーフノードであり、無情報を有するノード、それは実際にはこれらのノードは、指定された値を見つけることができないことを意味し、すなわち、ポイントノードポインタがヌルです。

非常に類似したプロセスBツリークエリとバイナリソートツリーは、各ノードのキーとして、各ノードにルートノードから順に比較し、左と右のサブツリーが順序付けされているので、長い比較ノードのキーとして、またはそれが失敗した場合はすぐにポインターに沿って指定されたキーワードを見つけることができるようになります、それはそれはNULLポインタで、リーフノードを返します。

シンプルな疑似木探索アルゴリズムB次のように:

1
2
3
4
5
6
7
8
9
10
11
12
BTree_Search(node, key) {
    if(node == null) return null;
    foreach(node.key)
    {
        if(node.key[i] == key) return node.data[i];
            if(node.key[i] > key) return BTree_Search(point[i]->node);
    }
    return BTree_Search(point[i+1]->node);
}

data = BTree_Search(root, my_key);

各ノードに対して、主キー配列のキー、[]、ポインタの配列(ポインティング息子)息子[]を含みます。Bツリーでは、プロセスは、探している:[]キーKが発見された配列、ノードアドレスと、キーKに戻されるキーを検索することがシーケンシャルサーチ(配列の長さが短い)、又は二分探索法を用いて、[]位置に、そうでなければ、それは鍵Kキー[I]中との間で決定することができる[I + 1]、息子から[i]は、子ノードを参照して検索が接合点で成功するまで検索を続けます。あなたは遺跡が成功を見つけるためにリーフノードとリーフノードを見つけるまで、または、検出プロセスは失敗します。

关于B-Tree有一系列有趣的性质,例如一个度为d的B-Tree,设其索引N个key,则其树高h的上限为logd((N+1)/2)logd((N+1)/2),检索一个key,其查找节点个数的渐进复杂度为O(logdN)O(logdN)。从这点可以看出,B-Tree是一个非常有效率的索引数据结构。

B+树

B-Tree有许多变种,其中最常见的是B+Tree,例如MySQL就普遍使用B+Tree实现其索引结构。

B+ 树是一种树数据结构,是一个n叉树,每个节点通常有多个孩子,一颗B+树包含根节点、内部节点和叶子节点。根节点可能是一个叶子节点,也可能是一个包含两个或两个以上孩子节点的节点。

B+ 树通常用于数据库和操作系统的文件系统中。

NTFS, ReiserFS, NSS, XFS, JFS, ReFS 和BFS等文件系统都在使用B+树作为元数据索引。

B+ 树的特点是能够保持数据稳定有序,其插入与修改拥有较稳定的对数时间复杂度。

B+ 树元素自底向上插入。

 

看节点之间有重复元素,而且在叶子节点上还用指针连接在了一起,而这些就是B+树的几个特点

  1. 每个父节点的元素都出现在了子节点中,分别是子节点最大或者最小的元素。

  2. 在上面的这一棵树中,根节点元素8是子节点258的最大的元素,根元素15也是。这时候要注意了,根节点最大的元素等同于整个B+树的最大的元素,以后无论是怎么插入或者是删除,始终都要保持最大的元素在根节点中。

  3. 叶子节点,因为父节点的元素都出现在了子节点当中,因此所有的叶子节点包含了全量的元素信息。

那么既然B+树是B树的的一种变形树,那么差异点在哪呢?

B+树与B树差异

有k个子节点的节点必然有k个元素

非叶子节点仅具有索引作用,跟记录有关的信息均存放在叶子节点中

树的所有叶子节点构成一个有序链表,可以按照元素排序的次序遍历全部记录

B树和B+树的区别在于,B+树的非叶子节点只包含导航信息,不包含实际的值,所有的叶子节点和相连的节点使用链表相连,便于区间查找和遍历。

B+树的优点

由于B+树在内部节点上不包含数据信息,因此在内存页中能够存放更多的key。 数据存放的更加紧密,具有更好的空间局部性。因此访问叶子节点上关联的数据也具有更好的缓存命中率。

B+树的叶子节点都是相连的,因此只要遍历叶子节点就可以实现整颗树的遍历。而且由于数据顺序排列并且相连,所以便于区间查找和搜索。而B树则需要进行每一层的递归遍历,相邻的元素可能在内存中不相邻,所以缓存命中性没有B+树好。

B+树的缺点

但是B树也有优点,其优点在于,由于B树的每一个节点都包含key和value,因此经常访问的元素可能离根节点更近,因此访问也更迅速。

因为B+树比B树的读写代价更低,所以B+树比B树更适合操作系统的文件索引和数据库索引。

那么既然基层实现我们理解完了,是不是该说一下这个数据库索引分类了呢?

数据库索引分类

根据数据库的功能,可以在数据库设计器中创建四种索引:普通索引、唯一索引、主键索引和聚集索引。

普通索引

最基本的索引类型,没有唯一性之类的限制。普通索引可以通过以下几种方式创建:创建索引,例如 CREATE INDEX <索引的名字> ON tablename (列的列表)

修改表,例如 ` ALTER TABLE tablename ADD INDEX [索引的名字] (列的列表)` ;

创建表的时候指定索引,例如 CREATE TABLE tablename ( [...], INDEX [索引的名字] (列的列表) ) 

唯一索引

唯一索引是不允许其中任何两行具有相同索引值的索引。

当现有数据中存在重复的键值时,大多数数据库不允许将新创建的唯一索引与表一起保存。数据库还可能防止添加将在表中创建重复键值的新数据。例如,如果在 employee 表中职员的姓 (lname) 上创建了唯一索引,则任何两个员工都不能同姓。

对某个列建立UNIQUE索引后,插入新记录时,数据库管理系统会自动检查新纪录在该列上是否取了重复值,在CREATE TABLE 命令中的UNIQE约束将隐式创建UNIQUE索引。 创建唯一索引的几种方式:

创建索引,例如 CREATE UNIQUE INDEX <索引的名字> ON tablename (列的列表) ;

修改表,例如 ALTER TABLE tablename ADD UNIQUE [索引的名字] (列的列表) ;

创建表的时候指定索引,例如 ` CREATE TABLE tablename ( […], UNIQUE [索引的名字] (列的列表) ) ` ;

主键索引

简称为主索引,数据库表中一列或列组合(字段)的值唯一标识表中的每一行。该列称为表的主键。在数据库关系图中为表定义主键将自动创建主键索引,主键索引是唯一索引的特定类型。该索引要求主键中的每个值都唯一。当在查询中使用主键索引时,它还允许对数据的快速访问。提示尽管唯一索引有助于定位信息,但为获得最佳性能结果,建议改用主键索引。

聚集索引

也称为聚簇索引,在聚集索引中,表中行的物理顺序与键值的逻辑(索引)顺序相同。一个表只能包含一个聚集索引, 即如果存在聚集索引,就不能再指定CLUSTERED 关键字。

索引不是聚集索引,则表中行的物理顺序与键值的逻辑顺序不匹配。与非聚集索引相比,聚集索引通常提供更快的数据访问速度。聚集索引更适用于对很少对基表进行增删改操作的情况。

如果在表中创建了主键约束,SQL Server将自动为其产生唯一性约束。在创建主键约束时,指定了CLUSTERED关键字或干脆没有制定该关键字,SQL Sever将会自动为表生成唯一聚集索引。

而如果是面试过程中很多就会问你是索引的分类和怎么使用的,最后我们再来说怎么操作索引。

操作索引

创建索引

SQL3没有提供建立索引的方法。但是,从事DBMS开发、销售的公司都提供他们具有这种功能的SQL工具。因为这些工具不是标准化的,它们相互不同。SQL语言使用CREATE INDEX 语句建立索引,其一般格式是:

1
2
3

CREATE [UNIQUE] [CLUSTERED| NONCLUSTERED] INDEX <索引名> ON <表名>(<列名>[ASC|DESC] [, <列名>[ASC|DESC]...])

说明:与表一样,索引也需要有唯一的名字,且基于一个表来建立,可以根据表中的一列或者多列,当列的顺序都是升序默认可不必标出,当属性列有按照降序排列的,所有属性的升序降序都不要标明。

– UNIQUE——建立唯一索引。

– CLUSTERED——建立聚集索引。

– NONCLUSTERED——建立非聚集索引。

– ASC——索引升序排序。

– DESC——索引降序排序。

修改索引 对于已经建立的索引,如果需要对其重新命名,可以使用ALTER INDEX 语句。其一般格式为

ALTER INDEX <旧引索名字> RENAME TO<新引索名>

删除索引

当某个时期基本表中数据更新频繁或者某个索引不再需要时,需要删除部分索引。SQL语言使用DROP INDEX 语句删除索引,其一般格式是:

DROP INDEX<索引名>

删除索引时,DBMS不仅在物理删除相关的索引数据,也会从数据字典删除有关该索引的描述。

关于索引你会了吗?

我是懿,一个正在被打击还在努力前进的码农。欢迎大家关注我们的公众号,加入我们的知识星球,我们在知识星球中等着你的加入。

おすすめ

転載: blog.csdn.net/keep12moving/article/details/102655342