관계형 데이터베이스 실전 입문 - 13. 리팩터링 최적의 해결책

1. 리팩터링

DB의 리팩터링은 한 개 이상의 테이블 설계를 변경하는 작업이다. 정의를 바꾸는 건 ALTER 명령 한 번으로 해결할 수 있다. 그러나 현실적으로 정의를 변경하는 작업은 그렇게 간단하지 않다. 응용프로그램이 운용중이라면 이미 데이터가 저장돼 있을 것이고 테이블의 엑세스에 의존하는 처리가 있기 때문이다.

이처럼 리팩토링할 때 가장 어려운 점은 리팩터링이 서비스 출시 전에만 일어나는 작업이 아니라는 것이다.

→ 실무에서 서비스를 가동하면서 DB 설계를 지속해서 변경하는 작업이 필요하게 된다.

서비스에 영향을 주지 않아야 하는 것은 DB의 리팩터링뿐만 아니라 응용프로그램의 리팩터링도 마찬가지이지만 DB의 리팩터링은 특유의 어려움이 있다.

DB 리팩터링은 어려운 작업

DB의 스키마는 응용프로그램과 밀접한 관련이 있다. 테이블의 정의를 변경하는 작업에 따라 그 테이블에 엑세스하는 모든 처리가 영향을 받게 된다.

→ DB를 개선하려면 실로 다양한 조정이 필요하다. 조정의 대상은 다음과 같다.

  • 쿼리의 재작성
  • 외부키나 그 외의 제약 확인
  • 뷰의 수정
  • 트리거의 수정
  • 스토어드 프로시저의 수정

다양한 응용프로그램에 대한 DB 환경

상황을 어렵게 하는 것은 DB에 엑세스하는 응용프로그램이 한 개뿐이라고 할 수 없다는 것이다. 공통 DB를 여러 개의 응용프로그램이 참조하는 것은 흔한 일이다.

변경은 번거롭고 시간도 걸린다. 게다가 다른 우선순위가 높은 작업이 있으면 그쪽 작업을 먼저 처리해야 할지도 모른다. 여러 개의 응용프로그램이 같은 DB에 엑세스하고 있으면 다양한 조정이 필요하다.

왜 리팩터링이 필요한가?

원래의 DB에 결함이 있으면 이를 수정해야 한다. 리팩터링은 본질적으로 해야만 하는 작업이다.

만약 적적ㄹ하지 않게 설계된 DB를 그대로 방치하면 응용프로그램의 유지보수나 품질, 개발 효율에 영향을 준다.

예를 들어, 정규화되어 있지 않으면 연산에 따른 쿼리작성이 어렵다.

DB 설계의 결함은 한마디로 기술적인 부채와 같다.

리팩터링의 절차

리팩터링을 할 때는 다음과 같은 절차가 필요하다.

  1. 작업 전, 후의 백업
  2. 스키마 변경
  3. 데이터 이행
  4. 응용프로그램 이행을 위한 트리거 작성
  5. 응용프로그램 배포
  6. 이행을 위한 트리거 삭제
  7. 이행을 위한 컬럼 삭제

단순히 ALTER로 정의를 변경하는 것뿐만 아니라 절차를 거쳐 응용프로그램의 영향을 최소화하면서 응용프로그램의 페이스에 맞게 이행할 수 있다.

스키마의 이행기간

DB 스키마를 변경할 때, 한 번에 대상 스키마를 변경하는 것이 아닌 일단 중간 단계를 거치는 기술을 이용하는 경우가 있다. 한 번에 원하는 상태로 변경하면 좋겠지만, 응용프로그램을 수정하는데 시간이 걸릴 때나 여러 개의 응용프로그램이 같은 DB를 사용할 때는 조정하는 데 시간이 걸릴 것이다.

기존 로직의 응용프로그램이 일정 기간 존재하므로 기존의 스키마와 변경한 스키마가 모두 있어야 하는 경우가 생긴다. → DB의 리팩터링에는 이행 기간이 필요할 때가 있다.

반복적인 리팩터링

최근 애자일 등의 반복적인 개발 방법을 사용하고 있다. 애자일 방식의 개발은 응용프로그램의 설계를 개발 초기에 결정하는 것이 아닌 반복적으로 추가하거나 개선하는 것이다.

문제는 응용프로그램의 코드만 반복해서 수행하고, 정의된 DB 스키마는 변경하지 않는 경우가 많다. 응용프로그램 쪽에서 영속화해야 하는 오브젝트의 구조에 변화가 있으면 DB 쪽의 구조도 그에 따라야 한다.

