복습
데이터베이스 인덱스: 특징, 구성요소, 작동방식, 그리고 클러스터/비클러스터 방식 비교 🚀
데이터베이스는 대량의 데이터를 효율적으로 관리하고, 빠르게 검색할 수 있도록 다양한 기법들을 제공합니다. 그 중에서 인덱스(Index) 는 가장 중요한 요소 중 하나입니다. 인덱스는 책의 목차처럼, 우리가 원하는 데이터를 빠르게 찾을 수 있도록 돕는 역할을 합니다. 오늘은 인덱스의 특징과 구성요소, B-Tree와의 관계, 그리고 클러스터 방식과 비클러스터 방식의 차이를 비교해보겠습니다.
1. 데이터베이스 인덱스란? 📚
인덱스는 데이터를 빠르게 검색할 수 있도록 돕는 검색 구조입니다. 일반적으로 인덱스는 데이터베이스 내의 특정 컬럼에 대한 정렬된 데이터를 저장하고, 이를 통해 데이터를 조회할 때 효율성을 높여줍니다. 예를 들어, 책에서 특정 주제나 내용을 빠르게 찾기 위해 목차를 이용하는 것처럼, 데이터베이스에서도 인덱스를 사용하여 필요한 레코드를 빠르게 찾아냅니다.
인덱스의 구성 요소
- 키(Key): 검색할 때 기준이 되는 컬럼 값. 예를 들어, 이름, 전화번호, 이메일 등이 키가 될 수 있습니다.
- 포인터(Pointer): 키에 해당하는 데이터를 실제로 저장하고 있는 위치나 레코드를 가리키는 주소입니다.
- 값(Value): 인덱스에서 저장된 실제 데이터의 주소입니다. 이 값이 없으면 인덱스를 통한 검색이 불가능하겠죠.
2. 인덱스의 작동 방식 🛠️
인덱스의 작동 방식은 주로 두 가지로 나눠집니다. B-Tree와 Hash 방식인데, 여기서는 가장 많이 사용되는 B-Tree 인덱스에 대해 설명드릴게요.
B-Tree 인덱스
B-Tree(Balanced Tree) 는 트리 구조를 기반으로 하는 데이터 구조입니다. 트리에서의 각 노드는 키와 포인터를 저장하고 있습니다. B-Tree는 균형 잡힌 구조로, 인덱스를 빠르고 효율적으로 조회할 수 있습니다. 데이터를 삽입하고 삭제할 때도 트리의 균형을 유지하여 검색 속도를 일정하게 유지합니다. 📊
B-Tree의 특징:
- 균형잡힌 트리로, 데이터의 검색 속도가 일정하게 빠릅니다.
- 범위 검색에 유리합니다. 예를 들어, A ~ D와 같은 범위로 데이터를 검색할 때 효율적입니다.
- 검색, 삽입, 삭제 등의 시간이 로그 시간 복잡도(log n)로 효율적입니다.
B-Tree 인덱스와 관련된 특징:
- 데이터를 정렬된 상태로 저장하므로, 범위 검색이나 정렬된 데이터를 조회할 때 성능이 좋습니다.
- 단점: 작은 데이터를 자주 변경하는 작업에는 오버헤드가 발생할 수 있습니다.
3. 클러스터 방식과 비클러스터 방식의 차이점 🔄
이제 인덱스가 어떻게 실제 데이터와 연결되는지, 그리고 클러스터 방식과 비클러스터 방식의 차이를 살펴보겠습니다.
클러스터 방식 (Clustered Index)
클러스터 인덱스는 데이터를 실제 레코드의 순서대로 저장하는 방식입니다. 즉, 인덱스가 데이터의 물리적 순서를 결정합니다. 한 테이블에 클러스터 인덱스는 하나만 존재할 수 있습니다. 왜냐하면, 데이터를 물리적으로 재배치해야 하기 때문입니다.
특징:
- 속도: 데이터가 물리적으로 순서대로 저장되기 때문에, 범위 검색 시 매우 효율적입니다.
- 정렬: 데이터가 인덱스 순서대로 정렬되어 있어, 정렬된 상태에서 조회하는 데 유리합니다.
- 단점: 데이터의 삽입/삭제가 많으면 인덱스의 재구성이 필요해 성능에 영향을 줄 수 있습니다.
비클러스터 방식 (Non-Clustered Index)
비클러스터 인덱스는 데이터와 인덱스가 별도로 저장되는 방식입니다. 즉, 인덱스는 데이터의 물리적 순서를 결정하지 않으며, 각 인덱스 항목은 포인터를 통해 데이터를 찾습니다. 테이블 당 여러 개의 비클러스터 인덱스를 만들 수 있습니다.
특징:
- 속도: 데이터가 물리적으로 정렬되어 있지 않기 때문에, 범위 검색에는 비클러스터 인덱스가 클러스터 인덱스보다 느릴 수 있습니다.
- 효율성: 비클러스터 인덱스는 하나의 테이블에 여러 개를 만들 수 있기 때문에, 다양한 쿼리에 대해 효율적으로 사용될 수 있습니다.
- 단점: 클러스터 인덱스보다 검색 속도가 다소 느릴 수 있습니다.
클러스터와 비클러스터 인덱스의 비교
특징 | 클러스터 인덱스 | 논클러스터 인덱스 |
데이터 저장 방식 | 데이터가 물리적으로 정렬됨 | 데이터와 인덱스가 별도로 저장 |
속도 | 범위 검색 및 정렬에 빠름 | 검색 속도는 빠르지만 범위 검색은 느릴 수 있음 |
인덱스 개수 | 하나만 존재 가능 | 여러 개 가능 |
효율성 | 데이터가 자주 변경되면 성능 저하 가능 | 변경이 자주 일어나도 성능에 큰 영향을 미치지 않음 |
사용 예시 | ID, 날짜 등의 자주 검색되는 범위 | 자주 사용되는 컬럼에 대해 효율적 사용 가능 |
택배 운송하는 사람들은 택배를 효율적으로 차에 쌓는 것도 중요하지만
효율적인 일처리를 위해 물건이 망가지지 않을 정도로만 효율적으로 쌓는 센스가 필요
4. 인덱스를 활용하는 방법 🧑💻
인덱스는 데이터베이스 성능을 크게 향상시킬 수 있습니다. 인덱스를 활용하는 방법을 알아봅시다:
- 검색 최적화: 자주 사용되는 검색 조건(예: WHERE, JOIN 조건)에 인덱스를 추가하여 조회 속도를 높일 수 있습니다.
- 범위 검색: BETWEEN, IN 등의 범위 검색을 자주 사용하는 경우 클러스터 인덱스를 활용하면 성능이 뛰어납니다.
- 중복 데이터 최소화: 고유한 값을 가지는 컬럼(예: 주문 ID, 고유 이메일 주소)에 인덱스를 추가하여 빠르게 검색할 수 있습니다.
인덱스를 언제 사용할까?
- 자주 검색되는 컬럼에 인덱스를 추가하면 쿼리 속도를 높일 수 있습니다.
- 데이터가 자주 변경되지 않는 컬럼(예: 사용자 ID, 날짜)에는 클러스터 인덱스를, 자주 변경되는 컬럼에는 비클러스터 인덱스를 고려하는 것이 좋습니다.
- 복합 인덱스: 여러 컬럼을 조합한 인덱스는 여러 조건을 동시에 처리할 때 유용합니다.
정리 🎯
인덱스는 데이터베이스 성능을 최적화하는 데 필수적인 요소입니다. 클러스터 인덱스와 비클러스터 인덱스는 각각의 장단점이 있으며, 사용하는 상황에 따라 적절하게 선택해야 합니다. 범위 검색이 많은 테이블에는 클러스터 인덱스를, 다양한 쿼리를 빠르게 처리해야 하는 경우에는 비클러스터 인덱스를 사용하는 것이 좋습니다.
인덱스를 잘 활용하면 데이터 조회 속도가 눈에 띄게 향상될 수 있으므로, 테이블 설계 시 신중하게 고려하는 것이 중요합니다.
실습 복습
CREATE DATABASE day3_2;
USE day3_2;
CREATE TABLE account(nickname VARCHAR(30) NOT NULL PRIMARY KEY,
address VARCHAR(100),
manner_point INT,
reg_date DATETIME);
/*
테이블 만들기 & 메인키 지정
NOT NULL PRIMARY KEY :
CREATE TABLT account
(자료명 자료형(크기) NOT NULL PRIMARY KEY,
자료명 자료형(크기),
...);
*/
CREATE TABLE market(market_id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
seller VARCHAR(30),
product VARCHAR(30),
amount INT,
price BIGINT,
reg_date DATETIME,
FOREIGN KEY (seller) REFERENCES account(nickname));
/*
테이블 값 입력하기
INSERT INTO 표이름 (항목 이름, seller, age, ph)
VALUES ('데이터 값', '개똥', '말똥', 20, '01011112222')
INSERT INTO 표이름 VALUES ('문자열','',0,0,'2023-03-07 10:00:00')
*/
/*테이블을 새로 만들 때 (column1,2에 대해 인덱스를 만드는 경우):*/
CREATE TABLE table_name(
column1 datatype,
column2 datatype,
column3 datatype,
INDEX index1_name (column1),
INDEX index2_name (column2));
/*이미 만들어진 테이블 스키마를 수정할 때:*/
ALTER TABLE table_name
ADD INDEX index_name (column_name);
MySQL 컬럼 옵션: 다양한 설정과 특징들 🛠️
MySQL에서 테이블을 만들 때 각 컬럼에 다양한 옵션을 설정할 수 있습니다. 컬럼 옵션은 데이터베이스의 구조와 데이터를 어떻게 처리할지 결정하는 중요한 역할을 합니다. 오늘은 CREATE TABLE 구문에서 사용할 수 있는 여러 가지 컬럼 옵션들에 대해 알아보겠습니다.
1. MySQL 컬럼 옵션이란? 🤔
컬럼 옵션은 데이터베이스 테이블을 정의할 때 각 컬럼에 대해 제약 조건이나 특정 속성을 지정하는 것입니다. 예를 들어, NOT NULL, UNIQUE, DEFAULT 등의 옵션을 통해 데이터를 유효성 검사하고, 삽입된 데이터의 상태를 조정할 수 있습니다. 이러한 옵션들은 데이터 무결성을 보장하고 성능을 향상시키는 데 도움을 줍니다.
2. MySQL 컬럼 옵션 종류 및 특징 🔧
아래는 MySQL에서 자주 사용되는 컬럼 옵션과 그 기능을 정리한 표입니다.
컬럼 옵션 | 설명 | 특징 |
NOT NULL | 컬럼에 NULL 값을 허용하지 않음. | 데이터 삽입 시 해당 컬럼에 값이 반드시 있어야 함. |
DEFAULT | 컬럼에 값이 지정되지 않았을 경우 기본값을 설정. | DEFAULT 값을 설정하여, 명시적으로 값을 입력하지 않으면 자동으로 설정된 기본값이 사용됨. |
UNIQUE | 컬럼 값이 고유해야 함. 즉, 중복 값을 허용하지 않음. | 테이블 내에서 해당 컬럼의 값은 유일해야 하며, 중복된 값을 삽입하려 하면 오류가 발생. |
PRIMARY KEY | 테이블에서 기본 키로 설정된 컬럼. 중복 및 NULL 값을 허용하지 않음. | 기본 키는 UNIQUE 및 NOT NULL을 자동으로 포함. 하나의 테이블에 하나만 존재 가능. |
AUTO_INCREMENT | 숫자 타입 컬럼에서 자동으로 증가하는 값을 설정. 주로 기본 키로 사용. | 데이터가 삽입될 때마다 값이 자동으로 증가하여 주로 ID 컬럼에 사용됨. |
INDEX | 컬럼에 인덱스를 설정하여 검색 속도를 향상시킴. | 데이터 조회 성능을 높일 때 사용되며, 자주 조회되는 컬럼에 유용. |
CHECK | 컬럼 값에 대한 조건을 설정 (MySQL 8.0 이상). | 특정 조건을 만족하는 값만 컬럼에 삽입 가능. 예를 들어, CHECK(age > 0)과 같이 사용할 수 있음. |
UNSIGNED | 양의 정수만 허용하는 옵션. | INT UNSIGNED와 같이 사용되며, 음수 값은 허용되지 않음. |
ZEROFILL | 숫자 타입 컬럼에 0으로 채운 값을 저장. | 숫자 컬럼에 0을 채워서 지정된 길이로 출력되도록 설정. 예: 000123과 같이. |
CHARACTER SET | 컬럼에 사용할 문자 집합을 설정. | 예: CHARACTER SET utf8로 설정하면 해당 컬럼은 UTF-8 문자 인코딩을 사용. |
COLLATE | 컬럼에 대한 정렬 규칙을 설정. | 예: COLLATE utf8_general_ci로 설정하면, 해당 컬럼에 대해 대소문자 구분 없이 정렬. |
COMMENT | 컬럼에 대한 설명을 추가. | 테이블의 구조를 명확히 할 수 있도록 문서화 용도로 사용. |
3. 예시를 통한 컬럼 옵션 활용 📑
앞서 소개한 다양한 옵션을 실제 MySQL 테이블에 어떻게 적용할 수 있는지 예시를 들어보겠습니다.
CREATE TABLE account (
nickname VARCHAR(30) NOT NULL PRIMARY KEY, -- 기본 키, NULL 값 허용하지 않음
address VARCHAR(100), -- 기본적으로 NULL 값 허용
age INT NOT NULL CHECK (age >= 18), -- 나이는 18세 이상이어야 함
email VARCHAR(100) UNIQUE, -- 이메일은 고유해야 함
account_balance DECIMAL(10, 2) DEFAULT 0.00, -- 기본 잔액 0.00 설정
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- 기본값은 현재 시간
user_id INT AUTO_INCREMENT, -- 자동 증가하는 사용자 ID
INDEX idx_address (address) -- 인덱스 추가: 주소로 검색 시 성능 향상
);
위 예시에서 사용된 각 컬럼 옵션을 하나씩 설명하겠습니다:
- NOT NULL: nickname은 반드시 값이 있어야 하며, 기본 키로 사용됩니다.
- PRIMARY KEY: nickname은 테이블에서 유일한 값이어야 하므로 중복된 값이 들어갈 수 없습니다.
- CHECK: age는 18세 이상만 허용하도록 제한됩니다.
- UNIQUE: email은 고유한 값을 가져야 하므로 중복된 이메일을 입력할 수 없습니다.
- DEFAULT: account_balance는 값을 입력하지 않으면 자동으로 0.00으로 설정됩니다.
- AUTO_INCREMENT: user_id는 매번 새로운 레코드가 삽입될 때마다 자동으로 증가합니다.
- INDEX: address 컬럼에 인덱스를 추가하여 해당 컬럼을 자주 검색할 때 성능을 향상시킵니다.
4. 결론 🎯
MySQL에서 컬럼 옵션은 데이터베이스의 성능을 최적화하고, 데이터 무결성을 보장하는 데 중요한 역할을 합니다. 각 컬럼에 적절한 옵션을 설정하여, 데이터의 정확성과 속도를 동시에 만족시킬 수 있습니다.
실습코드
USE day_4;
/*
CREATE TABLE account(nickname VARCHAR(30) NOT NULL PRIMARY KEY,
address VARCHAR(100),
manner_point INT,
reg_date DATETIME,
phone_number VARCHAR(15) UNIQUE
);
CREATE TABLE market(market_id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
seller VARCHAR(30),
product VARCHAR(30),
amount INT,
price BIGINT,
reg_date DATETIME,
FOREIGN KEY (seller) REFERENCES account(nickname));
*/
/*
INSERT INTO account VALUES('김영진', '서울', 100, '2023-03-07 10:10:10', '010-1234-1234');
INSERT INTO account VALUES('김민준', '인천', 53, '2023-03-07 10:10:10', '010-1234-2345');
INSERT INTO account VALUES('나수아', '부산', 45, '2023-03-09 12:48:20', '010-1234-3456');
INSERT INTO account VALUES('남건우', '분당', 17, '2023-02-21 23:54:00', '010-1234-4567');
INSERT INTO account VALUES('민지환', '서울', 43, '2023-02-16 17:54:24', '010-1234-5678');
INSERT INTO account VALUES('홍진호', '천안', 60, '2022-02-02 02:02:02', '010-1234-6789');
INSERT INTO account VALUES('조승우', '김해', 88, '2022-12-26 00:00:00' , '010-1234-7890');
INSERT INTO account VALUES('이가은', '서울', 78, '2023-03-01 10:55:00' , '010-5678-1234');
INSERT INTO account VALUES('최하린', '목포', 1, '2022-11-06 18:45:05', '010-5678-2345');
INSERT INTO account VALUES('장승우', '오산', 13, '2022-12-24 12:00:00', '010-5678-3456');
INSERT INTO market VALUES(NULL, '김영진', '닌텐도스위치', 1, 100000, '2023-03-07 10:10:10');
INSERT INTO market VALUES(NULL, '김민준', '사과', 50, 1300, '2023-03-07 10:10:10');
INSERT INTO market VALUES(NULL, '나수아', 'PS5', 2, 350000, '2023-03-09 12:48:20');
INSERT INTO market VALUES(NULL, '남건우', '아이폰14', 35, 1000000, '2023-02-21 23:54:00');
INSERT INTO market VALUES(NULL, '민지환', '책상', 10, 80000, '2023-02-16 17:54:24');
INSERT INTO market VALUES(NULL, '홍진호', '벙커벙커', 22, 222222, '2022-02-02 02:02:02');
INSERT INTO market VALUES(NULL, '조승우', '뮤지컬 티켓', 3, 80000, '2022-12-26 00:00:00');
INSERT INTO market VALUES(NULL, '이가은', '콜라', 35, 500, '2023-03-01 10:55:00');
INSERT INTO market VALUES(NULL, '최하린', '핸드크림', 12, 4500, '2022-11-06 18:45:05');
INSERT INTO market VALUES(NULL, '장승우', '이어폰', 2, 90000, '2022-12-24 12:00:00');
*/
/*
SELECT name
FROM market
ORDER BY name ASC;
*/
SELECT * FROM day_4.market;
SELECT SUM(amount), AVG(amount), min(price), max(price) From market;
SELECT seller, COUNT(product) FROM market GROUP BY seller;
SELECT seller, SUM(amount), MAX(price) FROM market GROUP BY seller;
'computing' 카테고리의 다른 글
20250327_java4 (자바 자료형, 연산자, 형변환 핵심요약) (1) | 2025.03.27 |
---|---|
20250325_OS4 (1) | 2025.03.25 |
AndroidStudio 알아보기 [app-manifest-AndroidManifest.xml] (2) | 2025.03.20 |
AndroidStudio 알아보기 (0) | 2025.03.20 |
20250318_OS3 (0) | 2025.03.18 |