관계형
데이터베이스 이전에는 대부분 key와 데이터가 매우 밀접한 관련이 있었음
Key
를 찾기만 하면 원하는 데이터를 찾을 수 있어야 하기 때문에 Key = Data 로 인식
Key
는 데이터를 항상 옆에 두어야 하는 불편함이 있었음
테이블과
인덱스가 별도로 분리되어 있는 구조는 관계형 데이터 베이스의 가장 일반적 저장형식
\-
데이터를 저장할 때 인덱스 영향을 받지 않음으로 인한 부담이 감소
\-
데이터에 들어있는 값이 저장과는 무관함(무조건적인 저장 가능)
\-
저장 위치를 기록해 두어야 하는 번거로움이 있음
\-
무조건 저장으로 인한 저장시의 부담이 감소함
한번도 사용되지 않은 블록
(10, 13번)
일정량 이상의 재사용이 허용된 블록
(11번)
재사용으로 허용되지 않은 블록
(12,14,15번)
활용이 가능한 블록들은 사용목록
(Free List)에 기록 후 데이터 저장시 사용할 블록으로 제공됨
[그림
1-1-1] 의 Insert데이터 저장된 모습을 보면 데이터에 들어있는 값과는 전혀 무관하게 저장됨을 알 수 있음.
저장할 블록이 재활용 블록
(11번) 이었다면, 비어있는 공간에 채웠을 것임.
이어진 공간이 없다면 전체블록의 로우 위치를 재배치
(Condensing)하는 작업이 발생.
블록 하단의
FREE SPACE는 새로운 로우가 들어올 때 사용하는 공간이 아니라, 이미 들어가 있는 로우의 길이에 변화가 생겼을 때 사용하는 공간으로 테이블 정의시 파라메터(PCTFREE)로 지정 가능함.
{*}테이블 스페이스{*}
(Table Space) {*}란{*}
논리적인 저장공간을 말함
(ex. 내 소유의 토지 or 부지)
테이블 스페이스는 물리적인 데이터파일
(Datafile)로 구성되고 용도별로 나눌 수 있음
{*}세그먼트{*}
(Segment)란{}
테이블 스페이스를 용도별로 나눌 수 있는데 이것을 세그먼트라고 함.
이 안에는 Object가 들어올 수 있음.
{*}ROWID{*}
{*}의 구성{*}
{*}Object No. + Datafile No.(Table space{*}
{*}당{*} {*}SeqNo.) + BlockNo. + SlotNo.*
{*}AAARJG{*}
{*}AAe{*}{*}AAACBm{*}{*}AAA{*}
6
자리 : 데이터오브젝트번호 = DB Segment 식별정보(해당 로우가 속해있는 오브젝트번호)
3
자리: Relative file = Tablespace의 상대적 Datafile번호(해당 로우가 속해있는 데이터파일번호)
6
자리: Block number = Row를 포함하는DataBlock번호(해당 로우가 속해있는 데이터파일의 데이터 블록 주소값)
3
자리: Row number = Block에서의 Row의 Slot : 데이터 블록 내에서 해당 로우의 주소값
ROWID
는 테이블에 존재하는것이 아니라 인덱스에 존재함.
ROWID
에는 로우의 구체적인 위치정보가 들어있는 것이 아니라 방(슬록)번호가 존재
이 슬롯 번호속에 로우의 위치 정보가 들어 있다
. 이는 블록내의 로우의 위치가 이동 하더라도 ROWID는 결코 변하지 않음.
{*}응축{*}
(Condensing)
블럭 내에 저장될 로우가 한조각
(one piece)이 되도록 하기 위한 공간은 있지만 이어진 조각이 없어 저장이 불가능하게 될 때 자동으로 블록의 로우들을 재구성하는 작업이 일어나는데 이를 응축이라 함.
{*}이주{*}
(RowMigration)
발생한 로우들의 길이가 너무 많이 커져 응축을 하더라도 로우의 길이가 늘어날 때 사용할 여유공간이 부족하게 되면
, 이는 결국 다른 블록을 사용할 수 밖에 없게 됨.
로우가 다른 블록으로 이동하면
ROWID의 변경을 의미하여 이를 변경시키지 않고 여러 블록을 Access 하는 오버헤드를 감수하는 상태를 로우의 이주(Migration)이라 함.
이는 로우나 테이블을 삭제하고 다시 생성해야만 치유할 수 있음
{*}체인{*}
(Chain)
여러 블록에 걸쳐 데이터가 존재하는 점에서는 이주와 유사하나 어떤
{+}로우의 길이가 한 블록을 넘는 다{+}면 어떤 방법을 사용하더라도 하나의 블록 내에는 존재할 수 없기 때문,
필요한 공간만큼 블록을 연결해서 저장해야 하는데 이것을 체인이 발생했다고 함.
이는 본질적으로 이주와는 다름을 유념해야 함.
분리형 테이블의 특징인
'임의의 위치'에 저장으로 인해 원하는 값을 찾기위해 필연적으로 여러 블럭을 찾아 보아야 함.
이미 액세스해 두었던 블록에서 원하는 로우를 찾을 확률이 높다면 물리적으로 액세스할 블럭의 량은 분명히 줄어듬
.
임의의 위치에 흩어져 있더라도 얼마나 주변에 모여 있느냐에 따라 액세스 효율은 커다란 영향을 받게 됨
인덱스의 컬럼값으로 정렬되어 있는 인덱스 로우의 순서와 테이블에 저장되어 있는 데이터 로우의 위치가 얼마나 비슷한 순서로 저장되어 있는지의 정도를 나타낸 것을
'클러스터링 팩터'라고 표현.
분리형 테이블 구조가 가지는 최대 특징
임의의 위치에 저장
= 원하는 값을 찾기 위해 여러 곳을 Access
아무 곳에나 저장됨
= 다양한 블록에 흩어져 있을 수 있음
관계형 데이터 베이스는 최소한 하나의 블록은
Access 되어야 함
1 Row Access = n Block Access
{*}클러스터링 팩터{*}
인덱스의 컬럼값으로 정렬되어 있는 인덱스 로우의 순서와 테이블에 저장된 데이터 로우의 위치가 얼마나 비슷한 순서로 저장되어 있는 정도
클러스터링 팩터를 향상시키는 것은 엑세스 효율에 직접적인 영향을 줌
임의의 위치에 저장이 되는 분리형 테이블은 클러스터링 팩터의 문제가 매우 중요함
.
클러스터링 팩터가 좋은 인덱스로 엑세스를 하면 많은 로우를 엑세스 하더라도 적은 블록을 엑세스 하게 되어 효율적일 수 있음
가) {*}넓은 범위의 액세스 처리에 대한 대처방안{*}
대부분의RDBMS에서는 사용자의 요청 데이터를 메모리 내에서만 처리하고 디스크에서는 여유가 있을 때 옮겨다 두는 지연기록(Differed write)방식을 취함
{*}DISK I/O{*}
{*}최적화를 위하여 디스크로의 저장{*}(Write){*}시간을 실제 작업의 시간과 다르게 유지{*}(Differed Write){*}하는 기법을 사용한다{*}
{*}1)*
{*}소형테이블{*}
소량의 데이터라면 그리 많지 않은 블록에 흩어져 있을 것이고
, 앞서 발생한 엑세스에 의해 이미 메모리 내에 존재할 가능성이 높음
메모리 내의 엑세스라면 그것이 비록 랜덤 엑세스라 하더라도 부하의 부담이 그리 크지 않음으로 충분이 수용 가능
중대한 엑세스
(Critical Access Path)라면 더 적극적인 방법을 적용
특별한 경우가 아니라면 이러한 조치를 하지 않아도 무방함
.
{*}2)*
{*}중형 테이블{*}
등록시에는 부담이 되더라도 좋은 엑세스를 위해서는 찾기 좋은 형태로 저장해 두는 것이 바람직함
.
가장 중요한 엑세스 형태를 선정
특정한 저장위치를 어느 컬럼
(들)에 맞추어 줄 것인지 결정
데이터 등록시 부하 부담을 무시할 수 없다면 특정 위치에 저장을 하는 것을 재검토
{*}3)*
{*}대형테이블{*}
{*}첫째{*}
: {*}단순 저장 형 개념으로 사용시{*}
로그 정보를 관리하는 테이블을 예로 들 수 있음
신속한 저장을 요구함
.
분리형이 가장 적적한 형태
파티션과 같은 조치가 필요
{*}둘째{*}
: {*}대량의 데이터 수집{*}, {*}랜덤 엑세스 주로 발생{*}
고객 테이블을 예로 들 수 있음
대량의 데이터가 급속히 들어오는 경우는 적음
.
범위 처리를 자주 하지 않는 편임
분리형 구조가 가장 적적한 형태
파티션이나 클러스터링을 하더라도 큰 혜택이 없는 경우임
{*}셋째{*}
: {*}대량의 데이터 지속적 증가{*}, {*}매우 다양한 엑세스{*}
매출 테이블을 예로 들 수 있음
시스템에 지대한 영향을 미침
데이터 관리 및 엑세스에 대한 부담이 큼
증가하는 데이터에 대한 관리적인 부담이 크면
, 파티션을 적용.
최소한의 필요부분 엑세스를 위해 인덱스를 전략적으로 구성
SQL
의 실행계획을 최적화 하는 방법이 가장 중요
{*}나) 클러스터링 팩터 향상 전략{*}
자주 엑세스 하는 것들이 유사한 위치에 모여 있도록 하는 것을 응집이라고 함
. 즉 클러스터링 팩터를 좋게 하는 것을 말함.
분리형 구조는 저장 시에 우리가 강제로 제어할 수 없음
.
이는 주기적인 테이블 재생성으로 응집도를 높여주어야 함
.
현실적으로는
체인(Chain)을 감소시키고 블록 내 데이터의 저장율을 높여 불필요한 I/O를 줄이기 위해 사용함.
이로 인한 효율이 높아지는 이유는 테이블을 재생성 하면 당연히 인덱스도 다시 생성 되야 함
. 이는 인덱스의 가지 깊이(Branch depth)가 정리되는 효과를 줌
원하는 정렬로 생성된 인덱스가 있다면 약간의 부하가 증가하지만 힌트를 적용해서라도 인덱스를 경유하여 저장하는 것이 좋음
.
병렬처리로 정렬을 하는 것도 하나의 대안임
{*}테이블 재생성시 주의{*}
\-
인덱스를 모두 제거하거나 비활성(Disable)시키는 것이 좋음
\-
인덱스 생성한 채로 데이터 저장 시 저장속도 저하를 가져옴
\-
인덱스 분할이 발생하여 인덱스 저장 밀도도 나빠짐
\-
인덱스 효율을 떨어뜨림