→ 애자일 등의 반복적인 개발 방법을 수행할 땐 응용프로그램뿐만 아니라 DB 리팩터링도 반복 수행해야 한다.

회귀테스트

리팩터링을 수행하는데 있어 중요한 것은 리팩터링을 실시한 후에도 기능이 손상되지 않아야 한다.

응용프로그램의 기능이 손상되지 않았는지 확인하는 방법은 테스트밖에 없다.

즉 리팩터링을 수행하기 전에 충분한 테스트 케이스가 있어야 한다. 테스트 없이는 리팩터링을 할 수 없다.

벤치마크 테스트

DB의 리팩터링을 수행하는 데 있어 놓치기 쉬운 것이 성능이다.

성능이 저하되지 않았는지 확인하는 방법은 벤치마크밖에 없다.

벤치마크를 수행할 때는 테스트 환경을 실전 환경과 같게 충실하게 재현하는 것이 중요하다. 하드웨어의 스팩이나 OS의 종류는 물론이고 테스트 데이터의 규모(사이즈)도 실전에 맞춰야 한다.

또한, 테스트 환경만 테스트용으로 적은 데이터를 사용하는 경우가 있다. 개발 중에 자주 테스트를 할 때는 적은 테스트 데이터로는 괜찮지만, 데이터 사이즈가 너무 작으면 성능 문제가 잘 드러나지 않는다.

→ 벤치마크 테스트를 수행할 때는 반드시 충분한 크기의 데이터를 준비해야 한다.

벤치마크를 수행하는 데 있어서 중요한 것은 실전 환경과 같은 시스템을 사용하는 것이다. 성능이나 구성이 다른 시스템으로 벤치마크를 하는 것은 실전 환경의 성능을 예측하는데 그다지 도움이 되지않는다. 최근에는 퍼블릭 클라우드를 사용해 테스트 환경을 준비하는 것이 어렵지 않기 때문에 같은 환경, 시스템을 두고 테스트를 하자.

마이그레이션 사용의 추천

반복적인 소프트웨어 개발은 버전 관리를 해야 한다. 문제가 있다면 임의의 시점으로 되돌리거나, 변경 사항을 나중에 추적할 수 있다는 편리성을 이용해 기존의 코드를 대담하게 변경할 수 있다.

그러나 DB 스키마는 단순한 버전관리를 적용할 수 없다. 어느 시점 이전의 정의로 변경하는 명령은 존재하지 않기 때문이다.

테이블 정의를 변경할 때 사용하는 명령은 ALTER TABLE이다. ALTER TABLE은 테이블을 특정 정의로 변경하는 것이 아니고 현재의 테이블 정의와 비교한 다음에 다른 부분을 제거하여 그 차이를 해소하는 형태로 해야 한다. 이와 같은 이유로 DB에는 단순히 테이블 정의의 diff(차이)를 얻을 뿐 버전관리가 어렵다.

그래서 등장한 것이 마이그레이션 스크립트다.

마이그레이션 스크립트란 ROR(루비온레일즈)의 액티브레코드에서 도입된 구조다. DB에 관한 개별 변경 사항을 스크립트로 작성해 DB 스키마의 변경을 관리한다. 스크립트는 순서를 붙일 수 있으며 스크립트를 순서대로 실행해 임의의 시점으로 DB 스키마를 추적할 수 있는 구조다.

버전 관리를 할 수 있다고 해도 소스 코드의 버전 관리와는 다르다.

→ DB 스키마는 버전의 분기를 할 수 없다. 따라서 스키마 버전은 앞으로 가거나 뒤로 되돌리는 직선적인 이력의 상태만 전환한다.

또한, 마이그레이션 스크립트를 실행하는 것은 시간이 걸린다. ALTER TABLE에 걸리는 시간은 하드웨어의 성능, 데이터 사이즈나 인덱스의 수에 따라 좌우된다.

마이그레이션은 버전을 쉽게 변경할 수 없지만, DB에 대한 변경을 관리하는 안전장치로서는 충분히 도움이 된다.


마이그레이션 스크립트를 사용할 때는 스크립트의 테스트도 잊지 않고 실행해야 한다. 스크립트에 버그가 있다면 버전의 변경이 어렵다.

