메뉴 바로가기 검색 및 카테고리 바로가기 본문 바로가기

한빛출판네트워크

IT/모바일

MySQL과 관련된 10가지 팁

한빛미디어

|

2002-08-01

|

by HANBIT

12,751

저자: 『Managing & Using MySQL, 2nd Edition』의 공동저자 조지 리스, 역 송종범

처음으로 MySQL을 배우려는 사람에게 이 소프트웨어는 당황스럽게 보일 수도 있다. 본기사에서는 MySQL 관리자, 설계자, 개발자에게 MySQL 설치와 관련된 퍼포먼스, 보안, 유지에 도움을 줄 수 있는 좋은 예제들을 설명할 것이다.

1. "root" 사용자 패스워드를 설정하고 사용자 명을 바꿔라.

MySQL을 설치한 후 가장 먼저 해야 할 일은 루트 사용자 패스워드를 설정하는 것이다.
 
[01:19:00] george@firenze$ mysqladmin -u root password "somepassword"
일단 패스워드를 설정했다면 "루트" 사용자의 이름을 다른 것으로 바꾸자. MySQL 서버를 공격하려는 해커는 수퍼유적의 권한을 갖고 있고 잘 알려진 사용자이기 때문에 대부분의 시스템에 존재하는 루트를 목표로 한다. "루트" 사용자의 이름을 바꾸면 해커일 수도 있는 공격자들이 야만스러운 공격을 시도하기 여렵게 되기 때문이다. 아래 명령은 "루트" 사용자 이름을 바꾸어 준다.
[01:25:29] george@firenze$ mysql -u root -p mysql
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 72 to server version: 4.0.0-alpha-log

Type "help;" or "\h" for help. Type "\c" to clear the buffer.

mysql> UPDATE user set user = "admin" where user = "root";
Query OK, 2 rows affected (0.00 sec)
Rows matched: 2  Changed: 2  Warnings: 0

mysql> quit;
Bye
[01:25:51] george@firenze$ mysqladmin -u root -p reload
Enter password:
물론, "admin" 보다 더 창의적인 이름을 택할 수도 있다.

2. 인터넷에서 MySQL을 숨겨라.

MySQL은 네트워크 서비스의 보안을 위한 매우 구체적인 레코드가 있다. 그럼에도 불구하고 인터넷에 직접적으로 MySQL을 노출하지 않는 것이 좋다. 방화벽 뒤에 MySQL을 숨기고 운영중인 애플리케이션 서버나 웹서버와 통신할 수 있게 될 때, 해커일 수도 있는 공격자가 공격할 수도 있는 경로를 저지할 수 있기 때문이다.

3. 다른 사용자들에 의해 MySQL 설치 디렉토리가 액세스되는 것을 보호하라.

첫째, MySQL은 "mysql" 같은 특정 사용자 아이디로 설치되어야 한다. 둘째, MySQL이외에 어느 사용자도 시스템의 MySQL 데이터 디렉토리에 접근할 수 없어야 한다. 다른 사용자가 당연스럽게 디렉토리에 접근할 수 있게 되면 MySQL 내부 보안과 절충하는 경로를 시작해야 한다. 데이터베이스 관리자라도 "mysql" 그룹에 가입되어서는 안된다. 대신, 대부분의 DBA 기능은 MySQL 자체를 통과하도록 한다. 파일 시스템 단계에서 일어날 필요가 있는 몇몇 과정에 한해서 DBA가 MySQL 사용자로 로그인 해야 한다.

4. MySQL에 바이너리 데이터를 저장하지 말아라

MySQL이 바이너리 타입을 지원하는 것은 사실이나, 그럴 수 있어도 포함시키지 않는게 좋다. MySQL은 결과를 한꺼번에 클라이언트로 보낸다. 따라서 바이너리 데이터를 결과값으로 파싱하는 애플리케이션은 모두 다 처리되기 전에 도착하는 각 결과값을 기다려야 한다. 게다가 MySQL에 바이너리를 저장해도 이득이 될 게 없다.

