• MySQL매뉴얼
    • MySQL 5.6 매뉴얼
    • MySQL 5.1 매뉴얼
    • MySQL 5.0 매뉴얼
    • MySQL HA 매뉴얼
  • 기술문서
    • Xtrabackup 구성
    • 메모리 사용량 모니터링
  • 라이선스
  • 온라인문의
  • 회사소개
  • → 목 록 (MySQL5.6 한글메뉴얼) [close]
  • 1. MySQL 5.6 새로운 기능
  • 2. MySQL 설치 및 업그레이드
  • 3. MySQL Tutorial
  • 4. MySQL 프로그램
  • 5. MySQL 서버관리
  • 6. 보안
  • 7. 백업 및 복구
  • 8. 최적화
  • 9. Language Structure(언어구조)
  • 10. Character Sets(Globalization)
  • 11. 데이터형(Data Types)
  • 12. 함수와 연산자
  • 13. SQL 문법
  • 14. InnoDB 스토리지 엔진
  • 15. 기타 스토리지 엔진
  • 16. 고가용성 및 확장성
  • 17. 리플리케이션
  • 18. MySQL Cluster
  • 19. 파티셔닝
  • 1. MySQL Partitioning 개요
    2. Partitioning Types
    1. RANGE 파티셔닝
    2. LIST 파티셔닝
    3. COLUMNS 파티셔닝
    4. HASH 파티셔닝
    5. KEY 파티셔닝
    6. 서브 파티셔닝
    7. MySQL Partitioning NULL 처리
    3. 파티션 관리
    4. Partition Pruning
    5. 파티션 선택
    6. 파티셔닝 제약 및 제한
  • 20. Stored Programs and Views
  • 21. INFORMATION_SCHEMA
  • 22. PERFORMANCE SCHEMA
  • 23. 컨넥터 및 API
  • 24. MySQL 확장
  • 25. MySQL Enterprise Edition
  • 26. MySQL Workbench
  • 27. 제약 및 제한
  • 28. MySQL 5.7 새로운 기능

19.2.7 MySQL Partitioning NULL 처리

MySQL의 파티셔닝은 파티셔닝 식의 값 (컬럼 값 또는 사용자 정의 식의 값에 관계없이)로 NULL 을 거부 수단은 없습니다. 식의 값으로 NULL 을 사용하는 것은 허용되고 있지만 (그렇지 않은 경우는 정수를 반환해야합니다), NULL 은 수치가 아닌 것을 인식하는 것이 중요합니다. MySQL의 파티셔닝 구현은 ORDER BY 와 같이 NULL 이 아닌 값보다 작은 값으로 NULL 을 처리합니다.

이것은 NULL 처리는 각 유형의 파티셔닝 달리이를 준비하지 않으면 예기치 않은 동작이 될 가능성이 있다는 것을 의미합니다. 이러한 상황이 있기 때문에,이 섹션에서는 각 MySQL 파티셔닝 타입이 줄을 어떤 파티션에 저장해야 하는지를 결정할 때 NULL 값을 어떻게 처리 할 것인지를 설명하고 각각의 예 합니다.

RANGE 파티셔닝의 NULL 처리 파티션을 결정하는 데 사용되는 컬럼 값이 NULL 인 행을 RANGE 로 파티션 된 테이블에 삽입 한 경우 행은 가장 낮은 파티션에 삽입됩니다. p 라는 데이터베이스에 다음과 같이 생성 된 2 개의 테이블이 있다고합니다.

mysql> CREATE TABLE t1 (
    ->     c1 INT,
    ->     c2 VARCHAR(20)
    -> )
    -> PARTITION BY RANGE(c1) (
    ->     PARTITION p0 VALUES LESS THAN (0),
    ->     PARTITION p1 VALUES LESS THAN (10),
    ->     PARTITION p2 VALUES LESS THAN MAXVALUE
    -> );
Query OK, 0 rows affected (0.09 sec)

mysql> CREATE TABLE t2 (
    ->     c1 INT,
    ->     c2 VARCHAR(20)
    -> )
    -> PARTITION BY RANGE(c1) (
    ->     PARTITION p0 VALUES LESS THAN (-5),
    ->     PARTITION p1 VALUES LESS THAN (0),
    ->     PARTITION p2 VALUES LESS THAN (10),
    ->     PARTITION p3 VALUES LESS THAN MAXVALUE
    -> );
Query OK, 0 rows affected (0.09 sec)

이러한 2 개의 CREATE TABLE 문에 의해 생성 된 파티션 내용은 다음의 쿼리를 INFORMATION_SCHEMA 데이터베이스의 PARTITIONS 테이블에 사용하여 확인할 수 있습니다.

