>헤드라인 >MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!

MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!

青灯夜游
青灯夜游앞으로
2022-06-23 17:36:114758검색

SQL Boy로서 기본을 모르는 사람은 없겠죠? 면접 질문은 많지 않습니다. 기본 지식이 좋은 친구들은 이 부분을 건너뛸 수 있습니다. 물론, SQ문은 Niuke, LeetCode, LintCode 등의 웹사이트를 통해 직접 작성해 볼 수도 있습니다.
1. 내부 조인, 외부 조인, 크로스 조인, 데카르트 곱이란 무엇인가요?

내부 조인: 연결 일치 관계를 만족하는 두 테이블에서 레코드를 얻습니다.
  • 외부 조인: 연결 일치 관계를 만족하는 두 테이블의 레코드를 얻을 뿐만 아니라, 일치 관계를 만족하지 않는 특정 테이블(또는 두 테이블)의 레코드도 포함합니다.
  • 교차 조인: 두 테이블의 모든 레코드 간의 일대일 대응을 표시합니다. 필터링을 위한 일치 관계가 없습니다. 테이블 A에 m개의 행이 있고 테이블 B에 n개의 행이 있는 경우, 그러면 A와 B의 교차 연결 결과는 m*n 행입니다.
  • 데카르트 곱: 수학의 개념입니다. 예를 들어 A={a,b}로 설정하고 B={1,2,3}으로 설정한 다음 A✖️B={,,,,,,}.
  • 2. MySQL의 내부 조인, 왼쪽 조인, 오른쪽 조인의 차이점은 무엇인가요?

MySQL 연결은 크게 내부 연결과 외부 연결로 구분됩니다. 일반적으로 사용되는 외부 연결에는 왼쪽 조인과 오른쪽 조인이 있습니다.

MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!

inner Join 내부 조인, 두 테이블을 연결하여 쿼리하면 두 테이블의 완전히 일치하는 결과 집합만 유지됩니다.
  • left Join 두 테이블을 연결하여 쿼리하면 왼쪽의 모든 행이 유지됩니다. 오른쪽 테이블에 일치하는 레코드가 없더라도 테이블이 반환됩니다.
  • 오른쪽 조인 두 테이블 사이에 연결 쿼리를 수행하면 왼쪽 테이블에 일치하는 레코드가 없더라도 오른쪽 테이블의 모든 행이 반환됩니다.
  • 3. 데이터베이스의 세 가지 주요 패러다임에 대해 이야기해 보세요.

MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!

첫번째 정규형: 데이터 테이블의 각 열(각 필드)은 분할될 수 없습니다. 예를 들어, 사용자 테이블에서 사용자 주소는 첫 번째 패러다임을 따르도록 국가, 지방, 도시로 분할될 수도 있습니다.
  • 두 번째 정규형: 첫 번째 정규형을 기반으로 하는 기본 키가 아닌 열은 기본 키에 완전히 의존하며 기본 키의 일부가 될 수 없습니다. 예를 들어 주문 테이블에는 상품 정보(상품 가격, 상품 종류)가 저장되어 있으므로, 두 번째 패러다임을 만족시키기 위해서는 상품 ID와 주문 ID를 공동 기본 키로 사용해야 합니다.
  • 제3정규형: 제2정규형을 만족한다는 원칙에 따라 테이블의 기본 키가 아닌 키는 기본 키에만 의존하고 다른 기본 키가 아닌 키에는 의존하지 않습니다. 예를 들어 주문 테이블에는 사용자 정보(이름, 주소)를 저장할 수 없습니다.

MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!세 가지 주요 패러다임의 역할은 데이터베이스의 중복성을 제어하고 공간을 절약하는 것입니다. 실제로 일반 인터넷 회사의 설계는 중복성에 의한 크로스 테이블 및 데이터베이스 간을 피하는 안티 패러다임입니다. 데이터, 성능 향상을 위해 공간을 사용합니다.

4. varchar와 char의 차이점은 무엇인가요?

MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!

char

:

char은 고정 길이 문자열을 나타내며 길이는 고정되어 있습니다.
  • 삽입된 데이터의 길이가 char의 고정 길이보다 작으면 공백으로 채워집니다. ;
  • 길이가 고정되어 있기 때문에 접근 속도는 varchar보다 훨씬 빠르며 심지어 50% 빠르지만 길이가 고정되어 있기 때문에 공간을 시간으로 교환하는 방법입니다. char, 인코딩에 관계없이 저장할 수 있는 최대 문자 수는 255자입니다.
  • varchar
  • :

varchar는 가변 길이 문자열을 나타내며 길이는 가변입니다.

삽입된 데이터는 long으로 저장됩니다.
  • varchar는 접근 측면에서 char와 반대인데, 길이가 고정되어 있지 않아 접근이 느리지만, 이로 인해 추가 공간을 차지하지 않는 방식입니다.
  • varchar의 경우 저장할 수 있는 최대 문자 수는 65532입니다.
  • 일상 디자인에서는 상대적으로 길이가 고정된 문자열의 경우 길이가 불확실한 문자열의 경우 char를 사용하는 것이 더 적합합니다. .
  • 5. 블롭과 텍스트의 차이점은 무엇인가요?

blob은 이진 데이터를 저장하는 데 사용되고, 텍스트는 큰 문자열을 저장하는 데 사용됩니다.

blob에는 문자 세트가 없고, 텍스트에는 문자 세트가 있으며, 문자 세트의 조합 규칙에 따라 값이 정렬되어 비교됩니다.
  • 6. DATETIME과 TIMESTAMP의 유사점과 차이점은 무엇인가요?
동일점

:

두 데이터 유형은 시간을 동일한 형식으로 저장합니다. 둘 다

    두 데이터 유형 모두 "날짜" 및 "시간" 부분을 포함합니다.
  1. YYYY-MM-DD HH:MM:SS두 데이터 유형 모두 마이크로초 단위로 소수 초를 저장할 수 있습니다(초 후 소수점 이하 6초)
  2. Difference
  3. :

MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!

  • Date range: DATETIME의 날짜 범위는 1000-01-01 00:00:00.0000009999-12-31 23:59:59.999999;TIMESTAMP 的时间范围是1970-01-01 00:00:01.000000 UTC到 ``2038-01-09 03:14:07.999999 UTC

  • 저장 공간: DATETIME의 저장 공간은 8바이트, TIMESTAMP의 저장 공간은 4바이트

  • 시간대 관련: DATETIME 저장 시간은 시간대와 관련이 없습니다. TIMESTAMP 저장 시간은 시간대와 관련이 있으며 표시되는 값도 시간대에 따라 다릅니다.

  • 기본값: DATETIME의 기본값은 null입니다. ; TIMESTAMP 필드는 기본적으로 비어 있지 않으며( null 아님) 기본값은 현재 시간(CURRENT_TIMESTAMP)

7입니다. MySQL에 존재하는 것과 차이점은 무엇입니까?

MySQL의 in 문은 외부 테이블과 내부 테이블 사이에 해시 연결을 수행하는 반면, 존재 문은 외부 테이블에서 루프를 수행하고 루프가 루프될 때마다 내부 테이블을 쿼리합니다. 존재하는 것이 명령문보다 더 효율적이라고 생각할 수도 있습니다. 이 문은 실제로 부정확합니다. 우리는 시나리오를 구별해야 합니다.

  • 쿼리된 두 테이블의 크기가 같은 경우 in과 사용 사이에는 큰 차이가 없습니다. 존재합니다.

  • 두 테이블 중 하나가 더 작고 다른 하나가 큰 테이블인 경우 더 큰 하위 쿼리 테이블과 더 작은 하위 쿼리 테이블에 대한 사용이 존재합니다.

  • not in 및 존재하지 않음: 쿼리 문에서 not in을 사용하면 인덱스를 사용하지 않고 내부 및 외부 테이블 모두에서 전체 테이블이 검색되며 not extsts의 하위 쿼리는 계속해서 인덱스를 사용할 수 있습니다. 테이블. 따라서 어떤 테이블이 크든 존재하지 않는 것을 사용하는 것이 없는 것보다 빠릅니다.

8. MySQL에서 통화를 기록하는 데 어떤 필드 유형을 사용하는 것이 더 좋습니까?

Currency는 MySQL 데이터베이스에서 일반적으로 Decimal 및 Numric 유형으로 표현되며, 이 두 유형은 MySQL에서 동일한 유형으로 구현됩니다. 통화 관련 데이터를 저장하는 데 사용됩니다.

예를 들어 급여 DECIMAL(9,2), 9(정밀도)는 값을 저장하는 데 사용할 전체 소수 자릿수를 나타내고, 2(스케일)은 저장하는 데 사용할 소수 자릿수를 나타냅니다. 가치. 급여 열에 저장되는 값의 범위는 -9999999.99부터 9999999.99까지입니다.

DECIMAL 및 NUMERIC 값은 해당 값의 소수 정밀도를 유지하기 위해 이진 부동 소수점이 아닌 문자열로 저장됩니다.

float이나 double을 사용하지 않는 이유: float와 double은 바이너리로 저장되기 때문에 일정한 오류가 있습니다.

9. MySQL은 이모티콘을 어떻게 저장하나요?

MySQL은 문자열을 직접 사용하여 이모티콘을 저장할 수 있습니다.

하지만 utf8 인코딩은 불가능하다는 점에 유의해야 합니다. MySQL의 utf8은 utf8의 축소된 버전이므로 문자를 저장하는 데 최대 3바이트만 사용하므로 표현식을 저장할 수 없습니다. 무엇을 해야 할까요?

utf8mb4 인코딩이 필요합니다.

alter table blogs modify content text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci not null;

10. 삭제, 삭제, 자르기의 차이점은 무엇인가요?

세 가지 모두 삭제를 의미하지만 세 가지 사이에는 약간의 차이가 있습니다.


delete truncate drop
type 은 DML에 속합니다 D DL 소속 DDL에 속함
Rollback 롤백 가능 롤백 불가 롤백 불가
콘텐츠 삭제 테이블 구조가 여전히 존재합니다. 데이터 행 전체 또는 일부를 삭제하세요. 의 테이블 테이블 구조가 그대로 남아 있습니다. 테이블을 삭제하세요. 데이터베이스에서 테이블을 삭제하면 모든 데이터 행, 인덱스 및 권한도 삭제됩니다.
삭제 속도 느린 삭제 속도, 한줄씩 삭제해야함 삭제속도가 빠름 삭제속도가 가장 빠름

따라서 테이블이 더 이상 필요하지 않으면 drop을 사용하고, 일부 데이터 행을 삭제하려면 delete를 사용하고, 테이블을 유지하고 모든 데이터를 삭제하려면 truncate를 사용하세요.

11.UNION과 UNION ALL의 차이점은 무엇인가요?

  • UNION ALL을 사용하면 중복된 레코드 행이 병합되지 않습니다
  • UNION의 효율성이 UNION ALL보다 높습니다

12. count(1), count(*) 및 count(열 이름)의 차이점은 무엇입니까? )?

MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!

실행 효과:

  • count(*)에는 행 수에 해당하는 모든 열이 포함됩니다. 이는 결과 계산 시 NULL 열 값이 무시되지 않습니다
  • count(1) 포함 무시 모든 열에 대해 1은 결과를 계산할 때 열 값을 무시하지 않습니다. 개수(열 이름)에는 결과를 계산할 때 열 값이 포함됩니다. 무시됩니다(여기서 공백은 빈 문자열이나 0이 아니라 null 개수를 나타냅니다). 즉, 특정 필드 값이 NULL인 경우 통계가 계산되지 않습니다.
실행 속도

:

열 이름이 기본 키인 경우 count(열 이름)는 count(1)보다 빠릅니다.
  • 열 이름이 기본 키가 아니면 count(1)은 count(컬럼명)보다 빠릅니다
  • 테이블에 여러 컬럼이 있고 기본 키가 없으면 count(1)의 실행 효율성이 count(*)보다 낫습니다
  • 기본 키가 있으면 select count의 실행 효율성이 더 좋습니다 (기본 키)가 최적입니다
  • 테이블에 필드가 하나만 있으면 셀렉트 카운트(*)가 최적입니다.
  • 13. SQL 쿼리문의 실행 순서는 무엇인가요?

MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!

  • FROM

    : FROM 절에서 왼쪽 테이블 및 오른쪽 테이블>에 데카르트 곱(Cartesian product)을 수행하여 가상 테이블 VT1

  • ON

    을 적용합니다. 가상 테이블 VT1로 필터링하고 을 충족하는 행만 가상 테이블 VT2

  • JOIN

    에 삽입됩니다. OUTER JOIN(예: LEFT OUTER JOIN, RIGHT OUTER JOIN)이 지정된 경우 Unmatched 예약된 테이블의 행은 가상 테이블 VT2에 외부 행으로 추가되어 가상 테이블 VT3이 됩니다. FROM 절에 테이블이 2개 이상 포함된 경우 이전 연결에서 생성된 결과 테이블 VT3과 다음 테이블에 대해 모든 테이블이 처리될 때까지 1)~3) 단계를 반복합니다.

  • WHERE

    : 오른쪽 가상 테이블 VT3이 적용됩니다. WHERE 필터 조건 및 과 일치하는 레코드만 가상 테이블 VT4

  • GROUP BY

    : GROUP BY 절의 열에 따라 VT4의 레코드를 그룹화합니다. CUBE|ROLLUP: 테이블 VT5에서 CUBE 또는 ROLLUP 작업을 수행하여 테이블 VT6

  • HAVING: 가상 테이블 VT6에 HAVING 필터를 적용합니다. 을 충족하는 레코드만 가상 테이블 VT7에 삽입됩니다.

  • SELECT: 두 번째로 SELECT 연산을 수행하고, 지정된 컬럼을 선택하여 가상 테이블 VT8

  • DISTINCT: 중복된 데이터를 제거하고 가상 테이블 VT9

  • ORDER에 삽입 BY : 가상 테이블 VT9의 레코드를 에 따라 정렬하여 가상 테이블 VT10을 생성합니다. 11)

  • LIMIT: 지정된 행의 레코드를 꺼내서 가상 테이블 VT11을 생성하고 반환합니다. the querying user

  • 데이터베이스 아키텍처

    14. MySQL의 기본 아키텍처에 대해 이야기해 보세요.

MySQL 논리 아키텍처 다이어그램은 주로 세 가지 계층으로 나뉩니다.

  • 클라이언트: 최상위 서비스는 MySQL에만 고유한 것이 아닙니다. 대부분의 네트워크 기반 클라이언트/서버 도구 또는 서비스는 유사한 아키텍처를 가지고 있습니다. 접속처리, 권한인증, 보안 등
  • 서버 계층: 쿼리 구문 분석, 분석, 최적화, 캐싱 및 모든 내장 기능(예: 날짜, 시간, 수학 및 암호화 기능)을 포함하여 스토리지 엔진 전반에 걸쳐 MySQL의 핵심 서비스 기능 대부분이 이 계층에 있습니다. 이 계층에서는 저장 프로시저, 트리거, 뷰 등의 기능이 구현됩니다.
  • 스토리지 엔진 레이어: 세 번째 레이어에는 스토리지 엔진이 포함되어 있습니다. 스토리지 엔진은 MySQL에서 데이터의 저장 및 검색을 담당합니다. 서버 계층은 API를 통해 스토리지 엔진과 통신합니다. 이러한 인터페이스는 서로 다른 스토리지 엔진 간의 차이점을 보호하여 이러한 차이점을 상위 계층 쿼리 프로세스에 투명하게 만듭니다.

15. MySQL에서 SQL 쿼리문은 어떻게 실행되나요?

  • 먼저 권한이 있는지 확인하세요. 권한이 없으면 바로 오류 메시지가 반환됩니다. (MySQL8.0 버전 이전) . 是否有权限,如果没有权限,直接返回错误信息,如果有权限会先查询缓存 (MySQL8.0 版本以前)。
  • 如果没有缓存,分析器进行语法分析,提取 sql 语句中 select 等关键元素,然后判断 sql 语句是否有语法错误,比如关键词是否正确等等。
  • 语法解析之后,MySQL的服务器会对查询的语句进行优化,确定执行的方案。
  • 完成查询优化后,按照生成的执行计划调用数据库引擎接口
  • 캐시가 없으면 분석기는 문법 분석을 수행하고 sql 문에서 select 등의 핵심 요소를 추출한 후 키워드가 올바른지 등 sql 문에 구문 오류가 있는지 확인합니다. , 등.

구문 분석 후 MySQL 서버는 쿼리 문을 최적화하고 실행 계획을 결정합니다.

쿼리 최적화 완료 후 생성된 실행 계획 에 따라 데이터베이스 엔진 인터페이스를 호출하고 실행 결과를 반환합니다.

MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!스토리지 엔진

16. MySQL의 일반적인 스토리지 엔진은 무엇입니까?

FunctionMylSAMMEMORYInnoDB스토리지 제한256TB RAM64TB거래 지원 아니요아니요예전체 텍스트 인덱스 지원예No예트리 인덱스 지원예예 네 지원합니다 해시 인덱스

MySQL 5.5 이전에는 기본 스토리지 엔진이 MylSAM이었고, 5.5 이후에는 InnoDB가 되었습니다.

InnoDB에서 지원하는 해시 인덱스는 적응형입니다. InnoDB는 테이블 사용에 따라 자동으로 테이블에 대한 해시 인덱스를 생성합니다.

MySQL 5.6부터 InnoDB는 전체 텍스트 인덱싱을 지원합니다.

17. 스토리지 엔진을 어떻게 선택해야 하나요?

대략 다음과 같이 선택할 수 있습니다.

  • 대부분의 경우 기본 InnoDB를 사용하면 충분합니다. 커밋, 롤백 및 복구를 위한 트랜잭션 보안(ACID 호환성) 기능을 제공하고 동시성 제어가 필요한 경우 InnoDB가 첫 번째 선택입니다.
  • 데이터 테이블이 주로 레코드를 삽입하고 쿼리하는 데 사용된다면 MyISAM 엔진은 더 높은 처리 효율성을 제공합니다.
  • 데이터를 임시로 저장하는 경우에는 데이터의 양이 많지 않고 높은 데이터 보안이 요구되지 않는 경우 MEMORY 엔진에 데이터를 메모리에 저장하도록 선택할 수 있습니다. MySQL은 쿼리의 중간 결과를 저장합니다.

사용할 엔진은 필요에 따라 유연하게 선택할 수 있습니다. 스토리지 엔진은 테이블을 기반으로 하기 때문에 데이터베이스의 여러 테이블은 다양한 엔진을 사용하여 다양한 성능과 실제 요구 사항을 충족할 수 있습니다. 적절한 스토리지 엔진을 사용하면 전체 데이터베이스의 성능이 향상됩니다.

18.InnoDB와 MylSAM의 주요 차이점은 무엇인가요?

PS: MySQL8.0은 서서히 인기를 얻고 있습니다. 인터뷰가 아니라면 MylSAM에 대해 많이 알 필요는 없습니다.

MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!

1. 저장 구조: 각 MyISAM은 디스크에 세 개의 파일로 저장됩니다. 모든 InnoDB 테이블은 동일한 데이터 파일에 저장됩니다(여러 파일일 수도 있고 독립적인 테이블 공간 파일일 수도 있음). InnoDB 테이블의 크기는 일반적으로 2GB인 운영 체제 파일 크기에 의해서만 제한됩니다.

2. 트랜잭션 지원: MyISAM은 트랜잭션 지원을 제공하지 않으며 트랜잭션(커밋), 롤백(롤백) 및 충돌 복구 기능(충돌 복구 기능)과 같은 트랜잭션 보안 기능을 제공합니다.

3 최소 잠금 세분성: MyISAM은 업데이트 중에 전체 테이블이 잠기므로 다른 쿼리 및 업데이트가 차단됩니다.

4. 인덱스 유형: MyISAM의 인덱스는 클러스터형 인덱스이고 데이터 구조는 B-트리입니다. InnoDB의 인덱스는 비클러스터형 인덱스이고 데이터 구조는 B+ 트리입니다.

5. 기본 키가 필요합니다: MyISAM은 인덱스나 기본 키가 없는 테이블이 존재할 수 있도록 허용합니다. InnoDB가 기본 키나 비어 있지 않은 고유 인덱스를 설정하지 않은 경우 는 자동으로 6바이트 기본 키( 사용자에게는 보이지 않음), 데이터는 메인 인덱스의 일부이며, 추가 인덱스는 메인 인덱스의 값을 저장합니다.

6. 테이블의 특정 행 수: MyISAM은 테이블의 총 행 수를 저장합니다. 테이블에서 count()를 선택하면 값이 직접 저장되지 않습니다. 테이블의 총 행 수. select count() from table;을 사용하면 전체 테이블을 탐색하지만 wehre 조건을 추가한 후에는 MyISAM과 InnoDB가 동일한 방식으로 처리합니다.

7. 외래 키 지원: MyISAM은 외래 키를 지원하지 않습니다.

Logs

19. MySQL 로그 파일이란 무엇입니까? 각각의 기능을 소개해주세요.

1MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!

다음을 포함한 많은 MySQL 로그 파일이 있습니다.

  • 오류 로그(오류 로그): 오류 로그 파일은 MySQL의 시작, 실행 및 종료 프로세스를 기록하고 MySQL 문제를 찾는 데 도움이 될 수 있습니다.
  • Slow query log(느린 쿼리 로그): 느린 쿼리 로그는 실행 시간이 long_query_time 변수에 정의된 길이를 초과하는 쿼리 문을 기록하는 데 사용됩니다. 느린 쿼리 로그를 통해 어떤 쿼리문이 최적화를 위한 실행 효율성이 낮은지 확인할 수 있습니다.
  • 일반 쿼리 로그(일반 로그): 일반 쿼리 로그는 요청이 올바르게 실행되었는지 여부에 관계없이 MySQL 데이터베이스에 요청된 모든 정보를 기록합니다.
  • 바이너리 로그(bin log): 바이너리 로그는 데이터베이스에서 실행되는 모든 DDL, DML 문(데이터 쿼리문 select, show 등 제외)을 기록하며, 이벤트 형태로 기록되어 바이너리로 저장된다. 파일.

InnoDB 스토리지 엔진별 로그 파일도 두 개 있습니다.

  • Redo log(redo 로그): Redo 로그는 InnoDB 스토리지 엔진에 대한 트랜잭션 로그를 기록하기 때문에 매우 중요합니다.
  • Rollback log(undo 로그): 롤백 로그는 이름에서도 알 수 있듯이 데이터를 롤백하는 로그입니다. 트랜잭션이 데이터베이스를 수정하면 InnoDB 엔진은 다시 실행 로그를 기록할 뿐만 아니라 해당 실행 취소 로그도 생성합니다. 트랜잭션 실행이 실패하거나 롤백이 호출되어 트랜잭션이 롤백되는 경우 실행 취소 로그의 정보 수정 전의 모습으로 스크롤하여 데이터를 복원할 수 있습니다.

20. binlog와 redo log의 차이점은 무엇인가요?

  • bin 로그는 InnoDB, MyISAM 등 스토리지 엔진의 로그를 포함하여 데이터베이스 관련 모든 로그 기록을 기록하는 반면, redo 로그는 InnoDB 스토리지 엔진의 로그만 기록합니다.
  • 기록된 내용이 다릅니다. bin 로그는 트랜잭션의 구체적인 작업 내용을 기록합니다. 즉, 논리적 로그입니다. 리두 로그는 각 페이지(Page)의 물리적 변경 사항을 기록합니다.
  • 쓰기 시간이 다릅니다. bin 로그는 트랜잭션이 커밋되기 전에만 커밋됩니다. 즉, 디스크에 한 번만 쓰여집니다. 트랜잭션이 진행되는 동안 redo ertry는 redo 로그에 지속적으로 기록됩니다.
  • 쓰기 방법도 다릅니다. Redo 로그는 쓰기와 지우기를 주기적으로 수행하는 반면, bin 로그는 추가 쓰기이며 이미 작성된 파일을 덮어쓰지 않습니다.

21. 업데이트 문 실행 방법을 이해하셨나요?

업데이트 문의 실행은 서버 계층과 엔진 계층의 협력에 의해 완료되며, 테이블에 데이터를 쓰는 것 외에도 해당 로그도 기록되어야 합니다.

1MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!

  • 실행자는 먼저 라인 ID=2를 얻기 위해 엔진을 찾습니다. ID는 기본 키이고 스토리지 엔진은 데이터를 검색하여 이 행을 찾습니다. ID=2인 행이 있는 데이터 페이지가 이미 메모리에 있으면 실행기로 직접 반환됩니다. 그렇지 않으면 먼저 디스크에서 메모리로 읽어온 다음 반환해야 합니다.

  • 실행자는 엔진에서 제공한 행 데이터를 가져오고 이 값에 1을 더합니다. 예를 들어 이전에는 N이었지만 지금은 N+1이고 새 데이터 행을 가져온 다음 엔진을 호출합니다. 이 새로운 데이터 행을 쓰는 인터페이스입니다.

  • 엔진은 이 새로운 데이터 행을 메모리에 업데이트하고 업데이트 작업을 리두 로그에 기록합니다. 이때 리두 로그는 준비 상태입니다. 그런 다음 실행이 완료되었으며 언제든지 트랜잭션을 제출할 수 있음을 실행자에게 알립니다.

  • 실행자는 이 작업의 binlog를 생성하고 binlog를 디스크에 기록합니다.

  • Executor는 엔진의 커밋 트랜잭션 인터페이스를 호출하고, 엔진은 방금 작성된 Redo 로그를 커밋 상태로 변경하며 업데이트가 완료됩니다.