백업으로도 가능하지만, 백업은 스키마뿐만 아니라 데이터까지 되돌려 버리므로 문제가 된다. 데이터는 최신의 상태로 스키마만 되돌리고 싶은 경우라면 백업은 대응하기 어렵다.

트리거를 사용해 두 개의 테이블 사이를 동기화하기

DB의 이행 기간에는 이행 전과 이행 후를 정의한 테이블이 동시에 존재한다. 이때 다른 두 개의 테이블에서 같은 데이터를 참조할 때는 어떻게 해야 할까? 한쪽만 데이터를 갱신하면 데이터에 불일치가 생긴다.

→ 여기서 트리거가 필요하다.

어떤 테이블을 갱신할 때에 다른 테이블에 같은 데이터를 저장하고 싶은 요구를 해결할 수 있는 최적의 도구는 바로 트리거다. 두 개의 테이블 사이에 양방향 트리거를 걸면 항상 데이터가 동기화된다. 또한, 트리거로 동기화를 구현할 때는 트리거에 의한 갱신이 순환되지 않게 주의해야 한다.

이행 기간이 끝나고 기존 테이블을 삭제했다면 트리거도 삭제해야 한다. 트리거도 마이그레이션에서 관리하도록 하는 것이 좋으며, 트리거의 테스트도 잊지말고 실시해야 한다.

2. 리팩터링의 종류

인덱스의 추가, 삭제

가장 간단한 것이 인덱스의 추가와 삭제다. 인덱스의 추가나 삭제를 수행한다고 해도 쿼리를 바꿀 필요는 없기 때문이다.

→ 인덱스를 추가하거나 삭제해도 논리적인 의미가 바뀌지 않으므로 재작성할 필요가 없다.

그러나 기본키나 유니크 키에 따라 고유성 제약을 도입하거나 삭제할 때는 테이블의 논리적인 의미가 변하므로 주의해야한다. 그렇지 않으면 테이블의 의미는 절대 변하지 않는다.

인덱스가 필요한 쿼리를 발견했다면 적극적으로 리팩터링을 하자. 인덱스의 변경은 성능에 영향이 있다. 인덱스를 변경한 후에는 벤치마크 테스트로 성능 저하가 생기지 않았는지 확인하자.

컬럼 이름 변경

컬럼의 이름이 적절하지 않다고 생각될 때는 이름을 변경하는 리팩터링을 수행할 때도 있다.

이행 기간이 필요할 경우 다른 이름으로 같은 데이터를 갖는 컬럼을 두 개 갖도록 해야 한다. 그 사이에 신규컬럼과 기존 컬럼 중 어느 쪽을 변경해도 같은 데이터가 되도록 트리거를 사용해 동기화한다.

다음은 행을 삽입할 때 컬럼의 데이터를 동기화하는 트리거다.

## MySQL용
delimiter //
CREATE TRIGGER bi_students
BEFORE INSERT ON fighters FOR EACH ROW
BEGIN
	IF NEW.name IS NULL OR NEW.name = ''
	THEN
		SET NEW.name := NEW.full_name;
	ELSEIF NEW.full_name IS NULL OR NEW.name = ''
	THEN
		SET NEW.full_name = NEW.name;
	END IF;
END;//
delimiter ;

name이라는 컬럼의 이름을 full_name으로 변경하는 시나리오를 전제로 하고 있다. 두 컬럼의 값이 지정된 경우에도 다른 쪽에 같은 데이터를 저장한다. INSERT 용 트리거이므로 실제로는 UPDATE 용도 필요하다.

응용프로그램에서 어느 쪽 컬럼에 접근해도 같은 데이터를 얻을 수 있고 어느 쪽 컬럼을 갱신해도 결과가 바뀌지 않는다는 점이 포인트다. 이행 기간이 끝나면 외부키 등을 조정하고 기존 컬럼과 트리거를 제거해야 한다.

NOT NULL 제약의 도입

테이블을 1NF 하려면 모든 컬럼에 NULL을 없애야 한다. 나중에라도 NOT NULL 제약을 추가하는 리팩터링을 수행하는 것이 중요하다.

NOT NULL 제약의 도입에는 그 컬럼을 NOT NULL로 할 수 있는지 판별하는 것이 포인트다. 이미 모든 행에 대해 해당 컬럼이 NULL이 아닌지, NULL이 있는 행에 적당한 초깃값을 대입할 수 있는지가 조건이 된다.

만약 NULL이 필요한 컬럼이라면 NOT NULL로 하는 것이 아니고 다른 테이블로 분리하는 설계가 필요하다.