mysql> SELECT TABLE_NAME, PARTITION_NAME, TABLE_ROWS, AVG_ROW_LENGTH, DATA_LENGTH
     >   FROM INFORMATION_SCHEMA.PARTITIONS
     >   WHERE TABLE_SCHEMA = 'p' AND TABLE_NAME LIKE 't_';
+------------+----------------+------------+----------------+-------------+
| TABLE_NAME | PARTITION_NAME | TABLE_ROWS | AVG_ROW_LENGTH | DATA_LENGTH |
+------------+----------------+------------+----------------+-------------+
| t1         | p0             |          0 |              0 |           0 |
| t1         | p1             |          0 |              0 |           0 |
| t1         | p2             |          0 |              0 |           0 |
| t2         | p0             |          0 |              0 |           0 |
| t2         | p1             |          0 |              0 |           0 |
| t2         | p2             |          0 |              0 |           0 |
| t2         | p3             |          0 |              0 |           0 |
+------------+----------------+------------+----------------+-------------+
7 rows in set (0.00 sec)

(이 테이블에 대한 자세한 내용은 섹션 21.13 "INFORMATION_SCHEMA PARTITIONS 테이블" 을 참조하십시오.) 여기서 이러한 각 테이블 파티셔닝 키로 사용되는 컬럼에 NULL 이 포함 된 단일 행을 채 2 하나의 SELECT 문을 사용하여 이러한 행이 삽입 된 것을 확인합니다.

mysql> INSERT INTO t1 VALUES (NULL, 'mothra');
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO t2 VALUES (NULL, 'mothra');
Query OK, 1 row affected (0.00 sec)

mysql> SELECT * FROM t1;
+------+--------+
| id   | name   |
+------+--------+
| NULL | mothra |
+------+--------+
1 row in set (0.00 sec)

mysql> SELECT * FROM t2;
+------+--------+
| id   | name   |
+------+--------+
| NULL | mothra |
+------+--------+
1 row in set (0.00 sec)

삽입 된 행을 저장하는 데 어떤 파티션이 사용되었는지에 대해서는 이전 쿼리를 INFORMATION_SCHEMA.PARTITIONS 에 대해 다시 실행하고 출력을 검사하여 확인할 수 있습니다.

mysql> SELECT TABLE_NAME, PARTITION_NAME, TABLE_ROWS, AVG_ROW_LENGTH, DATA_LENGTH
     >   FROM INFORMATION_SCHEMA.PARTITIONS
     >   WHERE TABLE_SCHEMA = 'p' AND TABLE_NAME LIKE 't_';
+------------+----------------+------------+----------------+-------------+
| TABLE_NAME | PARTITION_NAME | TABLE_ROWS | AVG_ROW_LENGTH | DATA_LENGTH |
+------------+----------------+------------+----------------+-------------+
| t1         | p0             |          1 |             20 |          20 |
| t1         | p1             |          0 |              0 |           0 |
| t1         | p2             |          0 |              0 |           0 |
| t2         | p0             |          1 |             20 |          20 |
| t2         | p1             |          0 |              0 |           0 |
| t2         | p2             |          0 |              0 |           0 |
| t2         | p3             |          0 |              0 |           0 |
+------------+----------------+------------+----------------+-------------+
7 rows in set (0.01 sec)

이러한 행이 각 테이블의 가장 낮은 파티션에 저장된 대해 이러한 파티션을 삭제하고 SELECT 문을 다시 실행하여 확인할 수 있습니다.

mysql> ALTER TABLE t1 DROP PARTITION p0;
Query OK, 0 rows affected (0.16 sec)

mysql> ALTER TABLE t2 DROP PARTITION p0;
Query OK, 0 rows affected (0.16 sec)

mysql> SELECT * FROM t1;
Empty set (0.00 sec)

mysql> SELECT * FROM t2;
Empty set (0.00 sec)

( ALTER TABLE ... DROP PARTITION 에 대한 자세한 내용은 섹션 13.1.7 "ALTER TABLE 구문" 을 참조하십시오.)

SQL 함수를 사용하여 분할 식의 경우에도 NULL 이 같이 처리됩니다. 다음과 같은 CREATE TABLE 문을 사용하여 테이블을 정의합니다.

CREATE TABLE tndate (
    id INT,
    dt DATE
)
PARTITION BY RANGE( YEAR(dt) ) (
    PARTITION p0 VALUES LESS THAN (1990),
    PARTITION p1 VALUES LESS THAN (2000),
    PARTITION p2 VALUES LESS THAN MAXVALUE
);

