좋은 테이블 설계의 4가지 규칙

 

1. 테이블의 각 필드는 고유한 종류의 정보를 나타내야 한다.

2. 각 테이블은 테이블에서 하나나 여러개의 필드로 구성된 고유 식별자나 기본키를 갖고 있어야 한다.

3. 각 고유한 키본키 값에 대해 데이터 열의 값은 테이블의 주제와 관련이 있어야 하고 그 주제를 완전히 설명할 수 잇어야 한다.

4. 어떤 필드(기본키로 지정한 필드)의 데이터를 바꿀 때 다른 필드의 데이터에 영향을 끼치지 않고 바꿀수 있어야 한다.

 

======================================================================================

1. 테이블 생선 전에 정규화 및 각 컬럼의 데이터 유형을 계획한다.

 

2. Block 영역을 위해 PCTFREE, PCTUSED를 충분히 고려한다.

  컬럼수가 많은 테이블에서 데이터를 처리하게 되면 디스트 I/O양이 증가하여 성능이 저하됨

 

▣ 행 이주 (Row Chaining) 현상 

Block 길이가 너무 길어 데이터 Block 하나에 저장되지 않고, 두개 이상의 Block에 걸쳐 하나의  Row가 저장되어 있는 형태

- Block에 더 이상 Free 한 공간이 부족 할 경우 Update 발생시 해당 행 자체가 다른 Block으로 이동하는 현상

- 주로 Varchar2 타입을 가진 컬럼에서 발생한다.

- Update가 자주 발생하는 테이블을 파악하여 PCTFREE 파라미터 값을 조절한다.

- PCTFREE = 10 의미는 테이블이 생성될 때 할당된 블록의 행 데이터 영역의 크기에서 10% 공간만큼은 INSERT문 실행시에 사용하지 말고 Update 될 때에만 사용하도록 미리 확보하는 것이다.

 

▣ Row Migration 

-  데이터 블럭에서 수정이 발생하면 수정된 데이터를 해당 데이터 블럭에서 저장하지 못하고 다른 블록의 빈 공간을 찾아 저장

 

▣ PCTFREE

- pctfree는 실제 Row길이가 커지는 비율만큼 예상하여 산정한다.

- 이를 예상하기 힘들기 때문에 다음과 같이 사용 가능하다.

   => 5  : Update가 거의 발생하지 않거나 Update시 Row길이가 거의 증가되지 않는 테이블에 젹용

      Sample : 코드 테이블, 통계 테이블

    => 10 : 보통의 테이블에 적용

    => 15 : Row길이가 증가되는 Update가 자주 발생되는 테이블에 적용

 

▣ PCTUSED

- pctused는 트랜잭션의 유형과 공간관리 정책에 의해 산정합니다.

- 이를 예상하기 힘들기 때문에 다음과 같이 사용 가능합니다.

  => 40 : Delete와 Insert가 많은 테이블에 적용 (특히 배치작업이 자주 이루어지는 테이블)

  => 60 : 보통의 테이블에 적용

  => 90 : Delete가 거이 이루어지지 않는 테이블에 적용 ( 코드 테이블 )

 

▣ PCTINCREASE

- pctincrease는 데이터의 Extent시 데이터의 증가 크기를 결정하는데 영향을 준다

- 테이블 파라메타 "pctincrease'는 '0'으로 하는것이 테이블 관리 및 운영 측면에서 유리하다.

 ( 테이블 증가 크기 = Next + ( Next * pctincrease))

    

3. Column의 데이터 타입

 ▣ 문자타입, 숫자타입의 결정

  - 가능한 문자와 숫자를 같이 결합하는 것은 좋지 못하다.

  - Number 타입 지정시 내부적인 변형을 일으켜 인덱스를 타지 못하는 경우 주의

  - 연산을 하거나 일련번호 등이 아닌 경우 Number 타입을 피한다.

  - 한자리 Number 타입은 피한다.

 

▣ Char

 - 입력 문자열의 길이가 일정한 경우 가능한 Char 타입을 사용하며 Varchar2, Varchar 타음은 가급적 사용하지 않는다.

