프로젝트는 다음과 같이 구성됩니다.
프로젝트 소스 파일의 패키지는 다음과 같은 합리적으로 배열됩니다.
논리적 계획에서 선택을 올바른 위치로 푸시하기 위해, 우리는 동일한 범위 조건을 가진 그룹 속성에 대한 Union 찾기 데이터 구조를 구현했습니다. 동일한 관계와 동일한 관계의 두 속성 사이의 EqualSto, 더 큰 미성년 표현 또는 동일한 관계의 두 속성 사이의 선택 조건은 결합 조건 후에 푸시됩니다. 비 Quality 및 기타 유용한 선택 조건은 조인 연산자에게 밀려날 것입니다.
우리는 사용할 선택 방법을 처리하기 위해 selectionOptimizer라는 클래스를 만들었습니다. 먼저 선택과 관련된 하나의 관계의 모든 속성에 대한 인덱싱 가용성을 확인합니다. 이러한 속성에 대한 적절한 인덱싱이 없으면 일반 스캔 방법을 선택합니다. 이러한 속성에 대한 인덱싱 옵션이있는 경우 비용을 비교하고 비용이 가장 낮은 비용을 선택합니다.
우리는 동적 프로그래밍 방법을 암살하여 최상의 조인 순서를 선택하는 데 몇 가지 문제가있었습니다. 우리가 구현 한 손상된 솔루션은 각 테이블 크기를 기준으로 결합 순서를 선택하는 것입니다.
당사의 논리는 적용 가능한 경우 정렬 merg 조인을 사용하는 것입니다. SMJ가 적용되지 않으면 블록 중첩 루프 조인을 사용하도록 선택합니다.
프로그램의 최상위 항목은 client.sqlinterpreter.main ()에 있습니다.
통역사는 입력 파일을 읽고 쿼리 평가자로 전송하고 결과를 파일에 출력합니다.
우리는 WHERE 절에서 다음과 같은 조건을 분류합니다. 1. 상수 비교. 2. 테이블 내 선택 조건. 3. 교차 테이블 조인 조건.
구문 분석이 시작될 때, 모든 조건은 재귀 적으로 및 표현을 분해함으로써 추출된다. 그런 다음 각 테이블에 대해 우리는 다음과 같이 기록합니다. 1) 선택 조건 및 2) 이전 테이블과의 조건. 이렇게하면 테이블에서 이동할 수 있으며 새 테이블을 현재 왼쪽 하위 트리와 결합 해야하는 관련 조건에만 집중할 수 있습니다. 물론, 일정한 조건은 모든 것보다 먼저 처리됩니다.
지침에 따라 SortOperator를 구현했습니다. 특정 주문 요소가 예상되지 않은 경우 (예 : SB의 S Order에서 SA를 선택) 고유 한 경우 해시 세트를 사용하여 주문을 유지하기 위해 다른 연산자가 있습니다.
우리는 bplustree 클래스를 제공하고 그 생성자는 주어진 관계 데이터에서 하나의 Purticular 속성에 대한 직렬화 된 인덱스 파일을 빌드 할 수 있습니다. 또한 사용자가 실행 중에 인덱스 스캔 연산자를 사용해야 할 때 트리 인덱스 사산화 기능을 제공합니다. 이것은 튜플 검색 시간이 단축됩니다.
B+ 트리 인덱스를 사용하여 인덱스 선택을위한 인덱스 스캔 연산자를 구현했습니다. 표현식에 인덱스 속성이 포함되어있는 표현식을 평가하고 Deserilizer를 호출하여 B+ 트리의 잎 노드에서 최초의 SATIFED 데이터 항목을 가져옵니다. 그 후, 파일이 클러스터링되면 튜플을 선형으로 가져오고, 다른 현명하게, 다음으로 만족스러운 데이터 항목을 불안정한 데이터 입력으로 가져옵니다.
이전 디자인에서 우리는 논리 선택 연산자에게 논리 선택 연산자의 자녀가 스캔 연산자 여야한다는 중요한 제약을 제공했습니다. 따라서 방문자 패턴을 사용하여 물리적 계획을 세우면 선택 연산자에게 최대를 통과하면됩니다. 방문자가 선택 연산자에게 가로 질러 가면 로직은 선택 연산자의 자녀가 전체 스캔 연산자 또는 인덱스 스캔 연산자 여야한다고 결정할 수 있습니다.
구성 파일에서 정보를 카탈로그에 저장했습니다. 첫째, 데이터베이스 카탈로그에 인덱스 쿼리가 켜져 있음을 보여 주면이 쿼리에서 인덱스 가용성을 확인해야합니다.
인덱스가 선택 조건에 적용되는지 확인하는 hasidxattr 이라는 메소드가 있습니다. 즉,이 테이블에 대한 선택 조건이 인덱스가있는 attraiet 의 것 보다 동일하지만 , 동등한 것보다 크고 크고 , 아동으로 인덱스 스캔 연산자를 구축하는 것이 좋습니다. 그런 다음 Lowkey와 Highkey는 모든 선택 조건에 따라 의존하고 연산자를 구축합니다.
hasidxattr 이 false를 반환하면 일반적인 전체 스캔 연산자를 구축해야합니다.
마지막으로 우리는 Uppper 레벨로 돌아갑니다.
우리는 두 가지 테스트 전략을 사용합니다
기본 테스트의 경우 수동으로 운영자를 구성하고 튜플을 덤프하여 연산자가 반복자 모델과 관련하여 작동 할 수 있음을 증명합니다.
엔드 투 엔드 테스트는 전체 통역사를 테스트중인 장치로 취하는 테스트입니다. 테스트 케이스는 입력 쿼리 파일을 가져온 다음 쿼리를 실행하고 마지막으로 결과를 대상 파일에 인쇄합니다.
테스트를 더 잘 수행하기 위해 MySQL 데이터베이스의 결과를 예상 출력으로 버리는 Bash 스크립트를 작성했습니다. 따라서 비교적 복잡한 테스트 사례를 구축하는 것은 매우 쉽습니다.
또한 출력의 정확성을 자동으로 판단하는 두 파일을 비교하기 위해 UTIL 클래스 Diff를 만들었습니다.