위 그림에서 볼 수 있듯이 MySQL은 업데이트 문을 실행할 때 서비스 계층의 문을 구문 분석하고 실행하는 동시에 엔진 계층에 데이터를 추출하여 저장하며 binlog를 기록합니다. 서비스 계층 및 Redo 로그는 InnoDB에 기록됩니다.

그뿐만 아니라 redo 로그를 작성할 때 제출 단계는 두 가지 단계가 있습니다. 하나는 binlog가 작성되기 전 prepare 상태를 작성하는 것이고, 다른 하나는 binlog가 작성된 후 commit입니다. .코드> 상태 쓰기. <code>prepare状态的写入,二是binlog写入之后commit状态的写入。

22.那为什么要两阶段提交呢?

为什么要两阶段提交呢?直接提交不行吗?

我们可以假设不采用两阶段提交的方式,而是采用“单阶段”进行提交,即要么先写入redo log,后写入binlog;要么先写入binlog,后写入redo log。这两种方式的提交都会导致原先数据库的状态和被恢复后的数据库的状态不一致。

先写入redo log,后写入binlog:

在写完redo log之后,数据此时具有crash-safe能力,因此系统崩溃,数据会恢复成事务开始之前的状态。但是,若在redo log写完时候,binlog写入之前,系统发生了宕机。此时binlog没有对上面的更新语句进行保存,导致当使用binlog进行数据库的备份或者恢复时,就少了上述的更新语句。从而使得id=2这一行的数据没有被更新。

1MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!

先写入binlog,后写入redo log:

写完binlog之后,所有的语句都被保存,所以通过binlog复制或恢复出来的数据库中id=2这一行的数据会被更新为a=1。但是如果在redo log写入之前,系统崩溃,那么redo log中记录的这个事务会无效,导致实际数据库中id=2

22. 그럼 왜 2단계 제출이 있는 걸까요?

왜 2단계 제출인가요? 그냥 직접 제출하면 안되나요? 1MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!

2단계 제출을 사용하는 대신 "단일 단계" 제출을 채택한다고 가정할 수 있습니다. 즉, 먼저 리두 로그를 작성한 다음 binlog를 작성하거나 binlog를 먼저 작성한 다음 리두 로그를 작성합니다. 이 두 가지 방법으로 제출하면 원본 데이터베이스의 상태가 복원된 데이터베이스의 상태와 일치하지 않게 됩니다.

🎜리두 로그를 먼저 작성한 다음 binlog를 작성하세요. 🎜🎜🎜리두 로그를 작성한 후 현재 데이터에는 충돌 방지 기능이 있으므로 시스템이 충돌하고 데이터가 거래 이전 상태의 시작. 그러나 redo 로그가 완료되고 binlog가 기록되기 전에 시스템이 충돌하면 시스템이 충돌합니다. 이때 binlog는 위의 업데이트 문을 저장하지 않으므로, binlog를 사용하여 데이터베이스를 백업하거나 복원할 때 위의 업데이트 문이 누락됩니다. 결과적으로 id=2 행의 데이터는 업데이트되지 않습니다. 🎜🎜1MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!🎜🎜🎜 binlog에 먼저 쓴 다음 redo 로그에 기록: 🎜🎜🎜binlog를 작성한 후 모든 명령문이 저장되므로 binlog를 통해 복사되거나 복원된 데이터베이스의 id=2 행에 있는 데이터가 a=1로 업데이트됩니다. 그러나 Redo 로그가 작성되기 전에 시스템이 충돌하면 Redo 로그에 기록된 트랜잭션이 유효하지 않게 되어 실제 데이터베이스의 id=2 행에 있는 데이터가 업데이트되지 않게 됩니다. 🎜🎜🎜🎜🎜간단히 말하면 redo 로그와 binlog는 모두 트랜잭션의 커밋 상태를 나타내는 데 사용될 수 있으며, 2단계 커밋은 두 상태를 논리적으로 일관되게 유지하는 것입니다. 🎜

23.redo log怎么刷入磁盘的知道吗?

redo log的写入不是直接落到磁盘,而是在内存中设置了一片称之为redo log buffer的连续内存空间,也就是redo 日志缓冲区

1MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!

什么时候会刷入磁盘?

在如下的一些情况中,log buffer的数据会刷入磁盘:

  • log buffer 空间不足时

log buffer 的大小是有限的,如果不停的往这个有限大小的 log buffer 里塞入日志,很快它就会被填满。如果当前写入 log buffer 的redo 日志量已经占满了 log buffer 总容量的大约一半左右,就需要把这些日志刷新到磁盘上。

  • 事务提交时

在事务提交时,为了保证持久性,会把log buffer中的日志全部刷到磁盘。注意,这时候,除了本事务的,可能还会刷入其它事务的日志。

  • 后台线程输入

有一个后台线程,大约每秒都会刷新一次log buffer中的redo log到磁盘。

  • 正常关闭服务器时
  • 触发checkpoint规则

重做日志缓存、重做日志文件都是以块(block) 的方式进行保存的,称之为重做日志块(redo log block) ,块的大小是固定的512字节。我们的redo log它是固定大小的,可以看作是一个逻辑上的 log group,由一定数量的log block 组成。

1MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!

它的写入方式是从头到尾开始写,写到末尾又回到开头循环写。

其中有两个标记位置:

write pos是当前记录的位置,一边写一边后移,写到第3号文件末尾后就回到0号文件开头。checkpoint是当前要擦除的位置,也是往后推移并且循环的,擦除记录前要把记录更新到磁盘。

1MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!

write_pos追上checkpoint时,表示redo log日志已经写满。这时候就不能接着往里写数据了,需要执行checkpoint规则腾出可写空间。

所谓的checkpoint规则,就是checkpoint触发后,将buffer中日志页都刷到磁盘。

SQL 优化

24.慢SQL如何定位呢?

慢SQL的监控主要通过两个途径:

MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!

  • 慢查询日志:开启MySQL的慢查询日志,再通过一些工具比如mysqldumpslow去分析对应的慢查询日志,当然现在一般的云厂商都提供了可视化的平台。
  • 服务监控:可以在业务的基建中加入对慢SQL的监控,常见的方案有字节码插桩、连接池扩展、ORM框架过程,对服务运行中的慢SQL进行监控和告警。

25.有哪些方式优化慢SQL?

慢SQL的优化,主要从两个方面考虑,SQL语句本身的优化,以及数据库设计的优化。

1MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!

避免不必要的列

这个是老生常谈,但还是经常会出的情况,SQL查询的时候,应该只查询需要的列,而不要包含额外的列,像slect * 这种写法应该尽量避免。

分页优化

在数据量比较大,分页比较深的情况下,需要考虑分页的优化。

例如:

select * from table where type = 2 and level = 9 order by id asc limit 190289,10;

