2024 04 07
2024-04-07¶
MySQL Charset, Collation¶
참고: https://sshkim.tistory.com/128 참고: https://www.lesstif.com/dbms/mysql-8-character-set-collation-91947077.html 참고: https://www.lesstif.com/dbms/mysql-character-sets-collations-9437311.html
- 배경
- 데이터베이스도 "더 작은 공간으로" "더 빠른 처리"가 가능하게 진화하였음
- ex) true/false 저장시...
- boolean > char(0, 1) > int(0, 1)
- Encoding
- character나 grapheme을 어떻게 binary로 표시할지 규정한 방법
- ex) ASCII, ISO-8859-1/LATIN-1, EUC-KR
- 대표적인게 UNICODE
- UTF-8: 문자당 1~4 바이트 (호환성 탑, 복잡한 코드 체계, 인/디코딩 때매 느린 속도, 저장공간 많이 먹음)
- UTF-16: 문자당 2 or 4 바이트
- UTF-32: 문자당 4 바이트 (처리속도 탑)
- character나 grapheme을 어떻게 binary로 표시할지 규정한 방법
- Charset (문자 집합)
- [UTF-8 Charset (다국어 언어셋)]
- 실생활의 모든 텍스트 데이터를 저장하고자 나옴
- UTF-8로는 1~4 바이트까지 저장 가능 (가변 바이트)
- 전 세계 모든 언어를 다룰 수 있는 "다국어" 언어셋
- MySQL/MariaDB 도 UTF-8 지원
- 전세계 모든 언어가 21bit에 저장되기에, MySQL은 utf8을 3바이트 가변 자료형으로 설정
- 그런데 최근 나온 4바이트 문자열 "이모지"의 등장으로 utf8에 값 저장시 값 손실!
- 널리 사용되던 MySQL 환경에서 charset: utf8, collation: utf8_general_ci 인데 이게 환경에서 문제됨
- [4바이트 UTF-8 Charset (utf8mb4)]
- 원래 설계대로 4바이트 UTF-8 문자열 저장 자료형 추가 => 이게 utf8mb4
- Emoji 문자열이 4바이트라서 뚝딱 처리가능
- MySQL 지원 Charset
mysql> show character set; +----------+---------------------------------+---------------------+--------+ | Charset | Description | Default collation | Maxlen | +----------+---------------------------------+---------------------+--------+ | armscii8 | ARMSCII-8 Armenian | armscii8_general_ci | 1 | | ascii | US ASCII | ascii_general_ci | 1 | | ujis | EUC-JP Japanese | ujis_japanese_ci | 3 | | utf16 | UTF-16 Unicode | utf16_general_ci | 4 | | utf16le | UTF-16LE Unicode | utf16le_general_ci | 4 | | utf32 | UTF-32 Unicode | utf32_general_ci | 4 | | utf8 | UTF-8 Unicode | utf8_general_ci | 3 | | utf8mb4 | UTF-8 Unicode | utf8mb4_0900_ai_ci | 4 | +----------+---------------------------------+---------------------+--------+
- [UTF-8 Charset (다국어 언어셋)]
- Collation (정렬)
- 텍스트 데이터를 정렬(order by)할 때 사용!
- TEXT 자료형에서만 사용할 수 있는 속성!
- text에서 a 와 b 중에 뭐가 큰지 어찌알지?
ORDER BY text ASC
- [utf8_bin(utf8mb4_bin)]
- 바이너리 값 그대로 정렬
- ex) A > B > a > b
- 바이너리 값 그대로 정렬
- [utf8_general_ci(utf8mb4_general_ci)]
- 텍스트 정렬시 a다음 b가 나오는게 맞다는 정렬방식
- 바이너리 한차례 가공
- ex) A > a > B > b
- [utf8_unicode_ci(utf8mb4_unicode_ci)]
- 조금 더 사람에 맞게 정렬
- 한영중일 사용환경에서는 general_ci, unicode_ci 결과 동일
- MySQL 지원 Collation
mysql> SHOW COLLATION; +----------------------------+----------+-----+---------+----------+---------+---------------+ | Collation | Charset | Id | Default | Compiled | Sortlen | Pad_attribute | +----------------------------+----------+-----+---------+----------+---------+---------------+ | armscii8_bin | armscii8 | 64 | | Yes | 1 | PAD SPACE | | armscii8_general_ci | armscii8 | 32 | Yes | Yes | 1 | PAD SPACE | | ascii_bin | ascii | 65 | | Yes | 1 | PAD SPACE | | ascii_general_ci | ascii | 11 | Yes | Yes | 1 | PAD SPACE | | utf8mb4_0900_ai_ci | utf8mb4 | 255 | Yes | Yes | 0 | NO PAD | | utf8mb4_0900_as_ci | utf8mb4 | 305 | | Yes | 0 | NO PAD | | utf8mb4_0900_as_cs | utf8mb4 | 278 | | Yes | 0 | NO PAD | | utf8mb4_0900_bin | utf8mb4 | 309 | | Yes | 1 | NO PAD | | utf8mb4_bin | utf8mb4 | 46 | | Yes | 1 | PAD SPACE | | utf8mb4_croatian_ci | utf8mb4 | 245 | | Yes | 8 | PAD SPACE | | utf8mb4_cs_0900_ai_ci | utf8mb4 | 266 | | Yes | 0 | NO PAD | | utf8mb4_cs_0900_as_cs | utf8mb4 | 289 | | Yes | 0 | NO PAD | +----------------------------+----------+-----+---------+----------+---------+---------------+
- MySQL 8의 charset, collation 변경 사항
- MySQL 8의 기본 charset: latin-1 => utf8mb4
- MySQL 8의 기본 collation: utf8mb4_0900_ai_ci
- utf8mb4: 각 character 최대 4바이트의 utf8 인코딩 지원
- 0900: Unicode의 collation algorithm 9.0.0 지원
- ai: accent insensitivity. (e, è, é, ê, ë 같은 문자로 취급 )
- ci: case insensitivity. (p, P 같은 문자로 취급)
- Collation 변경에 어찌 대처하는가?
- Collation 변경에 따라 정렬, index, pk, unique 까지 영향 줌.
- 다개국어 DB는 collation 변경 영향도 측정이 어려움
ES index templates¶
참고: https://developer-jp.tistory.com/41 참고: https://www.elastic.co/guide/en/elasticsearch/reference/7.17/index-templates.html
- 개요
- 인덱스 템플릿을 통해 인덱스 생성 시 어떻게 구성할지 알려줄 수 있음
- 인덱스 생성의 기초로 템플릿의 설정이 반영됨
- 템플릿의 구성요소
- 2가지의 템플릿 구성 요소가 있음
- index template (더 큰 개념인가보다)
- 컴포넌트 템플릿 모음을 포함 가능
- mapping, setting, alias 설정 가능
- component template
- 재사용 가능한 블럭
- mapping, setting, alias 설정 가능
- 인덱스 템플릿 구성 가능하나, 인덱스 집합에 직접 적용되진 X
- index template (더 큰 개념인가보다)
- 2가지의 템플릿 구성 요소가 있음
- 컴포넌트 템플릿
- 다수의 템플릿 관리하는데 문제 있을 수 있음
- 인덱스 템플릿간의 중복 => 클러스터 상태 커짐
- 모든 인덱스 템플릿 변경 시, 각 템플릿 수동 변경
- 인덱스가 여러 템플릿과 일치시, opensearch 자체적 병합 시도하며 예기치 않은 병합
- 컴포넌트를 통해 공통 설정, 매핑, 별칭 재사용 가능한 블록으로 추상화!
- 다수의 템플릿 관리하는데 문제 있을 수 있음
- Index template 조건
- Composable template이 먼저 나와야함.
- Composable template들의 조건에 아무것도 맞지 않으면, legacy template으로 처리 될 수 있음
- Index가 명시적으로 생성되고, 인덱스 템플릿과도 일치한다면, 인덱스 생성 요청의 설정이 가장 우선순위임
- 인덱스 템플릿의 세팅은 구성 요소 템플릿의 설정보다 우선함
- 새 데이터 스트림, 인덱스가 둘 이상의 인덱스 템플릿과 일치한다면, 우선순위 높은 인덱스 템플릿 채택
- Composable template이 먼저 나와야함.
-
예시
- component template 생성
PUT _component_template/component_template1 { "template": { "mappings": { "properties": { "@timestamp": { "type": "date" } } } } } PUT _component_template/runtime_component_template { "template": { "mappings": { "runtime": { "day_of_week": { "type": "keyword", "script": { "source": "emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT))" } } } } } }
- index template 생성
PUT _index_template/template_1 { "index_patterns": ["te*", "bar*"], "template": { "settings": { "number_of_shards": 1 }, "mappings": { "_source": { "enabled": true }, "properties": { "host_name": { "type": "keyword" }, "created_at": { "type": "date", "format": "EEE MMM dd HH:mm:ss Z yyyy" } } }, "aliases": { "mydata": { } } }, "priority": 500, "composed_of": ["component_template1", "runtime_component_template"], "version": 3, "_meta": { "description": "my custom" } }
- component template 생성
- 활용처
- 이미 정의된 mapping, setting 그대로 새 인덱스 초기화 가능
- 지속적으로 인덱싱하는 Log data 라면, index가 동일한 샤드/복제본 같도록 인덱스 템플릿 정의 가능