바이너리 데이터에 접근하는 좀더 나은 방법은 데이터를 파일 시스템에 저장하고 MySQL에 있는 이러한 파일들의 포인터를 저장하는 것이다. 이런 접근으로 여러분은 실제적으로 결과값을 처리하는 동안 백그라운드 스레드에 있는 바이너리 데이터를 스트림할 수 있다.

Managing & Using MySQL, 2nd Edition
이런 팁은 단지 바이너리 데이터에만 적용되는 것이 아니다. 큰 데이터 오브젝트 어느 것이나 적용될 수 있다. 바이너리 데이터를 귀찮게 하는 성능 문제는 역시 문자 데이터도 귀찮게 한다. 다시 말해 결과 값의 일부분을 읽는 것은 연속적으로 완료된다. 대개 그 값이 크기 때문에 바이너리 데이터에서는 쉽게 알 수 있을 것이다. 큰 문자 데이터를 처리할 때와 마찬가지로 쉽게 알 수 있다. 파일 시스템에 대규모 문자 데이터를 저장하는 것과 데이터베이스에 저장하는 것에 반해 탐색할 수 있는 성능상의 이익으로는 어떤 것이 더 좋은지 확인해봐야 한다.

5. ANSI SQL과 밀착

MySQL은 ANSI 표준보다 프로그래머에게 더 매력적인 편리한 부가물을 제공한다. 이런 부가물들은 멀티테이블 삭제나 멀티로우 삽입과 같은 시간을 절약해 주는 도구들을 포함한다. 이와 같은 MySQL 사양에 의존하면 애플리케이션이 다른 데이터베이스 엔진으로 이식하는 능력을 제한하게 된다. 사실 다시 심각하게 작성하지 않고 다른 데이터베이스로 이식하는 것이 불가능할 지도 모른다. 따라서 최대한의 이식성을 위해 애플리케이션을 ANSI SQL에 밀착되도록 작성해야 한다.

다른 한 편으로는 이런 도구들을 무시하라는 인상은 주고 싶지 않다. 도구들도 MySQL 유지와 관련하여 나름대로의 역할이 있기 때문이다. MySQL 명령줄에서 작업하거나 MySQL 설치 유지를 위해 구체적으로 스크립트를 만들 때 이런 도구가 가져다주는 편리함을 무시하는 것은 어리석은 일이다.

6. 자신의 시퀀스 생성 스키마를 만들어라.

이 지침은 위의 5번째 항목과 관련되어 있다. MySQL은 auto_increment 키워드를 사용하여 독특한 식별자를 만들 수 있는 MySQL용 도구을 제공한다. 구체적으로 MySQL은 한 줄을 삽입할 때마다 각 테이블마다 한 컬럼에 자동으로 생성되는 값을 정의할 수 있다. 이 기능은 안타깝게도 MySQL에만 있으며 다음과 같은 약간의 제약이 있다.
  • 한 테이블에 오직 하나의 auto_increment를 갖는다.
  • 여러 테이블을 위해 연속된 유일값을 가질 수 없다. 예를 들어 분리된 테이블에서 컬럼들이 유일성을 보장받기 위해 auto_increment를 사용할 수 없기 때문에 한 테이블에 유일한 값은 다른 테이블에서도 나타낼 수 없다.
  • 애플리케이션을 위해 MySQL이 자동으로 생성하는 값들을 쉽게 바꿀 수 없다.
자동 생성값으로 접근은 자신만의 크로스 플랫폼으로 개발하는 것이 좋다. 오라일리에서 발간될 『Java Best Practices:J2EE Edition』에서 필자는 그런 접근 방식으로 설명했다. 한마디로 이런 접근은 다른 연속값을 줄 수 있는 데이터베이스의 특별한 테이블 생성과 관련있다. 원하는 만큼 많은 연속값을 가질 수 있으며 여러 컬럼에 걸쳐 연속값들을 공유할 수도 있다. 단순하게 이름으로 연속값에 접근하면 된다. 그러면 애플리케이션은 메모리에 유일값을 생성하기 위해 이런 특별한 테이블로부터 시드(seed)를 사용한다. 시드로 인해 가능한 연속값들의 리스트가 고갈될 때까지 데이터베이스로 되돌아갈 필요가 없다.