가장 많이 하는 실수는 모든 컬럼에 NOT NULL 제약을 도입하는 것이다. 대상 테이블이 관계형 모델의 범주라면 NOT NULL을 도입해 1NF로 정규화하는 작업은 의미가 있다.

그러나, 즉 관계형 모델에서는 표현할 수 없는 데이터를 다루는 테이블이라면 NOT NULL 제약을 사용할 필요가 없다.

NOT NULL 제약을 추가하는 것뿐이라면 데이터 이행은 필요없지만 응용프로그램의 변경은 필요하다.

ALTER TABLE 명령으로 NOT NULL 제약을 도입하면 NULL이었던 곳의 값은 기본값으로 재작성된다.

→ 쿼리를 실행해 얻은 초기값이어도 NULL 이어도 같은 결과가 될 수 있도록 쿼리를(COALESCE 사용 등) 재작성하는 것이 좋다.

기본키의 정의 변경

기본키를 정하면 변경하지 않지만, 다음과 같은 경우에는 변경해야 할 때가 있다.

  • 기본키가 기약이 아닐 때
  • 기본키에서 다른 컬럼으로 함수 종속성이 없어졌을 때
  • 대리키에서 자연키로 변경하거나 그 반대

기본키가 변경할 경우 새로운 기본키가 고유성 제약을 충족하는 것이 중요하다. 기본키가 변경하기 전에 쿼리로 일관성을 확인하거나 유니크한 보조인덱스를 도입해두는 등의 방법이 효과적이다.

무손실 분해

정규화할 때 필요한 작업은 무손실 분해다. 자명하지 않은 함수 종속성, 자명하지도 암시적이지도 않은 결합 종속성을 발견했다면 무손실 분해를 통한 리팩터링이 필요하다.

무손실 분해도 이행 기간이 엇다면 어려울 부분은 없다. 이행 기간이 필요하면 새로운 테이블을 만들어 데이터 동기화가 필요하다.

데이터 동기화는 트리거를 사용하면 된다.

외부키 제약을 병용(ON UPDATE CASCADE)하는 방법도 있다.

다음은 이행 기간을 거쳐 함수 종속성을 해소 하는 쿼리다.

ALTER TABLE students
	ADD CONSTRINT FOREIGN KEY (name, age)
	REFERENCES student_prof (name, age)
	ON DELETE CASCADE ON UPDATE CASCADE;

양쪽의 테이블에 (name, age)라는 인덱스가 있다면 외부키 제약을 설정하여 students_prof 테이블에서 students 테이블로 데이터 동기화가 가능하다.

또한 다음 트리거를 사용해서 동기화가 가능하다.

delimiter //
CREATE TRIGGER bu_students
BEFORE UPDATE ON students FOR EACH ROW
BEGIN
	UPDATE students_prof
		SET age = NEW.age
		WHERE name = NEW.name;
END;//
CREATE TRIGGER bi_students
BEFORE INSERT ON students FOR EACH ROW
BEGIN
	IF NEW.age IS NULL OR NEW.age = 0 THEN
		SET NEW.age :=
			(SELECT age FROM student_prof
			WHERE name = NEW.name);
	ELSE
		REPLACE INTO student_prof
			(name, age)
			VALUES(NEW.name, NEW.age);
	END IF;
END;//
delimiter;

테이블의 수직 분할과 통합

여러 개의 테이블 사이에 직교성이 충족되지 않으면 테이블을 통합해야 한다. 직교성은 완전히 똑같은 테이블이라면 비교하기가 쉽지만 그렇지 않은 경우는 컬럼을 수직으로 분할해야 한다.

테이블의 수직 분할이란 암시적 결합 종속성에 의해 무손실 분해하는 것에 불과하다.

테이블의 통합은 어떤 테이블에 데이터를 옮기는 것이 될 것이다. 이행 기간이 필요하다면 불필요한 테이블은 별칭이나 변경할 수 있는 뷰의 형태로 남겨둬야 한다.

이처럼 모든 응용프로그램이 공통으로 엑세스하는 데이터와 각 응용프로그램이 개별적으로 필요한 데이터는 다른 테이블에 저장하는 것이 자연스러울 것이다.

관련 테이블의 실태

DB 설계 작업을 할 때 ERD를 사용하는 방법은 매우 일반적이다. ERD는 테이블을 전체적으로 볼 수 있어서 편리하지만, 관계형 모델에 대한 오해를 조장한다는 폐단이 있다.