优化方案:

  • 延迟关联

    先通过where条件提取出主键,在将该表与原数据表关联,通过主键id提取数据行,而不是通过原来的二级索引提取数据行

    例如:

    select a.* from table a, 
     (select id from table where type = 2 and level = 9 order by id asc limit 190289,10 ) b
     where a.id = b.id
  • 书签方式

    书签方式就是找到limit第一个参数对应的主键值,根据这个主键值再去过滤并limit

    例如:

  select * from table where id >
  (select * from table where type = 2 and level = 9 order by id asc limit 190
索引优化

合理地设计和使用索引,是优化慢SQL的利器。

利用覆盖索引

InnoDB使用非主键索引查询数据时会回表,但是如果索引的叶节点中已经包含要查询的字段,那它没有必要再回表查询了,这就叫覆盖索引

例如对于如下查询:

select name from test where city='上海'

我们将被查询的字段建立到联合索引中,这样查询结果就可以直接从索引中获取

alter table test add index idx_city_name (city, name);

低版本避免使用or查询

在 MySQL 5.0 之前的版本要尽量避免使用 or 查询,可以使用 union 或者子查询来替代,因为早期的 MySQL 版本使用 or 查询可能会导致索引失效,高版本引入了索引合并,解决了这个问题。

避免使用 != 或者 操作符

SQL中,不等于操作符会导致查询引擎放弃查询索引,引起全表扫描,即使比较的字段上有索引

解决方法:通过把不等于操作符改成or,可以使用索引,避免全表扫描

例如,把column’aaa’,改成column>’aaa’ or column,就可以使用索引了

适当使用前缀索引

适当地使用前缀所云,可以降低索引的空间占用,提高索引的查询效率。

比如,邮箱的后缀都是固定的“@xxx.com”,那么类似这种后面几位为固定值的字段就非常适合定义为前缀索引

alter table test add index index2(email(6));

PS:需要注意的是,前缀索引也存在缺点,MySQL无法利用前缀索引做order by和group by 操作,也无法作为覆盖索引

避免列上函数运算

要避免在列字段上进行算术运算或其他表达式运算,否则可能会导致存储引擎无法正确使用索引,从而影响了查询的效率

select * from test where id + 1 = 50;
select * from test where month(updateTime) = 7;

正确使用联合索引

使用联合索引的时候,注意最左匹配原则。

JOIN优化

优化子查询

尽量使用 Join 语句来替代子查询,因为子查询是嵌套查询,而嵌套查询会新创建一张临时表,而临时表的创建与销毁会占用一定的系统资源以及花费一定的时间,同时对于返回结果集比较大的子查询,其对查询性能的影响更大

小表驱动大表

关联查询的时候要拿小表去驱动大表,因为关联的时候,MySQL内部会遍历驱动表,再去连接被驱动表。

比如left join,左表就是驱动表,A表小于B表,建立连接的次数就少,查询速度就被加快了。

 select name from A left join B ;

适当增加冗余字段

增加冗余字段可以减少大量的连表查询,因为多张表的连表查询性能很低,所有可以适当的增加冗余字段,以减少多张表的关联查询,这是以空间换时间的优化策略

避免使用JOIN关联太多的表

《阿里巴巴Java开发手册》规定不要join超过三张表,第一join太多降低查询的速度,第二join的buffer会占用更多的内存。

如果不可避免要join多张表,可以考虑使用数据异构的方式异构到ES中查询。

排序优化

利用索引扫描做排序

MySQL有两种方式生成有序结果:其一是对结果集进行排序的操作,其二是按照索引顺序扫描得出的结果自然是有序的

但是如果索引不能覆盖查询所需列,就不得不每扫描一条记录回表查询一次,这个读操作是随机IO,通常会比顺序全表扫描还慢

因此,在设计索引时,尽可能使用同一个索引既满足排序又用于查找行

例如:

--建立索引(date,staff_id,customer_id)
select staff_id, customer_id from test where date = '2010-01-01' order by staff_id,customer_id;

只有当索引的列顺序和ORDER BY子句的顺序完全一致,并且所有列的排序方向都一样时,才能够使用索引来对结果做排序

UNION优化

条件下推

MySQL处理union的策略是先创建临时表,然后将各个查询结果填充到临时表中最后再来做查询,很多优化策略在union查询中都会失效,因为它无法利用索引

最好手工将where、limit等子句下推到union的各个子查询中,以便优化器可以充分利用这些条件进行优化

此外,除非确实需要服务器去重,一定要使用union all,如果不加all关键字,MySQL会给临时表加上distinct选项,这会导致对整个临时表做唯一性检查,代价很高。

26.怎么看执行计划(explain),如何理解其中各个字段的含义?

explain是sql优化的利器,除了优化慢sql,平时的sql编写,也应该先explain,查看一下执行计划,看看是否还有优化的空间。

直接在 select 语句之前增加explain关键字,就会返回执行计划的信息。

MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!

2MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!

  1. id 열: MySQL은 각 select 문에 고유한 ID 값을 할당합니다.

  2. select_type 열, 쿼리 유형, 연관, 통합, 하위 쿼리 등에 따라 분류됩니다. 일반적인 쿼리 유형은 SIMPLE, PRIMARY입니다.

  3. table 열: explain 행이 액세스하는 테이블을 나타냅니다.

  4. type 컬럼: 가장 중요한 컬럼 중 하나입니다. MySQL이 테이블에서 행을 찾는 방법을 결정하는 연결 유형 또는 액세스 유형을 나타냅니다.

    성능은 다음과 같습니다: system > const > eq_ref > fulltext > ref_or_null > index_subquery > index > system: 테이블에 레코드 행이 하나만 있는 경우(시스템 테이블) 데이터의 양이 매우 적고 디스크 IO가 필요하지 않은 경우가 많으며 속도가 매우 빠릅니다

    • const

      const : 쿼리가 기본 키 기본 키 또는 고유 고유 인덱스에 도달했거나 연결된 부분이 상수(const) 값 . 이러한 유형의 검색은 매우 효율적이고 소량의 데이터를 반환하며 매우 빠릅니다. system: 当表仅有一行记录时(系统表),数据量很少,往往不需要进行磁盘IO,速度非常快

    • const

      const:表示查询时命中 primary key 主键或者 unique 唯一索引,或者被连接的部分是一个常量(const)值。这类扫描效率极高,返回数据量少,速度非常快。

    • eq_ref

      eq_ref:查询时命中主键primary key 或者 unique key索引, type 就是 eq_ref

    • ref_or_null

      ref_or_null:这种连接类型类似于 ref,区别在于 MySQL会额外搜索包含NULL值的行。

    • index_merge

      index_merge:使用了索引合并优化方法,查询使用了两个以上的索引。

    • unique_subquery

      unique_subquery:替换下面的 IN子查询,子查询返回不重复的集合。

    • index_subquery

      index_subquery:区别于unique_subquery,用于非唯一索引,可以返回重复值。

    • range

      range:使用索引选择行,仅检索给定范围内的行。简单点说就是针对一个有索引的字段,给定范围检索数据。在where语句中使用 bettween...and、<code>>、<code>in 等条件查询 type 都是 range

    • index

      indexIndexALL 其实都是读全表,区别在于index是遍历索引树读取,而ALL

    • eq_ref

      eq_ref: 쿼리 중에 기본 키 기본 키 또는 고유 키 인덱스를 적중하고 입력eq_ref입니다.

    ref_or_null
  5. ref_or_null: 이 조인 유형은 MySQLNULL 값이 포함된 행을 추가로 검색한다는 점을 제외하면 ref와 유사합니다.

    index_merge
  6. index_merge: 인덱스 병합 최적화 방법이 사용되며 쿼리는 2개 이상의 인덱스를 사용합니다.

    unique_subquery
  7. unique_subquery: 다음 IN 하위 쿼리를 바꾸면 하위 쿼리가 고유한 집합을 반환합니다.

    index_subquery
  8. index_subquery: unique_subquery와는 달리 고유하지 않은 인덱스에 사용되며 중복된 값을 반환할 수 있습니다.

    range
  9. 범위: 인덱스를 사용하여 행을 선택하고 지정된 범위 내의 행만 검색합니다. 간단히 말하면 인덱스된 필드에 대해 지정된 범위 내의 데이터를 검색하는 것입니다. where 문에 between...and, , <code>>, , <code>in 및 기타 조건부 쿼리 type은 모두 범위입니다.

    index
  10. index: IndexALL는 실제로 전체 테이블을 읽습니다. 차이점은 index입니다. ALL은 하드 디스크에서 읽는 반면 인덱스 트리를 순회하여 읽습니다.

    ALL
말할 필요도 없이 전체 테이블 스캔입니다.
  • possible_keys
열: 쿼리가 찾는 데 사용할 수 있는 인덱스를 표시합니다. 이는 인덱스를 사용하여 SQL을 최적화할 때 더 중요합니다.

key

열: 이 열은 mysql이 테이블에 대한 액세스를 최적화하기 위해 실제로 사용하는 인덱스를 보여주며 일반적으로 인덱스가 유효하지 않은지 확인하는 데 사용됩니다.

2MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!

key_len

열: MySQL의 사용법을 표시합니다.

  • ref
  • 열: ref 열은 인덱스 열에 해당하는 값을 표시합니다. 일반적인 항목은 const(상수), func, NULL, 필드 이름.
rows

열: 이 필드도 통계 정보를 기반으로 MySQL 쿼리 최적화 프로그램은 SQL이 결과 집합을 찾기 위해 스캔하고 읽어야 하는 데이터 행 수를 추정합니다. SQL의 효율성은 원칙적으로 행이 적을수록 좋습니다.

🎜🎜Extra🎜 열: 다른 열에 맞지 않는 추가 정보를 표시하지만 추가라고 하지만 몇 가지 중요한 정보도 있습니다. 🎜🎜🎜🎜🎜인덱스 사용: MySQL이 포함 인덱스를 사용함을 나타냅니다. 피하기 테이블 백🎜 🎜Using where: 스토리지 엔진을 검색한 후 필터링이 수행됨을 나타냅니다. 🎜🎜Using temporary: 쿼리 결과를 정렬할 때 임시 테이블이 사용됨을 나타냅니다. 🎜🎜🎜Index🎜🎜MySQL 면접에서는 인덱스가 1순위라고 할 수 있고, 철저하게 승리해야 합니다. 🎜🎜27. 지수 분류에 대해 간략하게 설명해주실 수 있나요? 🎜🎜세 가지 다른 차원의 인덱스 분류: 🎜🎜🎜🎜🎜예를 들어 기본 사용법의 관점에서: 🎜🎜🎜기본 키 인덱스: InnoDB 기본 키가 기본 인덱스이며 데이터 열은 반복 또는 NULL이 허용되지 않습니다. . 테이블에는 기본 키가 하나만 있을 수 있습니다. 🎜🎜고유 인덱스: 데이터 열의 중복은 허용되지 않으며, NULL 값이 허용되며, 테이블에서는 여러 열이 고유 인덱스를 생성할 수 있습니다. 🎜🎜일반 인덱스: 기본 인덱스 유형, 고유성 제한 없음, NULL 값 허용. 🎜🎜결합 인덱스: 여러 열 값이 결합 검색을 위한 인덱스를 형성하는데, 이는 인덱스 병합보다 효율적입니다🎜🎜🎜28. 인덱스를 사용하면 쿼리 속도가 빨라지는 이유는 무엇입니까? 🎜🎜기존 쿼리 방법은 테이블을 순서대로 순회합니다. 쿼리되는 데이터의 양에 관계없이 MySQL은 테이블 데이터를 처음부터 끝까지 순회해야 합니다. 🎜

인덱스를 추가한 후 MySQL은 일반적으로 BTREE 알고리즘을 통해 인덱스 파일을 생성합니다. 데이터베이스를 쿼리할 때 인덱스 파일을 찾아 탐색하고 비교적 작은 인덱스 데이터를 검색한 다음 해당 데이터에 매핑할 수 있습니다. 검색 효율성이 크게 향상됩니다.

책의 목차를 통해 해당 내용을 찾아볼 때와 동일합니다.

2MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!

29. 인덱스 생성 시 주의할 점은 무엇인가요?

인덱스는 SQL 성능 최적화를 위한 강력한 도구이지만 인덱스 유지 관리에는 비용도 필요하므로 인덱스를 생성할 때는 다음 사항에도 주의해야 합니다.

  • 인덱스는 쿼리 응용 프로그램에서 자주 사용되는 필드에 구축되어야 합니다

    어디에서 판단하고 순서를 정하는데 사용됩니다. 정렬의 (on) 필드에 인덱스를 생성하고 조인합니다.

  • 인덱스 수는 적절해야 합니다.

    인덱스는 공간을 차지해야 하며 업데이트 중에도 유지 관리되어야 합니다.

  • 성별 등 차별화가 낮은 분야에 대해서는 인덱스를 구축하지 마세요.

    분포도가 너무 낮은 필드의 경우 스캔되는 행 수가 제한됩니다.

  • 자주 업데이트되는 값을 기본 키나 인덱스로 사용하지 마세요.

    인덱스 파일을 유지하는 데 비용이 들며 페이지 분할 및 IO 시간 증가로 이어질 수도 있습니다.

  • 결합 인덱스는 해싱(고분별)이 높은 값을 앞에 배치합니다

    가장 왼쪽 접두사 일치 원칙을 충족하기 위해

  • 단일 열 인덱스를 수정하는 대신 결합 인덱스를 생성합니다.

    결합 인덱스는 여러 단일 열 인덱스를 대체합니다. (단일 열 인덱스의 경우 MySQL은 기본적으로 하나의 인덱스만 사용할 수 있으므로 여러 조건으로 쿼리할 때는 결합 인덱스를 사용하는 것이 더 적합합니다.)

  • 필드가 너무 긴 경우 , 접두사 색인을 사용하십시오. 필드 값이 상대적으로 길면 인덱싱이 많은 공간을 소비하고 검색 속도가 매우 느려집니다. 접두사 인덱스라고 하는 필드의 이전 부분을 가로채서 인덱스를 만들 수 있습니다.

  • 순서가 지정되지 않은 값(예: ID 카드, UUID)을 인덱스로 사용하는 것은 권장하지 않습니다.

    기본 키가 확실하지 않으면 리프 노드가 자주 분할되고 디스크 저장소가 조각화됩니다

30. 인덱스는 어떤 경우에 실패합니까?

  • 쿼리 조건에 or가 포함되어 있어 인덱스 오류가 발생할 수 있습니다.
  • 필드 유형이 문자열인 경우 위치를 따옴표로 묶어야 합니다. 그렇지 않으면 암시적 유형 변환으로 인해 인덱스가 유효하지 않게 됩니다.
  • 와일드카드를 사용하면 인덱스가 발생할 수 있습니다. 실패.
  • 조인트 인덱스, 쿼리 시 조건 열이 조인 인덱스의 첫 번째 열이 아니고 인덱스가 무효화됩니다.
  • 인덱스 열에 mysql의 내장 함수를 사용하면 인덱스가 무효화됩니다.
  • 인덱싱된 열(예: +, -, *, /)에 대해 작업을 수행하면 인덱스가 유효하지 않게 됩니다.
  • 인덱스 필드에 (!= 또는 , not in)을 사용하면 인덱스 오류가 발생할 수 있습니다.
  • 인덱스 필드에 is null 또는 is not null을 사용하면 인덱스 오류가 발생할 수 있습니다.
  • 왼쪽 조인 쿼리 또는 오른쪽 조인 쿼리와 연결된 필드의 인코딩 형식이 다르기 때문에 인덱스 오류가 발생할 수 있습니다.
  • MySQL 옵티마이저는 전체 테이블 스캔을 사용하는 것이 인덱스를 사용하는 것보다 빠르다고 추정하므로 인덱스는 사용되지 않습니다.

31. 인덱스는 어떤 상황에 적합하지 않나요?

  • 데이터의 양이 상대적으로 적은 테이블은 인덱싱에 적합하지 않습니다.
  • 자주 업데이트되는 필드는 인덱싱에 적합하지 않습니다.
  • 분산성이 낮은 필드(예: 성별)는 인덱싱에 적합하지 않습니다

32. 지수가 너무 높을수록 좋은가요?

당연하지.

  • 인덱스는 디스크 공간을 차지합니다
  • 인덱스는 쿼리 효율성을 향상시키지만 테이블 업데이트 효율성을 떨어뜨립니다. 예를 들어, 테이블이 추가, 삭제, 수정될 때마다 MySQL은 데이터를 저장할 뿐만 아니라 해당 인덱스 파일을 저장하거나 업데이트해야 합니다.

33.MySQL 인덱스가 어떤 데이터 구조를 사용하는지 아시나요?

MySQL의 기본 스토리지 엔진은 B+ 트리 구조 인덱스를 사용하는 InnoDB입니다.

  • B+ 트리: 리프 노드만 데이터를 저장하고 리프가 아닌 노드는 키 값만 저장합니다. 리프 노드는 양방향 포인터를 사용하여 연결되며, 가장 낮은 리프 노드는 양방향 순서 연결 목록을 형성합니다.

2MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!

이 사진에는 두 가지 중요한 점이 있습니다.

  • 가장 바깥쪽 블록을 디스크 블록이라고 부릅니다. 각 디스크 블록에는 여러 데이터 항목(분홍색으로 표시)과 포인터(노란색/회색으로 표시)가 포함되어 있습니다. 예를 들어 루트 노드 디스크에는 데이터 항목 17이 포함되어 있습니다. 35에는 포인터 P1, P2 및 P3이 포함되어 있습니다. P1은 17보다 작은 디스크 블록을 나타내고, P2는 17과 35 사이의 디스크 블록을 나타내며, P3은 35보다 큰 디스크 블록을 나타냅니다. 실제 데이터는 리프 노드, 즉 3, 4, 5..., 65에 존재합니다. Non-leaf 노드는 실제 데이터를 저장하지 않고 검색 방향을 안내하는 데이터 항목만 저장합니다. 예를 들어 17과 35는 실제로 데이터 테이블에 존재하지 않습니다.
  • 리프 노드는 양방향 포인터를 사용하여 연결됩니다. 가장 낮은 리프 노드는 범위 쿼리가 가능한 양방향 순서 연결 목록을 형성합니다.

34. B+ 트리에는 몇 개의 데이터가 저장될 수 있나요?

2MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!

인덱스 필드가 bigint 유형이고 길이가 8바이트라고 가정합니다. InnoDB 소스 코드에서는 포인터 크기가 6바이트로 설정되어 총 14바이트가 됩니다. 비리프 노드(1페이지)는 이러한 단위(키 값 + 포인터)를 16384/14=1170개 저장할 수 있으며 이는 1170개의 포인터가 있음을 의미합니다.

트리 깊이가 2일 때 리프 노드는 1170^2개이고, 저장할 수 있는 데이터는 1170117016=21902400입니다.

데이터 검색 시 1페이지 검색은 1개의 IO를 의미합니다. 즉, 약 2천만 개의 테이블의 경우 데이터를 쿼리하려면 최대 3번의 디스크 액세스가 필요합니다.

따라서 InnoDB의 B+ 트리 깊이는 일반적으로 1~3개 레이어로 수천만 개의 데이터 저장 공간을 만족할 수 있습니다.

35. 왜 일반 이진 트리 대신 B+ 트리를 사용하나요?

이 문제는 쿼리가 충분히 빠른지, 효율성이 안정적인지, 저장된 데이터의 양, 디스크 검색 횟수 등 여러 차원에서 살펴볼 수 있습니다.

일반 이진 트리를 사용하면 어떨까요?

일반적인 이진 트리가 연결리스트로 퇴화되면 전체 테이블 스캔과 동일합니다. 이진 검색 트리와 비교하여 균형 이진 트리는 검색 효율성이 더 안정적이고 전체 검색 속도가 더 빠릅니다.

이진 트리의 균형을 맞추는 것이 어떨까요?

데이터를 읽을 때는 디스크에서 메모리로 읽혀집니다. 트리와 같은 데이터 구조를 인덱스로 사용하면 데이터를 검색할 때마다 디스크 블록인 디스크에서 노드를 읽어야 하는데, 균형 이진 트리는 노드당 하나의 키 값과 데이터만 저장한다. B+ 트리라면 더 많은 노드 데이터를 저장할 수 있고, 트리 높이도 줄어들므로 디스크 읽기 횟수가 줄어들고 쿼리 효율성이 빨라집니다.

36. 왜 B 트리 대신 B+ 트리를 사용하나요?

B+는 B-tree에 비해 다음과 같은 장점이 있습니다.

  • B-Tree의 변형으로 B-Tree가 해결할 수 있는 모든 문제를 해결할 수 있습니다.

    B 트리가 해결한 두 가지 주요 문제: 각 노드는 더 많은 키워드를 저장하고 더 많은 경로를 저장합니다.

  • 더 강력한 데이터베이스 및 테이블 검색 기능

    테이블에서 전체 테이블 검색을 수행하려면 리프 노드만 순회하면 됩니다. 충분하므로 모든 데이터를 얻기 위해 전체 B+Tree를 탐색할 필요가 없습니다.

  • B+Tree는 B Tree보다 디스크 읽기 및 쓰기 기능이 강력하고 IO 횟수도 적습니다.

    루트 노드와 분기 노드는 데이터 영역을 저장하지 않으므로 한 노드에서 더 많은 키워드를 저장하고 디스크를 한 번에 로드할 수 있습니다. time 키워드는 더 많고 IO 횟수는 더 적습니다.

  • 더 강력한 정렬 기능

    리프 노드에는 다음 데이터 영역에 대한 포인터가 있으므로 데이터는 연결 목록을 형성합니다.

  • 효율이 더 안정적입니다

    B+Tree는 항상 리프 노드에서 데이터를 가져오므로 IO 수가 안정적입니다.

37. 해시 인덱스와 B+ 트리 인덱스의 차이점은 무엇인가요?

  • B+ 트리는 범위 쿼리를 수행할 수 있지만 해시 인덱스는 수행할 수 없습니다.
  • B+ 트리는 가장 왼쪽의 조인트 인덱스 원칙을 지원하지만, 해시 인덱스는 이를 지원하지 않습니다.
  • B+ 트리는 정렬을 통한 순서를 지원하지만 해시 인덱스는 지원하지 않습니다.
  • 해시 인덱스는 동등한 쿼리에서 B+ 트리보다 더 효율적입니다.
  • B+ 트리가 퍼지 쿼리에 like를 사용하는 경우 like 뒤의 단어(%로 시작하는 등)가 최적화 역할을 할 수 있으며 해시 인덱스는 퍼지 쿼리를 전혀 수행할 수 없습니다.

38. 클러스터형 인덱스와 비클러스터형 인덱스의 차이점은 무엇인가요?

먼저 클러스터형 인덱스는 새로운 인덱스가 아니라 데이터 저장 방식이라는 점을 이해하세요. 클러스터링은 데이터 행과 인접한 키 값이 함께 콤팩트하게 저장되는 것을 의미합니다. 우리에게 익숙한 두 가지 스토리지 엔진인 MyISAM은 비클러스터형 인덱스를 사용하고 InnoDB는 클러스터형 인덱스를 사용합니다.

다음과 같이 말할 수 있습니다.

  • 인덱스의 데이터 구조는 트리에 저장됩니다. 비클러스터형 인덱스는 동일한 트리에 없습니다.

2MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!

  • 一个表中只能拥有一个聚簇索引,而非聚簇索引一个表可以存在多个。
  • 聚簇索引,索引中键值的逻辑顺序决定了表中相应行的物理顺序;索引,索引中索引的逻辑顺序与磁盘上行的物理存储顺序不同。
  • 聚簇索引:物理存储按照索引排序;非聚集索引:物理存储不按照索引排序;

39.回表了解吗?

在InnoDB存储引擎里,利用辅助索引查询,先通过辅助索引找到主键索引的键值,再通过主键值查出主键索引里面没有符合要求的数据,它比基于主键索引的查询多扫描了一棵索引树,这个过程就叫回表。

例如:select * from user where name = ‘张三’;

2MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!

40.覆盖索引了解吗?

在辅助索引里面,不管是单列索引还是联合索引,如果 select 的数据列只用辅助索引中就能够取得,不用去查主键索引,这时候使用的索引就叫做覆盖索引,避免了回表。

比如,select name from user where name = ‘张三’;

MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!

41.什么是最左前缀原则/最左匹配原则?

注意:最左前缀原则、最左匹配原则、最左前缀匹配原则这三个都是一个概念。

最左匹配原则:在InnoDB的联合索引中,查询的时候只有匹配了前一个/左边的值之后,才能匹配下一个。

根据最左匹配原则,我们创建了一个组合索引,如 (a1,a2,a3),相当于创建了(a1)、(a1,a2)和 (a1,a2,a3) 三个索引。

为什么不从最左开始查,就无法匹配呢?

比如有一个user表,我们给 name 和 age 建立了一个组合索引。

ALTER TABLE user add INDEX comidx_name_phone (name,age);

组合索引在 B+Tree 中是复合的数据结构,它是按照从左到右的顺序来建立搜索树的 (name 在左边,age 在右边)。

2MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!

从这张图可以看出来,name 是有序的,age 是无序的。当 name 相等的时候, age 才是有序的。

这个时候我们使用where name= ‘张三‘ and age = ‘20 ‘去查询数据的时候, B+Tree 会优先比较 name 来确定下一步应该搜索的方向,往左还是往右。如果 name 相同的时候再比较age。但是如果查询条件没有 name,就不知道下一步应该查哪个 节点,因为建立搜索树的时候 name 是第一个比较因子,所以就没用上索引。

42.什么是索引下推优化?

索引条件下推优化(Index Condition Pushdown (ICP) )是MySQL5.6添加的,用于优化数据查询。

  • 不使用索引条件下推优化时存储引擎通过索引检索到数据,然后返回给MySQL Server,MySQL Server进行过滤条件的判断。
  • 当使用索引条件下推优化时,如果存在某些被索引的列的判断条件时,MySQL Server将这一部分判断条件下推给存储引擎,然后由存储引擎通过判断索引是否符合MySQL Server传递的条件,只有当索引符合条件时才会将数据检索出来返回给MySQL服务器。

例如一张表,建了一个联合索引(name, age),查询语句:select * from t_user where name like '张%' and age=10;,由于name使用了范围查询,根据最左匹配原则:

不使用ICP,引擎层查找到name like '张%'的数据,再由Server层去过滤age=10这个条件,这样一来,就回表了两次,浪费了联合索引的另外一个字段age

MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!

但是,使用了索引下推优化,把where的条件放到了引擎层执行,直接根据name like '张%' and age=10的条件进行过滤,减少了回表的次数。

3MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!

索引条件下推优化可以减少存储引擎查询基础表的次数,也可以减少MySQL服务器从存储引擎接收数据的次数。

43.MySQL中有哪几种锁,列举一下?

3MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!

如果按锁粒度划分,有以下3种:

  • 테이블 잠금: 낮은 오버헤드, 빠른 잠금, 높은 잠금 강도, 높은 잠금 충돌 가능성, 가장 낮은 동시성.
  • 행 잠금: 높은 오버헤드, 느린 잠금, 작은 잠금 세분성, 낮은 잠금 충돌 가능성 및 높은 동시성이 발생할 수 있습니다.
  • 페이지 잠금: 오버헤드와 잠금 속도는 테이블 잠금과 행 잠금 사이에 있습니다. 잠금 세분성은 테이블 잠금과 행 잠금 사이에 있으며 동시성은 평균입니다.

호환성에 따라 두 가지 유형이 있습니다. ,

  • 읽기 잠금(read lock)이라고도 불리는 공유 잠금(S Lock)은 서로를 차단하지 않습니다.
  • 배타적 잠금(X Lock), 쓰기 잠금(write lock)이라고도 불리는 배타적 잠금은 특정 기간 내에 단 하나의 요청만 쓰기를 수행할 수 있으며 다른 잠금이 쓰기 중인 데이터를 읽는 것을 방지합니다.

44 InnoDB의 행 잠금 구현에 대해 이야기해 보세요.

우리는 이러한 사용자 테이블을 사용하여 4개의 데이터 행이 삽입되고 기본 키 값은 1, 6, 8, 12. 이제 단순화하십시오. 클러스터형 인덱스 구조는 데이터 레코드만 유지합니다.

3MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!

InnoDB 행 잠금의 주요 구현은 다음과 같습니다.

  • 레코드 잠금 레코드 잠금

레코드 잠금은 행 레코드를 직접 잠그는 것입니다. 동일한 쿼리를 수행하고 레코드와 정확하게 일치하기 위해 고유 인덱스(고유 인덱스 및 클러스터형 인덱스 포함)를 사용하면 레코드가 직접 잠깁니다. 예를 들어, select * from t where id =6 for update;id=6의 기록을 잠급니다. select * from t where id =6 for update;就会将id=6的记录锁定。

3MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!

  • Gap Lock 间隙锁

间隙锁(Gap Locks) 的间隙指的是两个记录之间逻辑上尚未填入数据的部分,是一个左开右开空间

3MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!

间隙锁就是锁定某些间隙区间的。当我们使用用等值查询或者范围查询,并且没有命中任何一个record,此时就会将对应的间隙区间锁定。例如select * from t where id =3 for update;或者select * from t where id > 1 and id 就会将(1,6)区间锁定。

  • Next-key Lock 临键锁

临键指的是间隙加上它右边的记录组成的左开右闭区间。比如上述的(1,6]、(6,8]等。

3MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!

临键锁就是记录锁(Record Locks)和间隙锁(Gap Locks)的结合,即除了锁住记录本身,还要再锁住索引之间的间隙。当我们使用范围查询,并且命中了部分record记录,此时锁住的就是临键区间。注意,临键锁锁住的区间会包含最后一个record的右边的临键区间。例如select * from t where id > 5 and id 会锁住(4,7]、(7,+∞)。mysql默认行锁类型就是<code>临键锁(Next-Key Locks)。当使用唯一性索引,等值查询匹配到一条记录的时候,临键锁(Next-Key Locks)会退化成记录锁;没有匹配到任何记录的时候,退化成间隙锁。

间隙锁(Gap Locks)临键锁(Next-Key Locks)都是用来解决幻读问题的,在已提交读(READ COMMITTED)隔离级别下,间隙锁(Gap Locks)临键锁(Next-Key Locks)

3MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!

    Gap Lock Gap Lock
  • Gap Locks의 간격은 아직 데이터가 채워지지 않은 두 레코드 사이의 논리적 부분을 의미하며
왼쪽으로 열린 공간

입니다.

3MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!

Gap 잠금은 특정 간격 간격을 잠그는 것입니다. 동일 쿼리 또는 범위 쿼리를 사용하고 기록에 도달하지 않으면 해당 간격 간격이 잠깁니다. 예를 들어, select * from t where id =3 for update; 또는 select * from t where id > 1 and id &lt 6 for update;는 (1 , 6) 간격 잠금. 3MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!

다음 키 잠금

다음 키는 공백과 오른쪽 레코드로 구성된 🎜왼쪽 열림 및 오른쪽 닫힘 간격🎜을 의미합니다. 예를 들어 위의 (1,6], (6,8] 등 🎜🎜3MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!🎜🎜프로키 잠금은 레코드 잠금(Record Locks)과 갭 잠금(Gap Locks)을 조합한 것으로, 즉 레코드 자체를 잠그는 것 외에 , 간격 사이의 인덱스도 잠급니다. 범위 쿼리를 사용하고 record 레코드의 일부를 적중하면 잠긴 것은 임시 키 잠금으로 잠긴 간격에 포함됩니다. 예를 들어, select * from t where id > id 는 (4,7], (7, +) MySQL 기본 행 잠금 유형은 <code>Next-Key Locks입니다. 고유 인덱스가 사용되고 동일한 값 쿼리가 레코드와 일치하면 Next-Key 잠금이 레코드 잠금으로 변질됩니다. 레코드가 일치하면 갭 잠금으로 변질됩니다. 🎜
🎜Gap LocksNext-Key Locks는 모두 READ COMMITTED 격리 수준, Gap LocksNext-Key Locks)는 유효하지 않습니다. 🎜🎜🎜위는 행 잠금의 세 가지 구현 알고리즘입니다. 또한 행에 삽입 의도 잠금도 있습니다. 🎜🎜🎜🎜Insert Intention Lock🎜🎜🎜 🎜트랜잭션이 레코드를 삽입할 때 삽입 위치가 다른 트랜잭션에 의해 잠겨 있는지 확인해야 합니다. 작업은 갭 잠금을 보유한 트랜잭션이 커밋될 때까지 기다려야 합니다. 그러나 트랜잭션도 기다리는 동안 기다려야 합니다. 트랜잭션이 특정 갭에 새 레코드를 삽입하려고 함을 나타내는 잠금 구조가 생성되어야 합니다. 이 유형의 잠금은 의도 잠금(Intention Lock)이라고 합니다. 즉, T1 트랜잭션이 (1,6) 간격에 의도 잠금을 추가합니다. (1,6) 간격 동안 삽입 의도 잠금을 획득하고 ID 3의 데이터 조각을 삽입하려는 또 다른 T3 트랜잭션이 있습니다. 또한 삽입 의도를 획득합니다. (1,6) 범위의 잠금입니다. 그러나 두 삽입 의도 잠금은 상호 배타적이지 않습니다. 🎜🎜🎜🎜🎜45. 의도 잠금이 무엇인지 아시나요? 🎜🎜의도 잠금은 테이블 수준 잠금이므로 삽입 의도 잠금과 혼동하지 마세요. 🎜🎜Intention 잠금은 InnoDB의 다중 세분성 잠금을 지원하는 것으로 나타납니다. 이는 테이블 잠금과 행 잠금의 공존 문제를 해결합니다. 🎜

