MySQL의 학습 - B + 트리 인덱스

우리는 이미 하나의 데이터 페이지에서 데이터를 찾는 검색 조건은 기본 키가있는 경우, 당신은 이분법 위치 홈, 특정 데이터를 찾을 수있는 데이터를 통해 순서의 다음 홈을 사용할 수있을 때 것을 알고있다. 그러나 우리는 어떻게 수십 페이지의 수천을 모르는 그것이 기본 키 열 또는 다른 열의 값을 찾을 수 있습니다 여부에 따라 인덱스가없는 페이지에서 데이터를 찾아부터 우리가 할 수있는 페이지로 빠르게 탐색 할 수없는 경우 기록, 우리가 할 수있는 첫 번째 페이지에서 함께 이중 연결리스트는 우리가 길을 찾아야했다 잔소리에 따라 특정 레코드를 찾기 위해 각 페이지에서 내려다보고있다.

간단한 지수 소개

위해서하는 것은 빠르게 페이지에서 데이터를 찾을 수 있도록, 인덱스가 제공하는 下一个数据页中用户记录的主键值必须大于上一个页中用户记录的主键值。데이터를 찾는 효율성을 개선하는 방법을 확인하기 위해 케이스를 사용하여 다음과 같은 인덱스를 :

테이블을 생성합니다 :

mysql> CREATE TABLE index_demo(
    ->     c1 INT,
    ->     c2 INT,
    ->     c3 CHAR(1),
    ->     PRIMARY KEY(c1)
    -> ) ROW_FORMAT = Compact;
Query OK, 0 rows affected (0.03 sec)

세 가지 데이터를 삽입합니다 :

mysql> INSERT INTO index_demo VALUES(1, 4, 'u'), (3, 9, 'd'), (5, 3, 'y');
Query OK, 3 rows affected (0.01 sec)
Records: 3  Duplicates: 0  Warnings: 0

단지 3 개 index_demo 테이블 레코드 데이터 페이지 (10)의 개수에 삽입 된 세 개의 일반 사용자 레코드를 저장할 수있는 페이지를 가정하는 레코드를 다시 삽입 :

mysql> INSERT INTO index_demo VALUES(4, 4, 'a');
Query OK, 1 row affected (0.00 sec)

우리는 페이지의 새로운 재배포 있었다 있도록 10 페이지까지 만, 세 개의 레코드를 넣을 수 있기 때문에 :

사용자의 기본 키가 가장 큰 5 페이지 (10)는 기록 페이지 (28)와 기록이 데이터의 다음 페이지의 기본 키 값과 일치되지 않도록 5> 네, 사용자는보다 커야합니다 기록하기 때문에 기본 키 값이 4가 키는이어서 움직임 레코드 동반 때 필요한 기본 키가 28 페이지로 이동 4 주 레코드 삽입 5 기록이기 때문에, 사용자에 기록 된 페이지의 기본 키를 필요 기록 4의 기본 키는 10 페이지에 삽입 :

작업에 페이지 추가 및 삭제를 기록하는 과정에서, 우리는 항상 같은 설정 한 상태를 기록하는 등의 작업의 번호를 이동할 수 있도록해야이 과정을 보여줍니다 :下一个数据页中用户记录的主键值必须大于上一个页中用户记录的主键值。这个过程我们也可以称为页分裂。

여러 데이터를 삽입 한 후, 다음이된다 :

그래서 당신은 신속하게 몇 가지 기록에 기본 키 값에 따라 페이지를 찾을 너무 많은 페이지에서 원하는 경우, 우리는 디렉토리 수를 줄 필요가 각 페이지에 해당하는 디렉토리 엔트리는, 각 디렉토리 항목은 다음 두 부분을 포함한다 :

페이지 사용자가 가장 작은 기본 키 값은, 우리가 대표하는 키를 사용하여 기록합니다.
페이지 번호, 우리는 page_no를 사용합니다.

우리는 단지 배열에 넣어, 예를 들어, 연속 실제 메모리에 저장된 몇 개의 디렉토리 항목이 필요합니다, 당신은 기본 키 값의 기록에 근거 빠른 검색 기능을 달성 할 수 있습니다. 의 우리가 특정 두 단계에 대한 기본 키의 기록 (20), 모양을 찾고 있다고 가정 해 봅시다 :