7. 출력 코드와 데이터베이스 코드를 섞지 마라

출력 코드와 데이터베이스 코드가 섞여 있는 애플리케이션은 유지하기가 힘들다. 그런 특이한 한 예는 JDBC 코드를 포함하는 JSP 페이지이다. 이런 상황이 발생해서는 안된다.

대신 model-view-controller(MVC) 디자인 패턴에 따라 애플리케이션 로직을 나눌 때 애플리케이션은 훨씬 유지하기 수월하다. 이런 좋은 예는 웹 프로그래밍과 GUI 애플리케이션 둘다 적용된다. 한마디로 MVC는 코드를 모델(데이터베이스 요소 하우징)과 뷰(사용자 인터페이스를 표현하는 요소), 컨트롤러(사용자 행동을 컨트롤하는 객체)로 나누게 한다.

8. 열정적으로 정규화하고, 비정규화를 적게하라.

정규화는 데이터베이스 디자인에서 중복된 데이터를 제거하는 과정이다. 중복성을 제거해서 데이터 일치성을 유지하기 위한 공간을 최소화해야 한다. 결과적으로 시스템 유지가능성이 늘어나기 때문이다. 데이터 모델을 제3정규화(3NF)형태로 항상 유지해라.

어떤 경우에는 정규화가 성능 저하를 초래하기도 한다. 그러나 이런 성능 저하는 사람들이 믿을 수 있게 될 정도로 자주 일어나지는 않는다. 이와 같이 성능 향상을 위해 정규화를 절충해 데이터 모델을 최적화 과정을 비정규화라고 부른다. 정규화를 거치지 않은 데이터 모델이 비정규화되지 않은 데이터베이스라는 것도 알아두어야 한다. 대신 그것은 unmormalized라 불린다.

비정규화는 구체적인 성능 향상을 위해 정규화에 의해 제거된 데이터 모델로의 매우 의도적이고 신중한 과정이다. 데이터 모델이 완전히 정규화된 후에 일어나야 하며 장점이 쉽게 증명될 수 있을 때에만 발생해야 한다.

9. 웹 서버와 애플리케이션 서버에서 connection pooling을 사용해라.

데이터베이스로의 연결은 돈이 많이 드는 작업이다. 클라이언트/서버 애플리케이션에서는 이런 비용이 대부분 알려지지 않고 발생한다. 그러나 웹 서버나 애플리케이션 서버는 지속적으로 데이터베이스와 사용자 세션을 시작했다 끊기 때문에 새로운 연결이 생성되면 바빠진다. 다행히도 대부분의 프로그래밍 언어들은 요즘 데이터베이스에 pooling을 위한 도구를 제공한다. 다시 말해 connecting pool은 계속해서 연결을 재시작할 필요없이 수많은 사용자 세션을 위해 같은 연결을 재사용할 수 있게 해준다. 어떤 프로그래밍 언어를 선택하든지 이런 지원사항을 미리 알아서 챙기는 것도 이득이 될 것이다.

10. EXPLAIN SELECT로 퀴리를 튜닝해라.

EXPLAIN SELECT는 알아 두어야 할 중요 명령어이다. 이것의 결과값은 단일 쿼리를 실행하기 전에 어떻게 SQL이 작동할 것인가를 이해하는데 도움을 준다. 역시 인덱스 생성과 같이 변경할 필요가 있는 곳을 알려줄 수 있다.
  • 샘플 챕터 13장 Java는 온라인에서 무료로 볼 수 있다.
  • 책의 목차와 설명은 여기에서 볼 수 있다.

조지 리스(George Reese)는 Bloomington, MN.에 사는 정보 시스템 컨설턴트이다.
TAG :
댓글 입력
자료실

최근 본 책0