다른 MySQL 함수와 마찬가지로 YEAR(NULL) 은 NULL 을 반환합니다. dt 컬럼 값이 NULL 인 행은 분할 식이 다른 값보다 작은 값으로 평가 된 것처럼 취급 파티션 p0 에 삽입됩니다.

LIST 파티셔닝의 NULL 처리 LIST 로 파티션 된 테이블에 NULL 값이 허용되는 것은 NULL 이 포함 된 값 목록을 사용하여 하나의 파티션이 정의되어있는 경우입니다. 이와는 반대로, LIST 에 의해 분할 된 테이블은 값 목록에서 NULL 을 명시 적으로 사용하지 않는 경우에는 다음 예와 같이 분할 식으로 NULL 값으로 평가되는 행을 거부합니다 합니다.

mysql> CREATE TABLE ts1 (
    ->     c1 INT,
    ->     c2 VARCHAR(20)
    -> )
    -> PARTITION BY LIST(c1) (
    ->     PARTITION p0 VALUES IN (0, 3, 6),
    ->     PARTITION p1 VALUES IN (1, 4, 7),
    ->     PARTITION p2 VALUES IN (2, 5, 8)
    -> );
Query OK, 0 rows affected (0.01 sec)

mysql> INSERT INTO ts1 VALUES (9, 'mothra');
ERROR 1504 (HY000): Table has no partition for value 9

mysql> INSERT INTO ts1 VALUES (NULL, 'mothra');
ERROR 1504 (HY000): Table has no partition for value NULL

ts1 에 삽입 할 수있는 것은 c1 값이 0 이상 8 다음 줄뿐입니다. NULL 은 숫자 9 와 같이 범위를 벗어난 있습니다. NULL 이 포함 된 값 목록을 가진 테이블 ts2 및 ts3 는 다음과 같이 만들 수 있습니다.

mysql> CREATE TABLE ts2 (
    ->     c1 INT,
    ->     c2 VARCHAR(20)
    -> )
    -> PARTITION BY LIST(c1) (
    ->     PARTITION p0 VALUES IN (0, 3, 6),
    ->     PARTITION p1 VALUES IN (1, 4, 7),
    ->     PARTITION p2 VALUES IN (2, 5, 8),
    ->     PARTITION p3 VALUES IN (NULL)
    -> );
Query OK, 0 rows affected (0.01 sec)

mysql> CREATE TABLE ts3 (
    ->     c1 INT,
    ->     c2 VARCHAR(20)
    -> )
    -> PARTITION BY LIST(c1) (
    ->     PARTITION p0 VALUES IN (0, 3, 6),
    ->     PARTITION p1 VALUES IN (1, 4, 7, NULL),
    ->     PARTITION p2 VALUES IN (2, 5, 8)
    -> );
Query OK, 0 rows affected (0.01 sec)

파티셔닝의 값 목록을 정의 할 때 NULL 을 다른 값과 같이 처리 할 수 있습니다 (이렇게해야한다). 예를 들어, VALUES IN (NULL) 및 VALUES IN (1, 4, 7, NULL) 모두 유효하며 VALUES IN (1, NULL, 4, 7) , VALUES IN (NULL, 1, 4, 7) 등 도 마찬가지입니다. 컬럼 c1 이 NULL 인 행을 테이블 ts2 및 ts3 에 각각 삽입 할 수 있습니다.

mysql> INSERT INTO ts2 VALUES (NULL, 'mothra');
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO ts3 VALUES (NULL, 'mothra');
Query OK, 1 row affected (0.00 sec)

INFORMATION_SCHEMA.PARTITIONS 에 대해 적절한 쿼리를 실행하여 방금 삽입 한 행을 저장하기 위해 어떤 파티션이 사용되었는지를 확인할 수 있습니다 (앞의 예와 마찬가지로 분할 된 테이블이 p 데이터베이스 생성 된 것을 상정하고 있습니다).

mysql> SELECT TABLE_NAME, PARTITION_NAME, TABLE_ROWS, AVG_ROW_LENGTH, DATA_LENGTH
     >   FROM INFORMATION_SCHEMA.PARTITIONS
     >   WHERE TABLE_SCHEMA = 'p' AND TABLE_NAME LIKE 'ts_';
+------------+----------------+------------+----------------+-------------+
| TABLE_NAME | PARTITION_NAME | TABLE_ROWS | AVG_ROW_LENGTH | DATA_LENGTH |
+------------+----------------+------------+----------------+-------------+
| ts2        | p0             |          0 |              0 |           0 |
| ts2        | p1             |          0 |              0 |           0 |
| ts2        | p2             |          0 |              0 |           0 |
| ts2        | p3             |          1 |             20 |          20 |
| ts3        | p0             |          0 |              0 |           0 |
| ts3        | p1             |          1 |             20 |          20 |
| ts3        | p2             |          0 |              0 |           0 |
+------------+----------------+------------+----------------+-------------+
7 rows in set (0.01 sec)