시작 신속 9 페이지 이분법 페이지에 대응하는 디렉토리 엔트리 (20) 3 (이후 12 <20 <209)에 기록 된 기본 키 값에 대한 디렉토리 엔트리를 결정한다.
그런 다음 첫 페이지에있는 방법의 기록 말한다을 찾을 수에 따라 특정 레코드를 찾을 수 9 페이지로 이동합니다.

페이지 디렉토리의 이름 인덱스의 이름입니다.

이노 지수

우리는 지속적으로 물리적 메모리에 저장되어있는 항목을 카탈로그에 따라 모든 기본 키 값을 찾기 위해 카탈로그에 특정 항목을 신속하게 이분법 사용 찾기 위해 가정 때문에 정상은, 간단한 인덱싱 기법이라고합니다

InnoDB는 16킬로바이트에 연속 저장 공간을 확보까지이며, 저장 공간의 관리와 같은 페이지를 사용하여 기본 단위이며, 테이블의 레코드 수의 증가와 함께, 당신은 항목을 내려 놓고 모든 카탈로그를 넣어 매우 큰 연속 저장 공간이 필요 또한, 우리는 종종 기록의 추가 및 삭제가, 28 페이지 수단 디렉토리 항목이 더 이상 필요, 요구하는있을 것이라는 점을, 더 이상 필요 없다, 우리는 기록의 28 페이지가 삭제 있다고 가정하지 2 개 카탈로그 항목 후 디렉토리 항목에 대한 앞으로 이동된다

관리 할 수있는 매우 유연한 방법을 제공해야 InnoDB의이 시점에서 目录项记录, 그것은 디렉토리 기록 데이터 레코드의 일반 관리에 따라 관리 할 수 없습니다. RECORD_TYPE 것 유일한 차이점은 디렉토리 데이터 기록이나 일반 데이터 레코드. 후 다시 생각 후, 페이지에 데이터가 페이지 관리 데이터의 방식으로 관리 할 수 있습니다 기록 :

디렉토리 엔트리 기록 데이터 기록 및 일반 차이 :

일반 사용자가 값이 0이 기록 RECORD_TYPE 동안 1 RECORD_TYPE 값 기록 디렉토리 항목은 1입니다.
자신의 InnoDB의 추가에 2 카탈로그 기록 번호와 기본 키 값의 페이지의 두 개의 열, 평균 사용자 레코드의 열을 사용자가 정의하면서, 또한 많은 열 숨기기 열을 포함 할 수있다.
디렉토리 엔트리 기록 min_rec_mask 값 (1)에 저장된 페이지 디렉토리 엔트리에 기록 된 3 만 최소 기본 키 값, 기타 다른 기록 min_rec_mask의 값은 0이고

이 세 가지 외에도, 다른 부분은 저장소가 인덱스 페이지는 페이지가 가게에 계속 높은 페이지 디렉토리를 생성하기 위해 나중에 확장 할 수 있습니다 가득 마지막 렌더링이되었다 때입니다 다음 동일합니다 :

그리고 천천히 추상화 :

그것의 이름은 B의 + 트리입니다.

저장 사용자 데이터 페이지 기록을 저장하거나 데이터 페이지 디렉토리 엔트리의 기록에 상관없이, 우리는 또한 노드에 대한 데이터의이 페이지를 호출 할 수 있도록 그들, B + 트리 데이터 구조에 저장 간주한다. 그것은 사실, 우리의 실제 사용자 레코드는 리프 노드 또는 리프 노드로 알려진 노드 B + 트리의 맨 아래에 저장되어, 그림에서 볼 수, 저장 디렉토리 항목에 사용되는 나머지 노드는 리프가 아닌 노드라고 또는 노드 B + 트리도 최상위 루트로 알려져있다 노드, 내. 논의의 편의를 위해, 최하부 층의 규정은, 그 레이어는 우리의 사용자 레코드의 0 층으로 저장되어, 다음 설정은 추가 할 수 있습니다.

페이지가 다음 100 개 개의 데이터를 저장할 수있는 경우이 거친 나무의 힘을 평가 :

B + 트리 하나만 100 개 레코드를 저장하기 위해, 사용자에 의해 기록 된 노드 기억 하나만 층 인 경우,
B + 트리 1000 × 100 = 100,000 레코드를 저장하기까지의 두 층이있는 경우
B + 트리 세 개의 층을 갖는 경우를 1,000 × 1,000 × 100 = 100,000,000 레코드까지 저장하는 단계를 포함한다.
는 B + 트리 4 개 개의 레이어가있는 경우, 1,000 × 1,000 × 1,000 × 100 =까지 저장할 수 천억 기록

