AD JB Toolbox 01

MariaDB 강좌 / 문자열 다루기: 연결·추출·치환·길이

문자열 함수는 글자를 연결·추출·치환하거나 길이를 계산해 조회 결과를 가공합니다. CONCAT·SUBSTRING·REPLACE·CHAR_LENGTH를 목적에 맞게 선택하되, NULL 처리와 문자 수·바이트 수를 구분해야 원본 의미를 훼손하지 않습니다.

연결·추출·치환의 역할 나누기

상품명과 분류를 한 줄로 보여 주는 일, 코드의 일부를 꺼내는 일, 전화번호 구분자를 제거하는 일은 서로 다른 작업입니다. 문자열 함수를 SELECT에 사용하면 출력값이 계산될 뿐 저장된 상품명이 자동으로 수정되지는 않습니다. 먼저 무엇을 원본으로 보관하고 무엇을 화면 표시로 만들지 정하세요. 함수 입력이 담기는 열의 저장 조건은 문자열 타입 선택하기: CHAR·VARCHAR·TEXT, 누락값의 의미를 보존하는 기준은 NULL을 올바르게 비교하기: IS NULL·COALESCE와 함께 확인하세요.

함수 용도 중요한 기준
CONCAT 문자열 이어 붙이기 일반 모드에서 인수에 NULL이 있으면 결과 NULL
CONCAT_WS 구분자로 연결 NULL 인수는 건너뛰지만 빈 문자열은 유지
SUBSTRING 위치와 길이로 추출 첫 문자 위치는 1
REPLACE 일치하는 부분 문자열 치환 행을 대체하는 REPLACE 문과 별개
CHAR_LENGTH / LENGTH 문자 수 / 바이트 수 멀티바이트 문자에서 서로 다름

연습 데이터를 준비하고 표시용 문자열 만들기

학습용 MariaDB 서버의 shopcourse에 course_user로 접속합니다. 명령줄 클라이언트와 UTF-8 SQL 파일 실행 방법대로 코드를 UTF-8 파일에 저장하고 SOURCE C:/mariadb-lab/lesson.sql;처럼 실제 파일 경로로 실행할 수 있습니다. SQL 문은 운영체제 터미널이 아닌 MariaDB 연결 안에서 실행합니다.

먼저 SELECT VERSION(), DATABASE();와 SHOW TABLES;로 대상 서버·DB·이름 중복을 확인합니다. 아래 products_19_lab는 이 글의 독립된 연습용 이름입니다. 이미 존재하면 정의와 행을 확인하고, 보관할 자료가 없는 이 글의 실습 테이블임이 확실할 때만 마지막 절의 정리 순서로 지운 뒤 다시 만듭니다. 기존 강좌의 동명 없는 테이블이나 운영 데이터는 삭제하지 않습니다.