- 디스크 공간의 효율적 활용 및 Insert, Update시 속도 향상과 fragmentation 방지를 위해 Varchar 보다는 Char 타입이 효율적이다.

- Char 타입의 출력 시 Right Trim 처리가 필요할 수 있으므로 주의한다.

- 날짜 혹은 시간을 표현할 경우 Date, DateTime 타입보다는 Char 타입을 사용하도록 한다.

  년월일을 저장할 경우 8자리, 시분초까지 저장할 겨우에는 14자리를 사용한다

  Sample >>

     Char(8)  : 날짜 - YYYYMMDD

     Char(14) : 날짜, 시간 - YYYYMMDDHHMI24SS

 

▣ Varchar2/Varchar

- 2000 Byte 이상의 데이터를 저장할 필요가 있을 경우, Long 혹은 Text 타입을 사용해야 한다.

 

▣ Long/Text

- 입력 문자열의 길이가 짧은 경우 가급적 사용하지 않는다.

- 각종 함수, 인덱스, Like 검색 등을 사용할 수 없다.

- Long 형은 하나의 테이블에 둘 이상의 컬럼을 만들수 없다.

   Text 형은 둘 이상의 컬럼을 허용한다.

 

 

▣ Number

 - 연산이 필요한 컬럼, 일련번호

 - 인덱스로 생성시킬 컬럼은 반드시 문자 타입

 

▣ Long

 - 하나의 테이블에 하나의 LONG 타입과 허용

 - 비교 불가

 - 인덱스 생성 못함

 - SQL 함수 사용 불가

 - PL/SQL에서 사용 불가

 - 서브쿼리 리스트 사용 불가

 

4. 제약조건

- 기본 키(Primary Key) 명칭은 테이블 명칭의 앞(또는 뒤)에 'PK_' 를 추가한다.

- 기본 키는 가급적 인덱스용 테이블스페이스에 생성토록 한다.

- Insert Query 시 성능 향상을 도모할 경우에는 가급적 Foreign Key를 지정하지 말아야 한다.

  설계서 상에는 논리적으로 선언해야 하며, 개발 완료 후 운영용 데이터베이스에서는 삭제해도 무방하다. 개발 및 테스트 단계에서 참조 무결성이 검증되어야 한다.

- 프로그램 개발 완료 후 각 테이블의 데이터를 추출(Select)하는 모든 쿼리를 검사한다. 이중에서 가장 많은 빈도로 호출되는 쿼리를 선택한 후, 쿼리의 응답 속도가 최상이 될 때까지 인덱스를 조정한다.

- 최빈도의 쿼리에 대한 인덱스 형성 후, 그보다 낮은 빈도로 접근하는 쿼리에 대한 인덱스를 생성하거나, 두 쿼리의 성능에 균형(balance)을 조절할 수 있도록 첫번째 인덱스를 조정한다.

- 앞서 하나 혹은 두 인덱스에 의해서 다른 쿼리의 성능이 떨어지는 현상이 발행하지 않는지 확인한다.

- 가급적 null 값이 허용되고, null 데이터를 많이 포함하는 커럼은 인덱스 대상에서 제외한다.

- 데이터 값이 편차가 적은 컬럼 또한 인덱스 대상에서 제외한다.

- 인덱스 생성으로 인한 성능 향상을 얻을 수 있는 경우는 인덱스를 포함하는 테이블이 데이터가 많거나, 향후 Row 의 수가 급격히 증가할 것이 예상되는 경우이다.

- 일반적으로 1000 ~ 10000 건 이하의 행을 지니는 테이블에서는 인덱스를 만들어도 성능 향상 효가가 없거나, 최적화기(optimizer)에 의해서 인덱스가 무시될 수도 있다.

- 하나의 테이블에 가급적 3개 이상의 인덱스를 만들지 않아야 한다. 인덱스가 많을 경우, INSERT, UPDATE, DELETE 시 쿼리의 반응 속도가 느려지게 되며, 디스크 사용량이 급증한다.

 

 

 

4. Null값이 예상되는 컬럼들을 가능한 연속된 순서로 지정한다.

   연속된 여러 개의 컬럼이 마지막 컬럼까지 Null값을 가진다면 그 전체가 1 바이트를 가진다.

 