이 섹션에서 이미 설명했듯이, 행을 저장하는 데 어떤 파티션이 사용되었는지에 대해서는 해당 파티션을 삭제하고 SELECT 를 실행하여 확인할 수 있습니다.

HASH 및 KEY 파티셔닝의 NULL 처리 HASH 또는 KEY 로 파티션 된 테이블의 경우 NULL 처리는 조금 다릅니다. 이러한 경우 NULL 값을 반환 파티셔닝 식은 반환 값이 0 인 것처럼 처리됩니다. 이 동작은 HASH 로 파티션 된 테이블을 작성하고 해당 값이 포함 된 레코드를 삽입하는 것으로, 파일 시스템에 어떤 영향이 있는지를 검사하여 확인할 수 있습니다. 다음 문을 사용하여 작성된 테이블 th (이것도 p 데이터베이스)가 있다고합니다.

mysql> CREATE TABLE th (
    ->     c1 INT,
    ->     c2 VARCHAR(20)
    -> )
    -> PARTITION BY HASH(c1)
    -> PARTITIONS 2;
Query OK, 0 rows affected (0.00 sec)

이 테이블에 속한 파티션은 다음의 쿼리를 사용하여 볼 수 있습니다.

mysql> SELECT TABLE_NAME,PARTITION_NAME,TABLE_ROWS,AVG_ROW_LENGTH,DATA_LENGTH
     >   FROM INFORMATION_SCHEMA.PARTITIONS
     >   WHERE TABLE_SCHEMA = 'p' AND TABLE_NAME ='th';
+------------+----------------+------------+----------------+-------------+
| TABLE_NAME | PARTITION_NAME | TABLE_ROWS | AVG_ROW_LENGTH | DATA_LENGTH |
+------------+----------------+------------+----------------+-------------+
| th         | p0             |          0 |              0 |           0 |
| th         | p1             |          0 |              0 |           0 |
+------------+----------------+------------+----------------+-------------+
2 rows in set (0.00 sec)

각 파티션의 TABLE_ROWS 은 0입니다. 여기에서 다음과 같이 c1 컬럼 값이 NULL 과 0 인 두 행을 th 에 삽입하고 그 행이 삽입 된 것을 확인합니다.

mysql> INSERT INTO th VALUES (NULL, 'mothra'), (0, 'gigan');
Query OK, 1 row affected (0.00 sec)

mysql> SELECT * FROM th;
+------+---------+
| c1   | c2      |
+------+---------+
| NULL | mothra  |
+------+---------+
|    0 | gigan   |
+------+---------+
2 rows in set (0.01 sec)

정수 N 대해 NULL MOD N 의 값은 항상 NULL 임을 기억하십시오. HASH 또는 KEY 로 파티션 된 테이블의 경우이 결과는 올바른 파티션을 판별하기 위해 0 으로 처리됩니다. INFORMATION_SCHEMA.PARTITIONS 테이블을 다시 확인하면 두 행이 파티션 p0 에 삽입 된 것을 알 수 있습니다.

mysql> SELECT TABLE_NAME, PARTITION_NAME, TABLE_ROWS, AVG_ROW_LENGTH, DATA_LENGTH
     >   FROM INFORMATION_SCHEMA.PARTITIONS
     >   WHERE TABLE_SCHEMA = 'p' AND TABLE_NAME ='th';
+------------+----------------+------------+----------------+-------------+
| TABLE_NAME | PARTITION_NAME | TABLE_ROWS | AVG_ROW_LENGTH | DATA_LENGTH |
+------------+----------------+------------+----------------+-------------+
| th         | p0             |          2 |             20 |          20 |
| th         | p1             |          0 |              0 |           0 |
+------------+----------------+------------+----------------+-------------+
2 rows in set (0.00 sec)

테이블의 정의 PARTITION BY HASH 대신 PARTITION BY KEY 를 사용하여이 예를 반복하면이 유형의 파티셔닝도 NULL 이 0처럼 취급되는 것을 쉽게 확인할 수 있습니다.

서울시 강남구 영동대로 602 6층
TEL: 02-6061-0006  /  E: csr@mysqlkorea.com
주식회사 이노클러스터  등록번호 : 727-86-02261
Copyright © innocluster Co. ltd. all rights reserved