테이블에 테이블 잠금을 추가해야 할 경우 테이블에 잠긴 데이터 행이 있는지 판단하여 추가가 성공할 수 있는지 판단해야 합니다.

의도 잠금이 없으면 테이블의 모든 데이터 행을 순회하여 행 잠금이 있는지 확인해야 합니다.

테이블 수준 잠금인 의도 잠금을 사용하면 한 번만 직접 판단할 수 있습니다. 테이블의 데이터 행이 잠겨 있는지 여부.

의도 잠금을 사용하면 실행될 트랜잭션 A가 행 잠금(쓰기 잠금)을 적용하기 전에 데이터베이스가 자동으로 트랜잭션 A의 테이블에 의도 배타적 잠금을 적용합니다. 트랜잭션 B가 테이블에 뮤텍스 잠금을 적용하면 테이블에 의도적인 배타적 잠금이 있으므로 실패하게 되며, 테이블에 뮤텍스 잠금을 적용하면 트랜잭션 B가 차단됩니다.

MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!

46. MySQL의 낙관적 잠금과 비관적 잠금을 이해하시나요?

  • 비관적 동시성 제어:

비관적 잠금은 트랜잭션이 비관적 잠금을 획득한 후에는 보호되는 데이터가 매우 안전하지 않으며 언제든지 변경될 수 있다고 믿습니다. 다른 트랜잭션은 데이터를 수정할 수 없으며 데이터 수정만 가능합니다. 실행하기 전에 잠금이 해제될 때까지 기다립니다.

