본문으로 건너뛰기
최종 수정: 에

MAP | 복합 타입

MAP<K, V>는 MAP을 나타내며, 각 요소의 타입은 K, V입니다. 주로 반정형 키-값 쌍 데이터를 저장하는 데 사용됩니다. 자세한 내용은 MAP 데이터 타입을 참고하세요.

이 문서는 MAP 타입 열에 데이터를 쓰는 방법을 중심으로, 자주 사용하는 두 가지 데이터 소스에 대한 전체 과정의 예제를 제공합니다.

  • CSV 형식 데이터 적재: 원본 데이터가 구분자로 나뉜 텍스트일 때 적합합니다. 열 구분자와 MAP 내부의 쉼표가 충돌하지 않도록 주의하세요.
  • JSON 형식 데이터 적재: 원본 데이터가 JSON 배열 또는 JSON Lines일 때 적합합니다.

두 데이터 적재 방식 모두 Stream Load 인터페이스를 사용합니다. 기본 절차는 다음과 같습니다.

  1. 데이터 파일을 준비합니다.
  2. 데이터베이스에 테이블을 생성합니다.
  3. curl로 Stream Load를 호출하여 데이터를 적재합니다.
  4. 쿼리로 결과를 확인합니다.

CSV 형식 데이터 적재​

1단계: 데이터 준비​

다음 내용으로 CSV 파일 test_map.csv를 생성합니다. MAP 내부의 쉼표와 충돌하지 않도록 열 구분자로 쉼표 대신 |를 사용합니다.

1|{"Emily":101,"age":25}
2|{"Benjamin":102}
3|{}
4|null

파일의 각 행은 다음을 의미합니다.

행의미
1|{"Emily":101,"age":25}키-값 쌍 두 개를 포함하는 MAP
2|{"Benjamin":102}키-값 쌍 한 개를 포함하는 MAP
3|{}빈 MAP
4|nullNULL 값

2단계: 데이터베이스에 테이블 생성​

CREATE TABLE map_test (
id INT NOT NULL,
c_map MAP<STRING, INT> NULL
)
DUPLICATE KEY(id)
DISTRIBUTED BY HASH(id) BUCKETS 1
PROPERTIES (
"replication_allocation" = "tag.location.default: 1"
);

3단계: 데이터 적재​

Stream Load를 사용해 CSV 파일의 데이터를 적재합니다. 주요 헤더의 의미는 아래 표와 같습니다.

curl --location-trusted \
-u "root":"" \
-H "column_separator:|" \
-H "columns: id, c_map" \
-T "test_map.csv" \
http://localhost:8040/api/testdb/map_test/_stream_load
헤더용도
`column_separator:`
columns: id, c_map파일 열과 테이블 열 간의 매핑을 선언함

4단계: 적재된 데이터 확인​

mysql> SELECT * FROM map_test;
+------+-------------------------+
| id | c_map |
+------+-------------------------+
| 1 | {"Emily":101, "age":25} |
| 2 | {"Benjamin":102} |
| 3 | {} |
| 4 | NULL |
+------+-------------------------+
4 rows in set (0.01 sec)

JSON 형식 데이터 적재​

1단계: 데이터 준비​

다음 내용으로 JSON 파일 test_map.json을 생성합니다. 파일 전체가 하나의 JSON 배열이며, 각 요소는 데이터 한 행에 해당합니다.

[
{"id":1, "c_map":{"Emily":101, "age":25}},
{"id":2, "c_map":{"Benjamin":102}},
{"id":3, "c_map":{}},
{"id":4, "c_map":null}
]

2단계: 데이터베이스에 테이블 생성​

CREATE TABLE map_test (
id INT NOT NULL,
c_map MAP<STRING, INT> NULL
)
DUPLICATE KEY(id)
DISTRIBUTED BY HASH(id) BUCKETS 1
PROPERTIES (
"replication_allocation" = "tag.location.default: 1"
);

3단계: 데이터 적재​

Stream Load를 사용해 JSON 파일의 데이터를 적재합니다. 주요 헤더의 의미는 아래 표와 같습니다.

curl --location-trusted \
-u "root":"" \
-H "format:json" \
-H "columns: id, c_map" \
-H "strip_outer_array:true" \
-T "test_map.json" \
http://localhost:8040/api/testdb/map_test/_stream_load
헤더용도
format:json데이터 형식을 JSON으로 선언함
strip_outer_array:true입력이 JSON 배열이면 각 배열 요소를 한 행으로 파싱함
columns: id, c_mapJSON 필드와 테이블 열 간의 매핑을 선언함

4단계: 적재된 데이터 확인​

mysql> SELECT * FROM map_test;
+------+-------------------------+
| id | c_map |
+------+-------------------------+
| 1 | {"Emily":101, "age":25} |
| 2 | {"Benjamin":102} |
| 3 | {} |
| 4 | NULL |
+------+-------------------------+
4 rows in set (0.01 sec)

자주 묻는 질문​

Q1: CSV에서 열 구분자로 쉼표를 사용하지 않는 이유는 무엇인가요?

MAP 리터럴 자체에서 여러 키-값 쌍을 구분하는 데 쉼표를 사용합니다. 예를 들어 {"Emily":101,"age":25}와 같습니다. 열 구분자로도 쉼표를 사용하면 파싱이 모호해집니다. | 또는 \t처럼 MAP 내용에 나타나지 않는 문자를 사용하는 것이 좋습니다.

Q2: JSON 배열을 적재할 때 strip_outer_array:true가 필요한 이유는 무엇인가요?

JSON 파일의 최상위 구조가 이 문서의 예제처럼 배열이면, strip_outer_array:true를 설정해야 Doris가 배열의 각 요소를 데이터 한 행으로 처리합니다. 파일이 이미 JSON Lines 형식(행마다 객체 하나)이라면 이 매개변수는 필요하지 않습니다.

Q3: 빈 MAP과 NULL은 각각 어떻게 표현하나요?

  • 빈 MAP: CSV에서는 {}로, JSON에서도 {}로 작성합니다.
  • NULL 값: CSV에서는 null로, JSON에서도 null로 작성합니다. 대상 열은 NULL을 허용해야 합니다.