5. Null 값으로 입력되는 경우 반드시 VARCHAR2 타입 사용

 

6. 저장될 테이블 스페이스를 지정한다.

 

7. 필요한 경우 NOLOGGING 키워드를 사용한다.

 

8. 필요한 경우CACHE 키워드를 사용한다.


출처 -  http://blog.naver.com/everekk79?Redirect=Log&logNo=30023255302 


'DB > Common' 카테고리의 다른 글

데이터 모델링 - ERD  (0) 2012.03.28
데이터베이스 설계 과정 1  (0) 2012.03.28
회원 정보 테이블 설계 시 고려 사항  (0) 2012.03.17
SQLite  (0) 2012.03.02
varchar와 varchar2의 차이와 number(5,2) 의미  (1) 2012.02.13
Posted by linuxism
,

문자셋(Character Set)
말 그대로 특정 '문자(좀 더 정확히는 symbol)'가 컴퓨터에 저장될 때 어떠한 '코드'로 인코딩되어 저장될 것인지에 대한 규칙이 정의되어있는 집합을 말함. (A character set is a set of symbols and encodings.) 
대표적인 것으로는 ASCII, 한글을 지원하는 EUC-KR, 유니코드 UTF-8, UTF-16 등이 있음.
문자셋은 자신이 처리할 문자 집합이 얼마나 큰가에 따라 하나의 '문자'를 저장하는데 필요한 저장공간의 크기가 달라지게 된다. 또한 항상 모든 문자들을 동일한 크기로 인코딩하는 고정폭 방식의 문자셋이 있는가하면, EUC-KR(1~2바이트)이나 UTF-8(1~3바이트)과 같이 가변폭 방식의 인코딩을 사용하는 문자셋도 있다.
 
콜레이션(Collation)
이것은 특정 문자셋에 의해 데이터베이스에 저장된 값들을 검색하거나 정렬 등의 작업을 위해 문자들간에 서로 '비교'할때 사용하는 규칙들의 집합이다. (A collation is a set of rules for comparing characters in a character set.) 따라서, 일반적인 Data Type에는 적용되지 않고, CHAR, VARCHAR, TEXT와 같은 데이터 타입을 가지는 칼럼들에 대해서만 적용된다.
주로 대소문자를 구별하는 binary 형식을 사용할 것인지, 대소문자를 구별하지 않는 Case Insensitive 형식을 사용할 것인지로 나누어진다. Case Insensitive 형식을 사용하는 collation들은 모두 collation 이름의 끝에 'ci'라는 문자가 붙어있다.
 
 
[참고]
1. 특별히, MySQL에서의 문자셋과 collation 에 대한 문제는 단순히 데이터를 저장하는 공간에 대한 관점만이 아니라, MySQL 서버와 MySQL 서버에게 요청을 하는 클라이언트 사이에 주고받는 상호작용에 대한 관점까지도 포함한다는 것을 꼭 기억할 필요가 있다. 
 
데이터를 저장하는 관점 : MySQL은 Server 레벨, Database 레벨, Table 레벨, Column 레벨까지 총 4개의 레벨을 지원하는 특징을 가지고 있음.
 
서버와 클라이언트간의 상호작용 관점 : MySQL은 이 관점에서 문자셋과 관련한 총 3개의 서로 다른 타입을 제공한다.
 
character_set_client : 클라이언트에서 문장이 떠날 때 해당 문장은 어떤 문자셋으로 이루어져있는가의 문제
 
character_set_connection : 클라이언트에서 넘어온 문장을 서버에서는 어떤 문자셋을 기준으로 해석해야하는가의 문제.
 
character_set_results : 서버에서 클라이언트로 응답을 넘겨줄때 어떤 문자셋으로 넘겨야하는가의 문제.
 
따라서, 데이터베이스 레벨에서 euckr 문자셋이 기본값으로 지정되어있는 데이터베이스를 생성한 후 해당 데이터베이스에 데이터를 잘 입력하였는데 이상하게 브라우저로 넘기면 데이터베이스에서 읽어온 문자만 글자가 깨지는 상황이 벌어진다면(브라우저의 인코딩 설정 등은 정상적이라고 가정) 다음과 같이 체크해봐야 한다.
 
