[문제점]
MariaDB에서는 FK 생성 시에 참조 키를 빠르게 확인하고 테이블 스캔을 하지 않으려고 인덱스를 생성함.
[테스트]
1. 스크립트
CREATE DATABASE ADB_TEST ;
-- ADS_기업
CREATE TABLE `ADB_TEST`.`ADS_CO` (
`CO_NO` DECIMAL(9) NOT NULL, -- 기업번호
`CO_NM` VARCHAR(100) NULL, -- 기업명
`HDOF_ADDR` VARCHAR(500) NOT NULL, -- 본사주소
`DLG_TEL_NO` VARCHAR(20) NULL, -- 대표전화번호
`DLG_DRTR_NM` VARCHAR(100) NOT NULL, -- 대표이사명
`ESTB_DT` VARCHAR(8) NULL, -- 설립일자
`SALES_AMT` DECIMAL(20) NULL COMMENT '매출금액|매출액(단위 : 원)||', -- 매출금액
`SALES_AMT_BASE_DT` VARCHAR(8) NULL, -- 매출금액기준일자
`CO_FORM_CODE` VARCHAR(6) NOT NULL COMMENT '기업형태코드|기업형태코드||', -- 기업형태코드
`EMP_CNT` DECIMAL(9) NOT NULL, -- 사원수
`REG_DTTM` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '등록일시|최초 등록일시를 기록한다.||', -- 등록일시
`ALT_DTTM` DATETIME NULL COMMENT '수정일시|수정일시를 기록한다.||' -- 수정일시
)
DEFAULT CHARACTER SET = 'utf8'
DEFAULT COLLATE = 'utf8_bin'
ENGINE = InnoDB
COMMENT 'ADS_기업|기업정보||';
-- ADS_기업
ALTER TABLE `ADB_TEST`.`ADS_CO`
ADD CONSTRAINT `ADS_CO_PK` -- ADS_기업 기본키
PRIMARY KEY (
`CO_NO` -- 기업번호
);
-- ADS_채용
CREATE TABLE `ADB_TEST`.`ADS_RECT` (
`RECT_NO` DECIMAL(9) NOT NULL, -- 채용번호
`RECT_TITLE` VARCHAR(100) NOT NULL, -- 채용제목
`PSNCH_NM` VARCHAR(100) NULL, -- 담당자명
`RECT_START_DTTM` DATETIME NOT NULL, -- 채용시작일시
`RECT_END_DTTM` DATETIME NOT NULL, -- 채용종료일시
`LWST_SALARY_AMT` DECIMAL(20) NOT NULL COMMENT '최저급여금액|최저 급여 금액(단위 : 원)||', -- 최저급여금액
`BEST_SALARY_AMT` DECIMAL(20) NOT NULL COMMENT '최고급여금액|최고 급여 금액(단위 : 원)||', -- 최고급여금액
`CO_NO` DECIMAL(9) NOT NULL, -- 기업번호
`REG_DTTM` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '등록일시|최초 등록일시를 기록한다.||', -- 등록일시
`ALT_DTTM` DATETIME NULL COMMENT '수정일시|수정일시를 기록한다.||' -- 수정일시
)
DEFAULT CHARACTER SET = 'utf8'
DEFAULT COLLATE = 'utf8_bin'
ENGINE = InnoDB
COMMENT 'ADS_채용|채용 정보||';
-- ADS_채용
ALTER TABLE `ADB_TEST`.`ADS_RECT`
ADD CONSTRAINT `ADS_RECT_PK` -- ADS_채용 기본키
PRIMARY KEY (
`RECT_NO` -- 채용번호
);
-- ADS_채용
ALTER TABLE `ADB_TEST`.`ADS_RECT`
ADD CONSTRAINT `ADS_RECT_FK01` -- ADS_기업 -> ADS_채용
FOREIGN KEY (
`CO_NO` -- 기업번호
)
REFERENCES `ADB_TEST`.`ADS_CO` ( -- ADS_기업
`CO_NO` -- 기업번호
);
2. 인덱스 확인
select * from mysql.innodb_index_stats a where a.database_name = 'ADB_TEST' and a.table_name = 'ADS_RECT' ;
- FK에 대해서 인덱스가 생성된 것을 확인
3. FK 컬럼으로 인덱스 생성
CREATE INDEX ADS_RECT_IX01 ON ADS_RECT(CO_NO);
4. 인덱스 확인
select * from mysql.innodb_index_stats a where a.database_name = 'ADB_TEST' and a.table_name = 'ADS_RECT' ;
ALTER TABLE ADS_RECT DROP INDEX ADS_RECT_IX01;
에러 발생: Cannot drop index 'ADS_RECT_IX01': needed in a foreign key constraint
- FK 인덱스 대신 사용하는 인덱스이기 때문에 삭제 불가
6. FK 삭제
ALTER TABLE ADS_RECT DROP FOREIGN KEY ADS_RECT_FK01;
select * from mysql.innodb_index_stats a where a.database_name = 'ADB_TEST' and a.table_name = 'ADS_RECT' ;
- FK 대신 사용하는 인덱스이더라도 FK삭제 시에 해당 인덱스는 삭제되지 않음.
ALTER TABLE ADS_RECT DROP INDEX ADS_RECT_IX01;
select * from mysql.innodb_index_stats a where a.database_name = 'ADB_TEST' and a.table_name = 'ADS_RECT' ;
10. FK 생성
ALTER TABLE `ADB_TEST`.`ADS_RECT`
ADD CONSTRAINT `ADS_RECT_FK01` -- ADS_기업 -> ADS_채용
FOREIGN KEY (
`CO_NO` -- 기업번호
)
REFERENCES `ADB_TEST`.`ADS_CO` ( -- ADS_기업
`CO_NO` -- 기업번호
);
11. 인덱스 확인
select * from mysql.innodb_index_stats a where a.database_name = 'ADB_TEST' and a.table_name = 'ADS_RECT' ;
12. FK 삭제
ALTER TABLE ADS_RECT DROP FOREIGN KEY ADS_RECT_FK01;
select * from mysql.innodb_index_stats a where a.database_name = 'ADB_TEST' and a.table_name = 'ADS_RECT' ;
- FK를 삭제하더라도 FK 인덱스는 삭제되지 않음.
14. FK 컬럼 변경
ALTER TABLE ADB_TEST.ADS_RECT ADD CO_NM VARCHAR(100); CREATE UNIQUE INDEX ADS_CO_UK01 ON ADS_CO(CO_NM); ALTER TABLE `ADB_TEST`.`ADS_RECT` ADD CONSTRAINT `ADS_RECT_FK01` -- ADS_기업 -> ADS_채용 FOREIGN KEY ( `CO_NM` ) REFERENCES `ADB_TEST`.`ADS_CO` ( -- ADS_기업 `CO_NM` );
에러 발생: Duplicate key name 'ADS_RECT_FK01'
- FK가 존재하지 않아도 FK 인덱스가 존재하기 때문에 FK 생성 시 에러가 발생함.
결론: FK는 삭제 시에도 인덱스로 남아있기 때문에 필요한 인덱스라면 FK가 아닌 인덱스를 생성하는 것이 좋을 것 같음.
'MariaDB > SQL' 카테고리의 다른 글
| [에러] Incorrect datetime value: '' (0) | 2017.08.02 |
|---|---|
| [MariaDB][SQL]사용자변수를 활용한 DENSE_RANK 분석함수 작성 (0) | 2017.03.09 |
| [MariaDB]TIMEDIFF 함수를 활용한 시간 계산 SQL (0) | 2017.02.17 |