일반적으로 1000 억이 때문에 정상적인 상황에서, 테이블에 기록이되지 않습니다, 우리는 네 페이지에있는 대부분이해야 할 찾을 수있는 기록을 찾기 위해 더 이상 기본 키 값에 의해 4 개 개의 레이어보다는 B + 트리를 사용 (3 찾을 이 소위 때문에 페이지도 구현 될 수 있도록 페이지 디렉토리 항목 및 기록 사용자 페이지), 페이지 디렉토리 각 페이지 내 (페이지 디렉토리), 신속하게 이분법에 의해 기록을 찾습니다

클러스터 된 인덱스

위의 트리 구조는 다음과 같은 두 가지 특징이 있습니다 :

1. 종류의 기본 키를 사용하여 녹화의 크기는 페이지 기록
2.B + 나무 잎 노드는 전체 사용자 레코드에 저장됩니다

B는이 두 가지 특성을 갖는 + 것은 나무라고 聚簇索引모든 완전한 사용자 레코드는이 클러스터 인덱스의 리프 노드에 저장된다. MySQL의 문을 작성하기 위해 명시 적으로 사용 INDEX 문을 필요로하지 않는다이 클러스터 된 인덱스는 InnoDB 스토리지 엔진은 자동으로 우리를 위해 클러스터 된 인덱스를 생성합니다.

클러스터 된 인덱스가 데이터를 확인하기 위해 기본 키이기 때문에, 때 우리의 쿼리에 기본 키를 포함 할 수 없습니다, 당신은 아직 데이터 모두를 처음부터 끝까지해야?

보조 인덱스

우리는 C2 칼럼 B + 트리의 값 종류의 새 게시물을 작성해야합니다, 우리의 쿼리가 C2 컬럼의 값입니다 가정하자.

여러 가지로 위에 소개 된 클러스터 B + 트리 인덱스 :

  • 의미의 세 가지 측면을 포함 정렬 기록과 페이지에 기록 C2 컬럼의 크기를 사용합니다 :

    • 그것은 단일 연결리스트로 배열 크기 C2 열 페이지 순서로 기록된다.
    • 각 페이지는 열 (C2)에 기록 된 페이지의 순서에 따른 이중 연결리스트로 배열하는 사용자 레코드를 저장한다.
    • 기록 저장 디렉토리 페이지는 열 (C2)에 기록 된 순서대로 페이지 디렉토리 엔트리에 따라 배열되는 이중 연결리스트에서 동일한 레벨과 다른 레벨의 페이지로 분할된다.
  • 그것은 B + 트리의 리프 노드에 저장 완전한 사용자 레코드가 아니라이 두 컬럼의 컬럼 C2 + 기본 키 값.

  • 디렉토리 기록은 더 이상 열 C2 + 페이지 번호가 일치로 바뀌 + 페이지 번호가 일치하는 기본 키, 없습니다.

그래서 우리는 당신이 우리의 단지 건설이 A B + 트리를 사용할 수있는 C2 컬럼의 값에 의해 기록 된 일부 단어를 찾으려면. 다음 레코드 조회 컬럼 C2는, 예를 들어 보면 4 :

  • P는 42이다 루트 페이지, 즉 페이지 (44)에있어서, 히스토리 페이지 디렉토리 엔트리를 결정하고, 페이지 디렉토리 레코드를 빠르게 찾을 수있다 (2 <4 <9 이후).

  • 실제 사용자가 페이지 디렉토리 엔트리 기록으로 페이지를 기록하는 위치를 결정합니다. 페이지에 페이지 (42) 상에 빠르게 실제로 저장된 사용자 레코드를 찾을 수 있지만, 단일 열 C2의 제약이 없기 때문에, (4)의 기록 C2 열 값의 데이터가 복수의 페이지로 분산 될 수 있고, (2) <4 ≤ 4 왜냐하면 34 페이지는 페이지 실제 저장 레코드 (35)는 사용자의 페이지를 결정한다.

  • 실제 사용자 레코드의 페이지에 저장된 특정 레코드로 이동합니다. 34 페이지와 35 페이지가 특정 레코드를 대상으로합니다.

  • 그러나 우리가 (있다, 기본 키)에만 C2와 C1이 B + 트리 리프 노드 점포의 기록을 두 개의 열, 必须再根据主键值去聚簇索引中再查找一遍完整的用户记录。这个过程也被称为回表。也就是根据c2列的值查询一条完整的用户记录需要使用到2棵B+树작업을 요구 한이 공간을 절약하기 위해 다시 테이블에 있습니다.