ERD를 사용해 DB 설계를 할 때 자주 나오는 이야기가 관련 테이블이라는 개념이다. 외부키 제약으로 1:N의 관계에 있던 두 개의 테이블이 1:N 대신 M:N의 관계가 될 때 이 관계를 나타내기 위해 도입됐다.

그러나 관계형 모델에서는 관련 테이블이라는 개념이 없다.

→ 관련 테이블을 지나치게 의식하면 릴레이션의 실태를 알 수 없게 된다.

다음은 1:N 에서 M:N으로 변하는 경우다.

departments

학과 대표번호
컴퓨터 아키텍처 xx-xxxx-xxxx
데이터베이스 zz-zzzz-zzzz
컴파일러 yy-yyyy-yyyy

students

이름 학과 학년
정은오 컴퓨터 아키텍처 2
홍윤서 컴파일러 3
오민혁 데이터베이스 1
한혜린 데이터베이스 4
정승효 컴파일러 3

외부키 제약이 참조하는 쪽의 테이블에서 참조하는 키의 값에 중복이 생기면 M:N으로 바뀌게 된다.

→ 테이블의 기본키 구조에 변화가 필요하다.

위 표는 이름이라는 컬럼이 기본키다. 예를 들어 학과 컬럼이 기본키(이름)에 대해 여러 개의 값에 대응하는 경우는 키본키를 (이름)에서 (이름, 학과)로 변경하는 리팩터링이 필요하다. 리팩터링 결과는 다음표와 같다.

departments

학과 대표번호
컴퓨터 아키텍처 xx-xxxx-xxxx
데이터베이스 zz-zzzz-zzzz
컴파일러 yy-yyyy-yyyy

students

이름 학과 학년
정은오 컴퓨터 아키텍처 2
홍윤서 컴파일러 3
오민혁 데이터베이스 1
오민혁 컴파일러 1
한혜린 데이터베이스 4
정승효 컴파일러 3
정승효 컴퓨터 아키텍처 3

위 표처럼 구조를 바꾸면 학과 이외의 컬럼은 원래의 기본키인 이름에 대해 함수 종속하게 되므로 이는 자명하지 않은 함수 종속성이 되며, 2NF의 요건을 만족하지 않게 된다. 그래서 이 테이블을 무손실 분해하는 리팩터링이 필요하게 되고, 그 결과 새로운 테이블이 생성된다.

departments

학과 대표번호
컴퓨터 아키텍처 xx-xxxx-xxxx
데이터베이스 zz-zzzz-zzzz
컴파일러 yy-yyyy-yyyy

students_departments

이름 학과
정은오 컴퓨터 아키텍처
홍윤서 컴파일러
오민혁 데이터베이스
오민혁 컴파일러
한혜린 데이터베이스
정승효 컴파일러
정승효 컴퓨터 아키텍처

students

이름 학년
정은오 2
홍윤서 3
오민혁 1
한혜린 4
정승효 3

students_departments 테이블을 일반적으로 관련 테이블이라고 한다. 이처럼 관련 테이블을 도입하는 리팩터링은 사실 기본키의 구조를 바꾸고 그 다음에 정규화를 실시하는 2번에 걸친 리팩토링을 줄인 것이다.

관련 테이블을 도입한다는 개념은 본질적인 것이 아니고 사실 두 번의 리팩터링을 줄인 것이라고 이해하면 된다.

3. 리팩터링을 위한 모범 사례

정규화와 직교성

리팩터링은 DB의 구조에 문제가 있을 때 필요하므로 처음부터 문제가 발생하지 않게 설계하는 것이 중요하다.

처음 DB 설계부터 정규화나 직교성에 관해서 제대로 고려하고 있다면 이 작업을 할 일이 줄어들 것이다.

컬럼이 아닌 테이블을 추가

새로운 기능을 추가할 때 무의식중으로 컬럼을 추가하기 쉽다. 그러나 1NF의 요건을 만족하지 못할 가능성이 커지므로 주의해야 한다. 컬럼을 추가하려고 하면 다음 사항을 고려해야 한다.

  • 컬럼의 초기값이 있는가?
  • 기본키에 대해 함수 종속성이 있는가?

이러한 요구를 만족한다면 컬럼을 추가해도 문제없다. 그러나 컬럼을 추가하는 것 이상으로 추천하는 방법은 테이블을 추가하는 리팩터링이다.