데이터베이스의 행 잠금, 테이블 잠금, 읽기 잠금 및 쓰기 잠금은 모두 비관적 잠금입니다.

  • Optimistic Concurrency Control

Optimistic Lock은 데이터가 너무 자주 변경되지 않을 것이라고 믿습니다.

낙관적 잠금은 일반적으로 테이블에 버전(version) 또는 타임스탬프(timestamp)를 추가하여 구현되며, 그 중 버전이 가장 일반적으로 사용됩니다.

트랜잭션이 데이터베이스에서 데이터를 가져올 때 데이터 버전(v1)도 가져옵니다. 트랜잭션이 데이터 변경을 완료하고 이를 테이블에 업데이트하려고 하면 이전에 가져온 버전 v1이 추가됩니다. 최신 버전 v2와 비교하여 v1=v2이면 데이터 변경 기간 동안 다른 트랜잭션이 데이터를 수정할 수 없음을 의미합니다. 이 시점에서 트랜잭션은 테이블의 데이터와 버전을 수정할 수 있습니다. 수정하는 동안 1씩 증가합니다. 이는 데이터가 변경되었음을 나타냅니다.

v1이 v2와 같지 않으면 데이터 변경 기간 동안 다른 트랜잭션에 의해 데이터가 수정되었음을 의미합니다. 이때 데이터는 테이블에 업데이트될 수 없습니다. 그리고 다시 작동하게 해주세요. 비관적 잠금과 달리 낙관적 잠금은 일반적으로 개발자가 구현합니다.

47.MySQL에서 교착 상태 문제를 겪은 적이 있나요? 어떻게 해결하셨나요?

교착 상태를 해결하는 일반적인 단계는 다음과 같습니다.

(1) 교착 상태 로그에서 엔진 innodb 상태를 확인합니다.

(2) 교착 상태를 확인합니다. sql

(3) SQL 잠금 상황을 분석합니다

(4 ) 교착상태 시뮬레이션

(5) 교착상태 로그 분석

(6) 교착상태 결과 분석

물론 이는 단순한 프로세스 설명일 뿐입니다. 사실 프로덕션에서의 교착상태는 온갖 종류의 이상하고 그렇습니다. 문제를 해결하고 해결하는 것은 매우 간단합니다.

Transactions

48. MySQL 트랜잭션의 네 가지 주요 특징은 무엇입니까?

3MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!

  • 원자성: 트랜잭션은 전체적으로 실행되며, 트랜잭션에 포함된 데이터베이스의 모든 작업이 실행되거나 아무것도 실행되지 않습니다.
  • 일관성: 거래 시작 전과 거래 종료 후에도 데이터가 파기되지 않음을 의미합니다. A 계좌가 B 계좌로 10위안을 이체하면 A와 B의 총액은 성공 여부에 관계없이 변경되지 않습니다.
  • 격리: 여러 트랜잭션이 동시에 액세스할 때 트랜잭션은 서로 격리됩니다. 즉, 하나의 트랜잭션이 다른 트랜잭션의 실행 효과에 영향을 주지 않습니다. 한마디로 말하면, 일들 사이에 갈등이 없다는 뜻이다.
  • 지속성: 트랜잭션이 완료된 후 트랜잭션으로 인해 데이터베이스에 대한 작업 변경 사항이 데이터베이스에 영구적으로 저장됨을 나타냅니다.

49. ACID는 어떤 보장을 합니까?

  • 트랜잭션의 격리는 데이터베이스 잠금 메커니즘을 통해 달성됩니다.
  • 트랜잭션의 일관성은 실행 취소 로그에 의해 보장됩니다. 실행 취소 로그는 트랜잭션의 삽입, 업데이트 및 삭제 작업을 기록하는 논리적 로그입니다. 롤백 중에는 반대의 삭제, 업데이트 및 삽입 작업이 수행됩니다. 데이터를 복구하기 위해 수행되었습니다.
  • 트랜잭션의 원자성내구성은 리두 로그에 의해 보장됩니다. 리두 로그는 리두 로그라고 하며 트랜잭션이 제출되면 먼저 트랜잭션의 모든 로그가 리두 로그에 기록되어야 합니다. 지속성을 위해 트랜잭션은 커밋 작업까지 완료되지 않습니다.

MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!

50. 거래의 격리 수준은 무엇입니까? MySQL의 기본 격리 수준은 무엇입니까?

4MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!

  • 읽기 커밋됨
  • 읽기 커밋됨
  • 반복 읽기
  • 직렬화 가능

MySQL의 기본 트랜잭션 격리 수준은 반복 읽기입니다.

51.팬텀 읽기, 더티 읽기, 반복 불가능 읽기란 무엇인가요?

  • 트랜잭션 A와 B가 교대로 실행되며, 트랜잭션 A는 트랜잭션 B의 커밋되지 않은 데이터를 읽습니다. 이것이 dirty reading입니다.
  • 트랜잭션 범위 내에서 두 개의 동일한 쿼리가 동일한 레코드를 읽었지만 다른 데이터를 반환합니다. 이는 반복 불가능한 읽기입니다.
  • 트랜잭션 A는 범위의 결과 집합을 쿼리하고 다른 동시 트랜잭션 B는 이 범위에 데이터를 삽입/삭제하고 자동으로 커밋합니다. 그런 다음 트랜잭션 A가 동일한 범위를 다시 쿼리하고 두 번의 읽기로 얻은 결과 집합이 다릅니다. 마찬가지다, 이것이 환상독서이다.

다양한 격리 수준, 동시 트랜잭션에서 발생할 수 있는 문제:

주요 스토리지 엔진 및 기능은 다음과 같습니다.
아니요
No
격리 수준 Dirty read Non-repeatable read Phantom read
Read Uncommitted Read Com 읽기 커밋됨 is Serialzable Serialized
No No

52. 다양한 트랜잭션 격리 수준은 어떻게 구현되나요?

Read uncommitted

Read uncommitted는 말할 필요도 없이 잠금 없이 읽는 원칙을 채택합니다.

  • 트랜잭션 읽기는 잠기지 않으며 다른 트랜잭션의 읽기 및 쓰기를 차단하지 않습니다.
  • 트랜잭션 쓰기는 다른 트랜잭션의 쓰기를 차단하지만 다른 트랜잭션의 읽기는 차단하지 않습니다.

읽기는 커밋되고 반복 가능합니다. reading

Reading 커밋되고 반복 가능한 읽기 수준은 ReadViewMVCC를 활용합니다. 즉, 각 트랜잭션은 볼 수 있는 버전(ReadView)만 읽을 수 있습니다. ReadViewMVCC,也就是每个事务只能读取它能看到的版本(ReadView)。

  • READ COMMITTED:每次读取数据前都生成一个ReadView
  • REPEATABLE READ : 在第一次读取数据时生成一个ReadView

串行化

串行化的实现采用的是读写都加锁的原理。

串行化的情况下,对于同一行事务,会加写锁会加读锁。当出现读写锁冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行。

53.MVCC了解吗?怎么实现的?

MVCC(Multi Version Concurrency Control),中文名是多版本并发控制,简单来说就是通过维护数据历史版本,从而解决并发访问情况下的读一致性问题。关于它的实现,要抓住几个关键点,隐式字段、undo日志、版本链、快照读&当前读、Read View

版本链

对于InnoDB存储引擎,每一行记录都有两个隐藏列DB_TRX_ID、DB_ROLL_PTR

  • DB_TRX_ID,事务ID,每次修改时,都会把该事务ID复制给DB_TRX_ID
  • DB_ROLL_PTR,回滚指针,指向回滚段的undo日志。

4MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!

假如有一张user表,表中只有一行记录,当时插入的事务id为80。此时,该条记录的示例图如下:

4MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!

接下来有两个DB_TRX_ID分别为100200的事务对这条记录进行update操作,整个过程如下:

4MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!

由于每次变动都会先把undo日志记录下来,并用DB_ROLL_PTR指向undo日志地址。因此可以认为,对该条记录的修改日志串联起来就形成了一个版本链,版本链的头节点就是当前记录最新的值。如下:

4MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!

ReadView

对于Read CommittedRepeatable Read隔离级别来说,都需要读取已经提交的事务所修改的记录,也就是说如果版本链中某个版本的修改没有提交,那么该版本的记录时不能被读取的。所以需要确定在Read CommittedRepeatable Read隔离级别下,版本链中哪个版本是能被当前事务读取的。于是就引入了ReadView

READ COMMITTED: 데이터를 읽기 전에 매번 ReadView를 생성합니다.

REPEATABLE READ: 처음으로 데이터를 읽을 때 ReadView를 생성합니다.

4MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!Serialization

  • Serialization은 읽기와 쓰기를 모두 잠그는 원리를 사용하여 구현됩니다.
  • 직렬화의 경우 동일한 트랜잭션 행에 대해 write쓰기 잠금을 추가하고 read를 추가합니다. >읽기 잠금. 읽기-쓰기 잠금 충돌이 발생하면 나중에 액세스되는 트랜잭션은 계속 실행되기 전에 이전 트랜잭션이 완료될 때까지 기다려야 합니다.
  • 53.MVCC를 이해하시나요? 어떻게 달성됩니까?

  • MVCC(Multi Version Concurrency Control), 중국어 이름은 다중 버전 동시성 제어입니다. 간단히 말해서 데이터의 기록 버전을 유지하여 동시 액세스 시 읽기 일관성 문제를 해결합니다. 구현과 관련하여
  • 암시적 필드, 실행 취소 로그, 버전 체인, 스냅샷 읽기 및 현재 읽기, 읽기 보기
  • 등 몇 가지 핵심 사항을 파악해야 합니다.