이것은 또한 B + 트리 인덱스 두 (영어 보조 인덱스) 또는 보조 지표로 알려져있다, 그래서 때문에 B + 트리의 기본 키가 아닌 열이의 완전한 사용자 레코드 앞에 위치 할 수 수술대에 반환을 필요로한다. 우리는 이것을 B + 트리가 설립 인덱스 컬럼 C2입니다 전화, 그래서 우리가 사용 때문에, B + C2 열 정렬 나무의 크기입니다.

공동 색인

우리는 또한 동시에 예를 들어, 우리는 B + 트리의 크기의 C2와 C3 칼럼에 따라 정렬하려면, 인덱스 여러 열을 동시에, 데이터 정렬, 여러 컬럼의 크기는이 두 가지 의미가 포함되어 있습니다 :

먼저 각 레코드의 페이지와 열 (C2)으로 분류.
동일한 기록 열 C2 경우, C3 정렬 컬럼 사용

렌더링 :

  • C2, C3에 의해 기록 된 각각의 디렉토리 엔트리가, 세 부분의 페이지 수, 각 레코드의 열 C2의 값에 의해 정렬되도록, C2 열은 동일한 기록이면 열 (C3)의 값에 따라 분류.

  • 기록 노드 C2, C3, 및 기본 키의 열 (C1)로부터 B + 사용자 잎

  • 정렬 B + 트리 인덱스 조인트라는 본질적 보조 인덱스로서 C2 및 크기 열의 C3이 설정된다. 이 열은 C2 및 C3 수단은 각각의 인덱스식이 다르다있다

참고 이노 B + 트리 인덱스

페이지 번호의 루트 페이지가 변경되지 않습니다

(기본이 생성 될하지있을 경우) 우리는 테이블에 클러스터 된 인덱스를 만들 때 루트 페이지 있었지만 한이 시간에는 데이터가 저장되지 않은 루트 페이지.

데이터 저장이 꽉 찼을 때 데이터를 추가 할 때, 데이터 테이블, 루트 페이지 이전에 저장된 데이터의 추가가, 페이지로 복사 된 데이터가, 페이지 분할을 생성하는 페이지 B가 발생하면, 현재의 루트 페이지 내에 저장된다 페이지 디렉토리가 기록됩니다.

그들이 그렇게 인덱스에 액세스하려면 고정 된 장소에서 페이지 번호를 근절 것, InnoDB 스토리지 엔진 인덱스를 사용해야하는 사람들.

페이지에있는 노드의 고유성

보조 인덱스가 열을 기준으로 분류 할 때 보조 인덱스에만 문제가, 같은 상황은 기본 키의 고유성을 구별 할 필요성과 함께,이 시간이 발생할 수 있습니다. 추가로 데이터를 추가 만 타겟팅 페이지입니다.

적어도 하나의 페이지를 저장 두 개의 레코드

당신은 단지 기록을 넣으면 그림이 상상 너무 아름다운이기 때문이다.

및 삭제 인덱스 문을 만들 MYSQL

InnoDB는 자동으로 자동으로 B + 트리 인덱스를 만들려면 기본 키 또는 UNIQUE 컬럼으로 선언 할 것이다, 그러나 우리가 다른 컬럼에 대한 빌드 인덱스 원한다면 우리는 명시 적으로 지정해야합니다.

우리는 하나의 열이 테이블 작성 또는 여러 열 공동 색인의 설립에 인덱싱 할 필요가 지정할 수 있습니다 :

CREATE TALBE 表名 (
    各种列的信息 ··· , 
    [KEY|INDEX] 索引名 (需要被索引的单个列或多个列)
)

테이블에 또는 것은 수정 :

ALTER TABLE 表名 ADD [INDEX|KEY] 索引名 (需要被索引的单个列或多个列);

또한 삭제 인덱스는 테이블 구조 때를 수정할 수 있습니다 :

ALTER TABLE 表名 DROP [INDEX|KEY] 索引名;

구체적인 예 :

CREATE TABLE index_demo(
    c1 INT,
    c2 INT,
    c3 CHAR(1),
    PRIMARY KEY(c1),
    INDEX idx_c2_c3 (c2, c3)
);
ALTER TABLE index_demo DROP INDEX idx_c2_c3;

추천

출처www.cnblogs.com/it-dennis/p/12611407.html