기본키에 대한 함수 종속성이 있는 데이터가 있다면 키가 아닌 속성이 되므로 암시적 결합 종속성에 의해 무손실 분해를 할 수 있다.

무손실 분해한 두 개의 테이블에서 원래의 데이터를 구하고 싶을 때는 JOIN(결합) 하면 된다.

→ JOIN 하는 함수는 필연적으로 증가할 것이다.

JOIN은 어떤 점이 문제가 있어 느리다고 생각할까?

내부 테이블에 대해 기본키로 엑세스할 수 있는 실행 계획이라면 물리적인 페이지에 대한 엑세스는 한 행별로 한 번 증가할 뿐이다. 게다가 JOIN하는 기본키가 같은 의미의 컬럼으로 구성돼 있다면 기본키를 저장한 페이지의 정렬 순서에는 서로 관계가 있을 것이다.

→ 데이터의 국소성도 높아질 것이다. 테이블을 나눠서 생기는 성능 저하는 생각하는 것보다 훨씬 적다.

한편 컬럼 대신에 테이블을 추가하는 장점은 또 하나 있다. 우선 기존의 테이블이 리팩터링에 의한 비정규화의 위험에 노출되지 않는다는 점이다. 또한, 기존의 테이블을 변경하지 않으므로 그 테이블에 엑세스하기 위한 코드는 다시 작성할 필요가 전혀 없다.

새로운 테이블에 엑세스하는 새로운 기능만 구현하면 되므로 소스 코드의 리팩터링이 쉽다. 또한, 기존의 테이블에 손댈 필요가 없어서 DB의 리팩터링을 실시해도 가동중인 서비스에 영향을 주지 않는다.

SELECT * 을 사용하지 않는다.

SELECT _ 대신 구체적으로 참조하는 컬럼 명을 열거하자. SELECT _ 은 테이블에 정의된 순서로 컬럼이 정렬될 것을 기대한 서식이다. 또한, 쿼리의 결과에 포함된 컬럼의 수는 그 테이블의 정의를 바꾸면 응용프로그램에 영향을 주고 테이블의 변경에 대응하는 비용도 증가한다.

SELECT * 을 사용함으로서 생기는 문제의 본질은 응용프로그램의 처리가 컬럼 단위에 의존한다는 것이다.

테이블에 컬럼을 추가, 삭제해 컬럼의 위치가 밀리는 것은 필연적이다. SELECT * 을 사용하지 않고 필요한 컬럼을 구체적으로 기술하면 이 컬럼의 나오는 위치는 쿼리에 따라 결정되고 스키마와 독립되어 테이블 변경에 대해 강해진다.

SELECT * 을 사용하겠다면 int형 인수 타입이 아닌 JDBC의 드라이버

java.sql.ResultSET#getString(StringColumnLabel)

컬럼의 이름을 참조하는 방법을 사용하자.

응용프로그램을 소결합으로

여러 개의 응용프로그램에서 같은 DB에 엑세스하는 아키텍처에서는 이행 기간이 길어진다. 어떤 DB에 엑세스 하는 응용프로그램이 여러 개일 때는 이를 주로 사용하는 응용프로그램 외에는 직접 엑세스하지 못하도록 숨기는 방법이 있다. 메인으로 사용하지 않으면 소결합으로 대응하는 것이다.

소결합으로 구현해 DAO(Data Access Object)로 데이터 엑세스를 프로그램 내에서 숨기는 방법, Web API 등으로 완전히 프로그램에서 숨기는 방법을 생각할 수 있다.

이를 통해 DB 쪽을 변경한 경우에 응용프로그램 쪽의 수정할 곳이 적어지게 된다.

그러나 데이터 엑세스는 숨길 수 있지만 다른 응용프로그램에 엑세스하기 위한 인터페이스를 설계하거나 요구의 변화나 결합에 대응하기 위해 인터페이스를 유지 보수하지 않으면 안되므로 러닝커브가 있다는 단점이 있다.

결론

애자일 개발환경하에 DB 리팩터링은 필수 작업이다.

리팩터링은 단순히 ALTER를 사용해 테이블의 정의를 변경하는 것만으로 끝나는 작업이 아니다. 변경하고 나서 응용프로그램이 영향을 받지 않게 이행 기간을 마련하는 등 계획적으로 수행해야 한다. 또는 트리거를 사용하여 동기화가 필요하다.


Written by@Sunny Son
개발자는 오늘도 뚠뚠

GitHubFacebook