버전 체인🎜🎜🎜InnoDB 스토리지 엔진의 경우 레코드의 각 행에는 두 개의 숨겨진 열이 있습니다🎜DB_TRX_ID, DB_ROLL_PTR🎜🎜🎜🎜DB_TRX_ID, 트랜잭션 ID, 수정될 때마다 트랜잭션 ID가 DB_TRX_ID에 복사됩니다. 🎜🎜DB_ROLL_PTR, 롤백 포인터는 롤백 세그먼트의 실행 취소 로그를 가리킵니다. 🎜🎜🎜4MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!🎜🎜 레코드가 한 행만 있는 user 테이블이 있고 이때 삽입된 트랜잭션 ID가 80이라고 가정합니다. 이때 본 음반의 샘플 이미지는 다음과 같습니다. 🎜🎜4MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!🎜🎜다음으로 DB_TRX_ID100이고 200인 두 개의 트랜잭션이 업데이트 작업의 전체 프로세스는 다음과 같습니다. 🎜🎜4MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!🎜🎜모든 변경 사항은 먼저 실행 취소 로그에 기록되고 DB_ROLL_PTR을 사용하여 실행 취소 로그 주소. 따라서 🎜이 레코드의 수정 로그가 연결되어 버전 체인을 형성하고, 버전 체인의 헤드 노드가 현재 레코드의 최신 값🎜이라고 생각할 수 있습니다. 다음과 같습니다: 🎜🎜4MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문! 🎜 🎜🎜ReadView🎜🎜
🎜 Read CommittedRepeatable Read 격리 수준 모두에서 제출된 트랜잭션에 의해 수정된 레코드를 읽어야 합니다. 즉, 버전 체인의 특정 버전에 대한 수정 사항이 커밋되지 않으면 해당 버전의 기록을 읽을 수 없습니다. 따라서 커밋된 읽기반복 가능한 읽기 격리 수준에서 현재 트랜잭션이 읽을 수 있는 버전 체인의 버전을 결정해야 합니다. 그래서 이 문제를 해결하기 위해 ReadView라는 개념이 도입되었습니다. 🎜🎜🎜Read View는 트랜잭션이 실행될 때 생성되는 읽기 뷰입니다. 🎜snapshot read🎜는 특정 일정에 기록된 스냅샷과 동일합니다. 🎜🎜🎜🎜🎜🎜m_ids: 언제를 나타냅니다. ReadView가 생성됩니다. 현재 시스템에서 활성 읽기 및 쓰기 트랜잭션의 트랜잭션 ID 목록이 생성됩니다. 🎜🎜min_trx_id: ReadView가 생성될 때 현재 시스템에서 활성화된 읽기 및 쓰기 트랜잭션 중 가장 작은 트랜잭션 ID, 즉 m_ids에서 가장 작은 값을 나타냅니다. 🎜🎜max_trx_id: ReadView 생성 시 시스템에서 다음 트랜잭션에 할당되어야 하는 id 값을 나타냅니다. 🎜🎜creator_trx_id: ReadView를 생성한 트랜잭션의 트랜잭션 ID를 나타냅니다. 이 ReadView를 사용하면 레코드에 액세스할 때 특정 버전의 레코드가 표시되는지 확인하려면 아래 단계만 따르면 됩니다. 🎜
  • 접근한 버전의 DB_TRX_ID 속성 값이 ReadView의 creator_trx_id 값과 동일하다면 현재 트랜잭션이 자신의 수정된 레코드에 접근하고 있다는 의미이므로 현재 트랜잭션에서 이 버전에 접근할 수 있습니다.
  • 접근한 버전의 DB_TRX_ID 속성 값이 ReadView의 min_trx_id 값보다 작다면, 현재 트랜잭션이 ReadView를 생성하기 전에 이 버전을 생성한 트랜잭션이 커밋되었기 때문에 현재 트랜잭션에서 이 버전에 접근할 수 있다는 의미입니다.
  • 접속된 버전의 DB_TRX_ID 속성 값이 ReadView의 max_trx_id 값보다 크다면, 현재 트랜잭션이 ReadView를 생성한 이후에 이 버전을 생성한 트랜잭션이 오픈되었기 때문에 현재 트랜잭션에서는 이 버전에 접근할 수 없다는 의미입니다.
  • 접근한 버전의 DB_TRX_ID 속성 값이 ReadView의 min_trx_id와 max_trx_id 사이에 있다면 trx_id 속성 값이 m_ids 목록에 있는지 확인해야 합니다. 생성된 ReadView는 여전히 활성 상태입니다. 그렇지 않은 경우 이 버전에 액세스할 수 없습니다. 이는 ReadView가 생성될 때 이 버전을 생성한 트랜잭션이 커밋되었으며 이 버전에 액세스할 수 있음을 의미합니다.

특정 버전의 데이터가 현재 트랜잭션에 표시되지 않는 경우 버전 체인을 따라 다음 데이터 버전을 찾고, 위 단계를 계속 수행하여 가시성을 결정하는 등의 과정을 마지막 버전이 될 때까지 계속합니다. 버전 체인. 마지막 버전이 보이지 않는다면, 해당 기록이 거래에 전혀 보이지 않는다는 의미이며, 쿼리 결과에는 해당 기록이 포함되지 않습니다.

MySQL에서 READ COMMITTED와 REPEATABLE READ 격리 수준의 매우 큰 차이점은 서로 다른 시간에 ReadView를 생성한다는 것입니다.

READ COMMITTED는 각 데이터를 읽기 전에 ReadView를 생성하여 매번 다른 트랜잭션에 의해 제출된 데이터를 읽을 수 있도록 보장합니다. REPEATABLE READ는 처음으로 데이터를 읽을 때 ReadView를 생성합니다. 후속 판독 결과는 완전히 일관됩니다.

고가용성/성능

54. 데이터베이스 읽기와 쓰기의 분리를 이해하고 계십니까?

읽기 및 쓰기 분리의 기본 원칙은 데이터베이스 읽기 및 쓰기 작업을 여러 노드에 분산시키는 것입니다. 다음은 기본 아키텍처 다이어그램입니다.

4MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!

읽기 및 쓰기 분리의 기본 구현은 다음과 같습니다.

  • 데이터베이스 서버는 마스터-슬레이브 클러스터를 구축합니다. 하나의 마스터와 하나의 슬레이브 또는 하나의 마스터와 여러 슬레이브를 사용할 수 있습니다.
  • 데이터베이스 호스트는 읽기 및 쓰기 작업을 담당하고, 슬레이브는 읽기 작업만 담당합니다.
  • 데이터베이스 호스트는 복제를 통해 데이터를 슬레이브 머신에 동기화하고, 각 데이터베이스 서버는 모든 비즈니스 데이터를 저장합니다.
  • 비즈니스 서버는 데이터베이스 호스트에 쓰기 작업을 보내고 데이터베이스 슬레이브에 읽기 작업을 보냅니다.

55. 읽기 및 쓰기 분리 할당을 구현하는 방법은 무엇입니까?

읽기 및 쓰기 작업을 분리하고 다른 데이터베이스 서버에 액세스하려면 일반적으로 프로그램 코드 캡슐화와 미들웨어 캡슐화라는 두 가지 방법이 있습니다.

1. 프로그램 코드 캡슐화

프로그램 코드 캡슐화는 읽기 및 쓰기 작업과 데이터베이스 서버 연결을 분리하기 위해 코드에서 데이터 액세스 계층을 추상화하는 것을 의미합니다(일부 기사에서는 이 방법을 "중간 계층 캡슐화"라고도 함). 관리. 예를 들어 Hibernate 기반의 간단한 캡슐화는 읽기-쓰기 분리를 달성할 수 있습니다.

MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!

현재 오픈 소스 구현 솔루션 중에서 Taobao의 TDDL(Taobao Distributed Data Layer, 별명: 머리가 너무 큽니다)이 비교적 유명합니다.

2. 미들웨어 캡슐화

미들웨어 캡슐화는 읽기 및 쓰기 작업의 분리와 데이터베이스 서버 연결 관리를 구현하는 독립적인 시스템을 의미합니다. 미들웨어는 SQL 호환 프로토콜을 비즈니스 서버에 제공하며, 비즈니스 서버는 자체적으로 읽기와 쓰기를 분리할 필요가 없습니다.

비즈니스 서버의 경우 미들웨어에 액세스하는 것과 데이터베이스에 액세스하는 것에는 차이가 없습니다. 실제로 비즈니스 서버의 관점에서는 미들웨어가 데이터베이스 서버입니다.

기본 구조는 다음과 같습니다.

4MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!

56. 마스터-슬레이브 복제의 원리를 이해하시나요?

  • 마스터는 데이터를 쓰고 binlog를 업데이트합니다.
  • 마스터는 binlog를 슬레이브에 푸시하기 위해 덤프 스레드를 생성합니다.
  • 슬레이브가 마스터에 연결되면 IO 스레드를 생성하여 binlog를 수신하고 이를 릴레이 로그에 기록합니다. Relay log
  • 슬레이브 그런 다음 SQL 스레드를 열어 릴레이 로그 이벤트를 읽고 슬레이브에서 이를 실행하여 동기화를 완료합니다. 슬레이브는 자체 빙로그를 기록합니다. 57. 마스터-슬레이브 동기화 지연을 처리하는 방법은 무엇입니까?
  • 마스터-슬레이브 동기화 지연 이유

서버는 클라이언트가 연결할 수 있도록 N개의 링크를 열어두므로 동시 업데이트 작업이 많이 발생합니다. 그러나 서버에서 binlog를 읽는 스레드는 하나뿐입니다. 슬레이브 서버에서 특정 SQL을 실행하는 데는 약간의 시간이 걸립니다. 시간이 오래 걸리거나 특정 SQL이 테이블을 잠가야 하므로 마스터 서버에 SQL 백로그가 많아지고 슬레이브 서버에 동기화되지 않을 수 있습니다. 이로 인해 마스터-슬레이브 불일치, 즉 마스터-슬레이브 지연이 발생합니다.

마스터-슬레이브 동기화 지연에 대한 솔루션

마스터-슬레이브 복제 지연을 해결하는 몇 가지 일반적인 방법이 있습니다:

  • 쓰기 작업 후의 읽기 작업은 기본 데이터베이스 서버로 전송되도록 지정됩니다

예를 들어 계정 등록이 완료되면 마지막으로 로그인 시 계정을 읽어오는 읽기 작업도 메인 데이터베이스 서버로 전송됩니다. 이 방법은 비즈니스와 밀접하게 연관되어 있으며 비즈니스에 더 큰 침입과 영향을 미칩니다. 새로운 프로그래머가 이런 방식으로 코드를 작성하는 방법을 모른다면 버그가 발생하게 됩니다.

  • 슬레이브가 실패한 후 호스트를 다시 읽습니다.

이를 일반적으로 "보조 읽기"라고 합니다. 보조 읽기는 비즈니스에 바인딩되지 않으며 기본 데이터베이스에 액세스하기 위한 API만 캡슐화하면 됩니다. 단점은 보조 읽기가 많으면 호스트에 대한 읽기 작업 부담이 크게 증가한다는 것입니다. 예를 들어, 해커가 계정을 폭력적으로 크랙하는 경우 호스트는 읽기 작업의 압력을 견디지 못하고 붕괴될 수 있습니다.

  • 주요 비즈니스 읽기 및 쓰기 작업은 모두 호스트를 가리키고 중요하지 않은 비즈니스는 읽기 및 쓰기 분리를 사용합니다.

예를 들어 사용자 관리 시스템의 경우 등록 + 로그인 비즈니스 읽기 및 쓰기 작업은 모두 액세스합니다. 호스트, 사용자 소개, 사랑 및 수준과 같은 비즈니스는 읽기-쓰기 분리를 사용할 수 있습니다. 사용자가 자기 소개를 변경하더라도 쿼리할 때 자기 소개가 여전히 동일하다는 것을 알 수 있기 때문입니다. 로그인할 수 없는 것보다 훨씬 작고, 견딜 수 있습니다.

58. 보통 데이터베이스를 어떻게 나누나요?

  • 수직적 데이터베이스 분할: 테이블을 기반으로 다양한 비즈니스 소속에 따라 다양한 테이블이 다양한 데이터베이스로 분할됩니다.

5MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!

  • 수평 데이터베이스 분할: 필드를 기반으로 특정 전략(해시, 범위 등)에 따라 한 데이터베이스의 데이터가 여러 데이터베이스로 분할됩니다.

5MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!

59. 그럼 시계는 어떻게 나누나요?

  • 수평 테이블 분할: 필드 및 특정 전략(해시, 범위 등)에 따라 한 테이블의 데이터를 여러 테이블로 분할합니다.
  • 수직 테이블 분할: 필드 기반 및 필드 활동에 따라 테이블의 필드가 여러 테이블(메인 테이블과 확장 테이블)로 분할됩니다.

5MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!

60. 수평 테이블 분할의 라우팅 방법은 무엇입니까?

라우팅이란 무엇인가요? 이는 데이터를 어떤 테이블로 나누어야 하는지를 나타냅니다.

수평 테이블 샤딩에는 세 가지 주요 라우팅 방법이 있습니다.

  • 범위 라우팅: 순서가 지정된 데이터 열(예: 형태, 타임스탬프 등)을 라우팅 조건으로 선택하면 서로 다른 세그먼트가 서로 다른 데이터베이스 테이블에 분산됩니다.

일부 결제 시스템을 관찰해보면 1년 이내의 결제 내역만 확인할 수 있는 것을 알 수 있는데, 이는 결제 회사가 시간에 따라 테이블을 나누었기 때문일 수 있습니다.

5MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!

범위 라우팅 설계의 복잡성은 주로 세그먼트 크기 선택에 반영됩니다. 세그먼트가 너무 작으면 분할 후 하위 테이블이 너무 많아지고 세그먼트가 너무 크면 유지 관리가 복잡해집니다. , 여전히 성능 문제가 발생할 수 있습니다. 일반적으로 비즈니스에 따라 적절한 세그먼트 크기를 선택하는 것이 좋습니다.

범위 라우팅의 장점은 데이터 증가에 따라 새로운 테이블을 원활하게 확장할 수 있다는 것입니다. 예를 들어 현재 사용자 수가 100만 명이라면, 1000만 명으로 늘어나면 새 테이블만 추가하면 되고 원본 데이터는 변경할 필요가 없습니다. 범위 라우팅의 상대적으로 암묵적인 단점은 불균일한 분포입니다. 테이블을 1,000만개로 나눈 경우 한 세그먼트에 저장된 실제 데이터 양은 1,000개에 불과한 반면 다른 세그먼트에 저장된 데이터의 실제 양은 900개일 수 있습니다. 만.

  • 해시 라우팅: 해시 작업을 위해 특정 열(또는 특정 열의 조합)의 값을 선택한 다음 해시 결과에 따라 다른 데이터베이스 테이블에 배포합니다.

또한 주문 ID를 예로 들면, 처음부터 4개의 데이터베이스 테이블을 계획한다면 라우팅 알고리즘은 단순히 ID % 4의 값을 사용하여 해당 데이터가 속한 데이터베이스 테이블 번호를 나타낼 수 있습니다. 12는 50번 서브 테이블에 배치되고, id 13인 주문은 61번 워드 테이블에 배치된다.

5MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!

해시 라우팅 설계의 복잡성은 주로 초기 테이블 수 선택에 반영됩니다. 테이블이 너무 많으면 유지 관리가 번거롭고, 테이블이 너무 적으면 단일 테이블에서 성능 문제가 발생할 수 있습니다. 해시 라우팅을 사용한 후에는 하위 테이블 수를 늘리는 것이 매우 번거롭고, 모든 데이터를 재분배해야 합니다. 해시 라우팅의 장점과 단점은 기본적으로 범위 라우팅의 장점과 반대입니다.

  • 라우팅 구성: 라우팅 구성은 라우팅 정보를 기록하기 위해 독립 테이블을 사용하는 라우팅 테이블입니다. 주문 ID를 예로 들면, 새로운 order_router 테이블을 추가합니다. 이 테이블에는 orderjd와 tablejd라는 두 개의 열이 포함되어 있습니다. 해당 table_id는 orderjd를 기반으로 쿼리할 수 있습니다.

구성 라우팅 설계는 간단하고 사용이 매우 유연합니다. 특히 테이블을 확장할 때 지정된 데이터를 마이그레이션한 다음 라우팅 테이블을 수정하기만 하면 됩니다.

5MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!

라우팅 구성의 단점은 두 번 이상 쿼리해야 한다는 것입니다. 이는 전체 성능에 영향을 미치며, 라우팅 테이블 자체가 너무 큰 경우(예: 수억 개의 데이터) 성능이 저하될 수 있습니다. 라우팅 테이블을 다시 데이터베이스로 분할하면 병목 현상이 발생합니다. 테이블을 분할하면 무한 루프 라우팅 알고리즘 선택 문제에 직면하게 됩니다.

61. 다운타임 없이 용량 확장을 달성하는 방법은 무엇입니까?

사실 다운타임 없는 확장은 실제로 매우 번거롭고 위험한 작업입니다. 물론 인터뷰가 훨씬 간단합니다.

  • 첫 번째 단계: 온라인 이중 쓰기, 기존 데이터베이스 쿼리

    • 새 데이터베이스 테이블 구조를 설정하고 데이터가 장기 데이터베이스에 기록되고 분할된 새 데이터베이스에도 기록됩니다

    • 데이터 마이그레이션, 데이터 마이그레이션 프로그램을 사용하여 기존 데이터베이스의 기록 데이터를 새 데이터베이스로 마이그레이션

    • 예약된 작업을 사용하여 기존 데이터베이스와 새 데이터베이스의 데이터를 비교하고 차이점을 채우세요

5MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!

  • 2단계: 온라인 이중 쓰기, 새 데이터베이스 쿼리

    • 기록 데이터의 동기화 및 확인 완료

    • 데이터 읽기를 새 데이터베이스로 전환

MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!

  • 세 번째 단계: 기존 라이브러리가 오프라인 상태입니다

    • 이전 라이브러리는 더 이상 새 데이터를 쓰지 않습니다

    • 일정 시간이 지난 후, 기존 라이브러리의 요청이 없는지 확인한 후, 오래된 라이브러리를 오프라인으로 전환할 수 있습니다

5MySQL 지식 포인트를 정리하는 데 도움이 되는 66개의 인터뷰 질문!

62. 데이터베이스 및 테이블 샤딩에 일반적으로 사용되는 미들웨어는 무엇입니까?

  • sharding-jdbc
  • Mycat

63. 그러면 하위 데이터베이스와 하위 테이블로 인해 어떤 문제가 발생할 것이라고 생각하시나요?

하위 데이터베이스 관점에서:

  • 트랜잭션 문제

관계형 데이터베이스 사용의 가장 큰 장점은 트랜잭션 무결성을 보장한다는 것입니다.

데이터베이스가 분할되면 단일 머신 트랜잭션은 더 이상 필요하지 않으며 분산 트랜잭션을 사용하여 해결해야 합니다.

  • 교차 데이터베이스 JOIN 문제

한 데이터베이스에 있을 때는 JOIN을 사용하여 테이블 쿼리를 조인할 수도 있지만, 데이터베이스를 교차한 후에는 JOIN을 사용할 수 없습니다.

이때 해결 방법은 비즈니스 코드에서 상관관계 즉, 먼저 한 테이블의 데이터를 확인하고, 얻은 결과를 통해 다른 테이블을 확인한 후 코드를 이용하여 상관시켜 최종 결과를 얻는 것입니다. .

이 방법은 구현하기가 약간 더 복잡하지만 허용됩니다.

또한 적절하게 중복할 수 있는 일부 필드도 있습니다. 예를 들어 이전 테이블에는 상관 관계 ID가 저장되어 있었지만 비즈니스에서는 해당 이름이나 기타 필드를 반환해야 하는 경우가 많았습니다. 이때 이러한 필드를 현재 테이블에 중복하여 추가하여 연결이 필요한 작업을 제거할 수 있습니다.

또 다른 방법은 데이터 이질성입니다. binlog 동기화 및 기타 방법을 통해 교차 데이터베이스 조인이 필요한 데이터를 ES와 같은 저장소 구조로 이질화하고 ES를 통해 쿼리합니다.

하위 테이블 관점에서:

  • 교차 노드 수, 정렬 기준, 그룹화 및 집계 기능 문제

는 비즈니스 코드로만 구현하거나 미들웨어를 사용하여 각 테이블의 데이터를 요약할 수 있습니다. 정렬, 페이지 매기기 및 반환.

  • 데이터 마이그레이션, 용량 계획, 확장 및 기타 문제

데이터 마이그레이션, 용량 계획 방법, 향후 다시 확장이 필요한지 여부 등은 모두 고려해야 할 문제입니다.

  • ID 문제

데이터베이스 테이블이 분할된 후에는 더 이상 데이터베이스 자체의 기본 키 생성 메커니즘에 의존할 수 없으므로 전역 기본 키가 고유한지 확인하기 위한 몇 가지 수단이 필요합니다.

  • 여전히 자동 증가이지만 자동 증가 단계 크기가 설정됩니다. 예를 들어, 현재 3개의 테이블이 있고, 단계 크기는 3으로 설정되었으며, 3개 테이블의 초기 ID 값은 각각 1, 2, 3입니다. 이런 식으로 첫 번째 테이블의 ID 증가는 1, 4, 7이 됩니다. 두 번째 테이블은 2, 5, 8입니다. 세 번째 테이블은 3, 6, 9이므로 중복이 없습니다.

  • UUID, 이것은 가장 간단하지만 불연속적인 기본 키 삽입으로 인해 심각한 페이지 분할과 성능 저하가 발생합니다.

  • 분산ID 중 가장 유명한 것은 트위터의 오픈소스 sonwflake 눈송이 알고리즘

운영 및 유지보수

64. 100만 레벨이 넘는 데이터를 어떻게 삭제하나요?

인덱스에 대하여: 인덱스 파일은 별도의 파일이기 때문에 추가 유지관리 비용이 필요하므로, 데이터를 추가, 수정, 삭제할 때 인덱스 파일에 대한 추가 작업이 발생하게 되며, 이러한 작업에는 추가 비용이 발생합니다. 추가/수정/삭제 실행 효율성이 저하됩니다.

그래서 우리는 데이터베이스에서 수백만 개의 데이터를 삭제할 때 MySQL 공식 매뉴얼을 참조하여 데이터 삭제 속도가 생성된 인덱스 수에 정비례한다는 것을 알게 됩니다.

  • 그래서 수백만 개의 데이터를 삭제하려면 먼저 인덱스를 삭제하고

  • 쓸데없는 데이터를 삭제하면 됩니다.

  • 삭제가 완료된 후 인덱스를 다시 생성하는 것도 매우 어렵습니다. fast

65. Million 수천만 개의 테이블이 있는 큰 테이블에 필드를 추가하는 방법은 무엇입니까?

온라인 데이터베이스 데이터의 양이 수백만 또는 수천만에 도달하면 테이블이 오랫동안 잠겨 있을 수 있기 때문에 필드를 추가하는 것이 그리 간단하지 않습니다.

대형 테이블에 필드를 추가하려면 일반적으로 다음 방법이 있습니다.

  • 중간 테이블을 통해 변환

    임시 새 테이블을 만들고, 이전 테이블의 구조를 완전히 복사하고, 필드를 추가한 다음, 이전 테이블 데이터를 삭제하고 새 테이블의 이름을 이전 테이블의 이름으로 지정하면 일부 데이터가 손실될 수 있습니다.

  • Use pt-online-schema-change

    pt-online-schema-change는 percona 회사에서 개발한 도구로, 중간 테이블을 통해서도 테이블 구조를 수정할 수 있습니다.

  • 먼저 슬레이브 데이터베이스에 추가한 후 마스터-슬레이브 전환을 수행합니다

    테이블이 데이터량이 많고 핫 테이블(읽기와 쓰기가 특히 빈번한 경우)인 경우에는 먼저 슬레이브 데이터베이스를 수행한 다음 마스터-슬레이브 전환을 수행한 다음 다른 여러 노드에 필드를 추가합니다.

66. MySQL 데이터베이스 CPU가 급증하면 어떻게 해야 하나요?

문제 해결 프로세스:

(1) top 명령을 사용하여 mysqld 또는 다른 이유로 인해 발생했는지 관찰하고 확인합니다.

(2) mysqld로 인해 발생한 경우 processlist를 표시하고 세션 상태를 확인하여 리소스를 소모하는 SQL이 실행되고 있는지 확인합니다.

(3) 소모량이 많은 SQL을 찾아 실행 계획이 정확한지, 인덱스가 누락되었는지, 데이터량이 너무 많은지 살펴보세요.

처리:

(1) 이 스레드를 종료하고(CPU 사용량이 떨어지는지 관찰),

(2) 해당 조정을 수행합니다(예: 인덱스 추가, SQL 변경, 메모리 매개변수 변경)

(3) 다음을 실행합니다. 다시 SQL.

기타 상황:

각 SQL 문이 많은 리소스를 소비하지 않지만 갑자기 많은 수의 세션 연결이 들어와 CPU가 급증하는 경우도 가능합니다. 이 경우 애플리케이션으로 분석해야 합니다. 연결 수가 급증하는 이유. 그런 다음 연결 수 제한 등 해당 조정을 수행하세요.

[관련 권장 사항: mysql 비디오 튜토리얼]

성명:
이 기사는 juejin.cn에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제