USE shopcourse;
CREATE TABLE products_19_lab (
  product_id INT NOT NULL AUTO_INCREMENT,
  product_name VARCHAR(100) NOT NULL,
  category VARCHAR(30) NOT NULL,
  price DECIMAL(10,2) NOT NULL,
  stock INT NOT NULL DEFAULT 0,
  note VARCHAR(100) NULL DEFAULT NULL,
  PRIMARY KEY (product_id),
  CONSTRAINT ck_p19_price CHECK (price >= 0),
  CONSTRAINT ck_p19_stock CHECK (stock >= 0)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO products_19_lab (product_id,product_name,category,price,stock,note) VALUES (1, '노트', '문구', 3500.00, 20, NULL),
  (2, '볼펜', '문구', 1500.00, 0, ''),
  (3, '머그컵', '생활', 8000.00, 12, '선물 포장'),
  (4, '스탠드', '생활', 25000.00, 5, NULL),
  (5, '파일', '문구', 1500.00, 50, ''),
  (6, '케이블', '전자', 8000.00, 0, '호환 확인');

상품 메모에는 NULL과 빈 문자열이 함께 있습니다. 같은 입력에 서로 다른 연결 함수를 적용하면 표시 정책이 드러납니다. NULL과 빈 문자열 비교 실습에서 두 상태의 차이를 먼저 확인할 수 있습니다.

SELECT product_id, CONCAT(product_name,' / ',category) AS label,
 CONCAT_WS(' / ',product_name,note) AS note_label
FROM products_19_lab ORDER BY product_id;

첫 상품의 label은 노트 / 문구이고 note_label은 노트입니다. note가 NULL인 경우 CONCAT_WS가 해당 인수를 생략했기 때문입니다. 반면 볼펜의 메모는 빈 문자열이므로 구분자가 붙은 결과가 될 수 있습니다. 화면에 구분자가 남는다고 NULL 데이터로 바꾸지 말고 빈 메모의 표시 정책을 정해야 합니다.

문자 위치를 기준으로 필요한 부분 꺼내기

SELECT SUBSTRING('MariaDB',1,5), SUBSTRING('MariaDB',-2);
SELECT REPLACE('010-1234-5678','-','') AS normalized_phone;

결과는 Maria, DB, 01012345678입니다. SUBSTRING의 시작 위치는 0이 아니라 1이며 음수 위치는 뒤쪽을 기준으로 계산합니다. 길이는 바이트가 아닌 문자 기준이므로 한글 문자열도 문자 위치로 다룰 수 있습니다. 코드 앞부분을 무조건 자르기 전에 그 위치가 업무상 고정되어 있는지도 확인하세요. SUBSTRING 문법과 위치 규칙을 참고할 수 있습니다.

REPLACE 함수는 일치하는 부분 문자열을 바꿉니다. 문서 전체를 업데이트하는 명령은 아니며, 전화번호에서 구분자를 지운 결과를 식별값으로 저장할지는 별도의 검증이 필요합니다. 국가 번호·내선·앞자리 0 같은 정보를 숫자 변환으로 없애지 않도록 주의합니다.

문자 수와 바이트 수를 비교하기

SELECT CHAR_LENGTH('한글'), LENGTH('한글'),
 CHAR_LENGTH('🙂'), LENGTH('🙂');

클라이언트와 문자열이 utf8mb4인 실습에서는 한글은 2문자·6바이트, 이모지는 1문자·4바이트입니다. UI에서 보이는 하나의 기호가 여러 코드 포인트의 조합일 수도 있으므로 CHAR_LENGTH가 언제나 사람이 인식하는 글자 묶음의 수와 같다고 단정하지는 않습니다.

입력 제한을 100자로 정하는 일과 네트워크·저장소의 100바이트를 제한하는 일은 다릅니다. 문자열 타입과 길이 기준을 함께 확인하고, 바이트 수를 임의로 잘라 잘못된 UTF-8 조각을 만들지 않습니다.

NULL·빈 문자열·공백 정리의 차이 확인하기

SELECT CONCAT('노트',NULL),
 CONCAT_WS(' / ','노트',NULL,'');
SELECT CONCAT('[',TRIM('  노트  '),']');

첫 결과는 NULL이며 둘째 결과에는 빈 문자열 때문에 마지막 구분자가 남습니다. TRIM 예제는 양끝의 기본 공백을 제거해 [노트]를 만듭니다. TRIM이 모든 종류의 유니코드 공백이나 문자열 중간 공백까지 제거하는 기능은 아닙니다. 사용자 이름·비밀번호처럼 공백 자체가 의미 있는 값은 일괄 정리하지 않습니다.

문자열 비교에는 열의 정렬 규칙이 영향을 줍니다. 대소문자·악센트·끝 공백을 구분해야 하는 업무에서는 함수만 바꾸기보다 타입과 collation을 함께 검토합니다. MariaDB 문자열 함수 안내에서 함수별 NULL과 변환 동작을 확인하세요.

원본과 가공 결과를 나란히 점검하고 반복하기

새 표시값만 출력하지 말고 기본키·원본 열·가공 열을 함께 조회합니다. 잘린 값이 예상보다 짧으면 위치와 길이를, 연결 결과가 NULL이면 각 인수를, 한글이 깨지면 파일·연결 문자 집합을 확인합니다. 원본을 UPDATE하기 전에는 SELECT로 가공 규칙을 검증하고 복구 가능한 변경 절차를 따르세요.

반복하기 전 현재 DB와 실제 정의·행을 확인하고 필요한 자료를 백업합니다. 보관할 데이터가 없는 이 글의 전용 실습 객체만 아래 순서로 정리합니다. 외래키가 있으면 자식부터 지웁니다. DROP TABLE은 구조와 데이터를 모두 없애며 일반적인 ROLLBACK으로 복원되지 않으므로 취소 가능한 DML 실습과 분리합니다.

DROP TABLE shopcourse.products_19_lab;
같은 카테고리의 다른 글
MariaDB 강좌 / 두 연결로 격리 수준·잠금·교착 상태 확인하기

MariaDB 강좌 / 두 연결로 격리 수준·잠금·교착 상태 확인하기

별도 연결 A·B의 실행 순서대로 격리 수준, 행 잠금 대기와 교착 상태를 비교합니다. 초기화·재조회·오류 후 정리와 연결별 설정 복원까지 전체 코드로 확인합니다.

MariaDB 강좌 / ALTER TABLE로 구조 변경하기: 열·제약 조건·변경 전 점검

MariaDB 강좌 / ALTER TABLE로 구조 변경하기: 열·제약 조건·변경 전 점검

ALTER TABLE을 새 코드 열 추가·기존 행 채우기·제약 적용으로 나누어 실습합니다. NULL·중복 사전 검사, MODIFY 속성 보존, 실제 실패 입력과 잠금·복구 계획을 설명합니다.

MariaDB 강좌 / mariadb-dump로 데이터베이스 백업하기

MariaDB 강좌 / mariadb-dump로 데이터베이스 백업하기

별도 주문 실습 DB를 준비해 mariadb-dump로 새 SQL 백업 파일을 만듭니다. 종료 코드·해시·문자 인코딩, InnoDB 스냅샷과 동시 DDL의 한계, 객체·권한·별도 복원 검증 기준을 설명합니다.

MariaDB 강좌 / WHERE로 조건 지정하기: 비교·AND·OR·IN·BETWEEN·LIKE

MariaDB 강좌 / WHERE로 조건 지정하기: 비교·AND·OR·IN·BETWEEN·LIKE

상품 가격·분류·재고·이름으로 WHERE 조건을 실습합니다. AND·OR 괄호 차이, IN 목록, BETWEEN 경계, LIKE 와일드카드와 실제 퍼센트 검색을 예상 행 번호로 확인합니다.

MariaDB 강좌 / Ubuntu에 MariaDB 설치하고 서버 실행하기

MariaDB 강좌 / Ubuntu에 MariaDB 설치하고 서버 실행하기

Ubuntu APT 설치 후 서버 실행·자동 시작·관리자 소켓 인증을 확인합니다. 로컬 TCP 학습 계정을 만들고 패키지 버전, 인증 오류와 서비스 로그를 확인하는 절차를 설명합니다.

MariaDB 강좌 / 명령줄 클라이언트로 접속하고 SQL 파일 실행하기

MariaDB 강좌 / 명령줄 클라이언트로 접속하고 SQL 파일 실행하기

터미널 명령과 SQL 입력 위치를 구분하고 학습 계정으로 접속합니다. UTF-8 SQL 파일의 SOURCE 실행, 예상 결과, 오류 중단·한글 표시·경로 문제를 함께 확인합니다.

MariaDB 강좌 / 복제 구조와 지연·오류·장애 대응 이해하기

MariaDB 강좌 / 복제 구조와 지연·오류·장애 대응 이해하기

빈 두 서버를 준비하는 로컬 Compose 구성과 복제 상태·지연·오류 진단을 설명합니다. 적용 중지·재개를 관찰하고 백업과 장애 승격의 경계를 구분합니다.

MariaDB 강좌 / 여러 테이블 JOIN하기: 중복 행과 집계 오류 확인

MariaDB 강좌 / 여러 테이블 JOIN하기: 중복 행과 집계 오류 확인

고객·주문·상세·상품을 JOIN하고 행 증가에 따른 배송비 중복 합산을 확인합니다. COUNT DISTINCT와 SUM DISTINCT의 차이, 주문별 선집계로 올바른 금액을 얻는 방법을 설명합니다.

MariaDB 강좌 / 서브쿼리·EXISTS·NOT EXISTS로 조건 표현하기

MariaDB 강좌 / 서브쿼리·EXISTS·NOT EXISTS로 조건 표현하기

평균값 서브쿼리와 EXISTS·NOT EXISTS를 상품·고객·주문으로 실습합니다. 한 값의 반환 조건, 상관 키 누락, paid 주문 부재의 정의와 NOT IN의 NULL 함정을 설명합니다.

MariaDB 강좌 / CREATE TABLE로 테이블 구조 정의하기

MariaDB 강좌 / CREATE TABLE로 테이블 구조 정의하기

상품 테이블을 예로 열·타입·기본값·기본키·저장 엔진을 정의하고 실제 생성 결과를 확인합니다. 기존 테이블 처리, IF NOT EXISTS의 한계와 안전한 반복 실습 방법도 설명합니다.