Database 레벨, Table 레벨, Column 레벨에서 원하는 문자셋으로 잘 지정되어있는지를 확인
client, connection, results 에서의 문자셋도 적절하게 지정되어있는지를 확인. (대개 글자가 깨지는 경우라면, 아마도 이쪽이 잘못 지정되어있을 가능성이 높다)
 
SQL 문장 중에 'SET NAMES euckr [COLLATE collation_name]'을 사용하면 앞에서 살펴본 client, connection, results 3가지에 대한 문자셋을 한꺼번에 지정해줄 수 있음. (서버 실행중에도 변경이 가능. 단, 서버 실행중에 SQL 문장으로 변경하는 것은 영구 변경이 아니라 현재 연결에 한해서만 임시로 변경하는 것임)
 
임시 변경이 아닌 영구 변경을 하려면, MySQL 서버가 처음 시작할 때 참고하는 my.cnf 환경설정 파일내에 'init_connect=SET NAMES euckr' 이런식으로 지정해두면 됨.
이렇게 영구 변경과 임시 변경 방법을 활용하면 좀 더 다양한 응용이 가능해진다.
 
서버가 시작하는 단계에서 지정하는 경우 : 대개 환경설정 파일인 my.cnf 파일에서 'init_connect=SET NAMES euckr' 명령어로 지정. 이렇게 했을때는 해당 서버를 사용하는 모든 애플리케이션들에게 이 설정이 기본값으로서의 영향을 미친다.
 
시작 단계가 아니라 서버가 실행중에 데이터베이스 별로 다른 문자셋을 사용하도록 지정하는 경우 : 일단 클라이언트가 서버로 연결을 한 이후에 곧바로 'SET NAMES euckr' 명령어를 실행시켜서 현재 연결에 대한 연결 관련 문자셋들을 수정해놓고 시작한다. 이렇게 하면, 각각의 데이터베이스별로 서로 다른 연결 관련 문자셋을 지정할 수 있게 됨(!!!)
즉, 동일한 서버내에서 대부분의 애플리케이션은 utf-8 문자셋을 사용하는데 특정 애플리케이션만 euckr 문자셋을 사용하고자 할 경우에 위와 같은 방법을 사용하면 가능.
참고로, PHP에서 사용하는 mysqli 확장에서는 'SET NAMES ...'를 query 메소드로 실행시키는 방법 이외에 'set_charset' 이라는 더 나은 메소드를 통해서 동일한 효과를 얻을 수도 있음.
 
(질문) PHPMyAdmin에서 새로운 데이터베이스를 생성할 때, 해당 데이터베이스에서 사용할 Default collation 만을 지정하게 되는데... 그렇다면, 해당 데이터베이스이 Default Character Set은 어떻게 되는 것일까?
(대답) 뭐... 당연한 이야기겠지만, Default collation 만을 지정하게 되면 해당 collation이 속해있는 Character Set이 자동으로 그 데이터베이스의 Default Character Set으로 지정됨. 물론, PHPMyAdmin의 GUI 방식을 사용하지 않고, 직접 DDL 문장을 사용하면 하나 하나 별도로 지정해줄 수도 있음. 또한, PHPMyAdmin에서 데이터베이스를 생성할 때, Default collation 조차도 지정하지 않게 되면, 당연히 MySQL의 환경설정 파일인 my.cnf(또는 my.ini)에서 지정되어있는 시스템의 기본적인 Character Set이 적용되게 되며 Collation은 해당 Character Set의 Default collation이 적용되게 됨.

출처 -  http://blog.naver.com/kumimo?Redirect=Log&logNo=80090609083 


문자셋 변경
ALTER DATABASE `db` CHARACTER SET utf8 COLLATE 'utf8_general_ci';
Posted by linuxism
,

mysql 주석

DB/MySQL 2012. 3. 17. 13:22

mysql 주석
1. '#' 을 사용한다.
2.  '/* ..... */' 을 사용한다.
3.  '--' 는 사용하지 못 한다.
Posted by linuxism
,