[MySQL] 2. 테이블에서 데이터 검색

2019. 4. 16. 11:39·DB/MySQL
반응형

<!doctype html>

4. 데이터 조회하기

SQL을 통해 데이터를 조회해보자.

 

1) 'SELECT * FORM 테이블명' 실행

SQL 명령은 mysql클라이언트를 통해 실행할 수 있다.

 
 
 
 
 
 
 
 
SELECT * FROM 테이블명
 
 
 
 
 
xxxxxxxxxx
 
 
 
 
SELECT * FROM employees;
 
 
select_table

SELECT 문을 통해 데이터를 조회할 수 있다.

 

2) SELECT 명령 구문

SELECT는 DML에 속하는 명령으로 SQL에서 자주 사용된다. SELECT 명령으로 데이터베이스의 데이터를 읽어올 수 있다.

 
 
 
xxxxxxxxxx
 
 
 
 
SELECT *        //열 이름, *은 모든 열
FROM employees;
 
 

*는 테이블의 모든 열을 출력하도록 한다. 열 이름을 지칭하면 해당 열의 데이터들만 표시된다.

 

3) 예약어와 데이터베이스 객체명

SQL에서 이미 사용되고 있는 키워드(SELECT, FROM, INSERT, ...)는 테이블이나 기타 데이터 베이스 객체의 이름으로 사용할 수 없다.
또 예약어와 데이터베이스 객체명은 대소문자를 구분하지 않는다. 예약어는 대문자로, 데이터베이스 객체는 소문자로 표기하는 것이 일반적이다.

 

4) NULL

SELECT의 결과 NULL값을 가지는 셀이 존재할 수 도 있다. NULL은 특별한 데이터 값으로 아무것도 저장되어 있지 않은 상태를 의미한다.

 

 

5. 테이블 구조 참조하기

DESC 명령으로 테이블 구조를 참조할 수 있다.

 

1) DESC 명령

 
 
 
xxxxxxxxxx
 
 
 
 
DESC 테이블명;
 
 
 
 
 
xxxxxxxxxx
 
 
 
 
DESC employees
 
 
DESC

이와 같이 DESC 명령으로 테이블에 어떤 열이 정의되어 있는지 알 수 있다.

  • Field : 열 이름
  • Type : 해당 열의 자료형
  • Null : NULL값 허용 여부
  • Key : 키로 지정되었는지
  • Default : 기본값

※모든 테이블 보기

 
 
 
xxxxxxxxxx
 
 
 
 
SHOW TABLES
 
 

이걸로 현재 스키마의 테이블 목록을 확인할 수 있다.

 

2) 자료형

테이블은 하나 이상의 열로 구성된다. 자료형을 통해 데이터를 올바른 형식에 맞게 저장/관리 할 수 있다.

 

CHAR 데이터 타입

CHAR와 VARCHAR(VARiable length CHARacter string)은 모두 텍스트 문자열을 허용하고, 필드의 크기를 제한한다. 두 타입의 차이점은 CHAR 필드의 모든 문자열은 크기가 정해진다는 것. 즉 더 작은 문자열을 입력하면 공백으로 채워진다. 반면 VARCHAR의 경우, 텍스트를 채우지 않으며, 입력한 텍스트 크기에 맞게 가변적으로 크기를 가진다. 그러나, VARCHAR는 각 값의 크기를 추적할 수 있는 약간의 오버헤드가 필요하기 때문에 모든 데이터의 크기가 비슷하다면, CHAR가 더 효율적이다.

TYPE 사용되는 바이트 예제
CHAR(n) 정확히 n (<=255) CHAR(5) 'Hello'는 5바이트 사용CHAR(50) / 'Hello'는 50바이트 사용
VARCHAR(n) 최대 n 까지(<=65535) VARCHAR(100)'Hello'는 5바이트 사용 / VARCHAR(5) 'Hello'는 5바이트 사용

 

BINARY 데이터 타입

BINARY 데이터 타입은 관련된 문자 세트가 없는 문자의 전체 바이트를 저장하는데 사용된다. 예를 들면 GIF 이미지를 저장하는데 사용할 수 있다.

TYPE 사용되는 바이트 예제
BINARY(n) 혹은 BYTE(n) 정확히 n (<=255) CHAR이지만 바이너리 데이터를 가짐
VARBINARY(n) 최대 n 까지(<=65535) VARCHAR이지만 바이너리 데이터를 가짐

 

TEXT와 VARCHAR 데이터 타입

TEXT와 VARCHAR에는 작은 차이점이 있다.

TEXT 필드는 기본 값을 가질 수 없다.
MySQL은 TEXT 열의 처음 n 개의 문자만 인덱싱 할 수 있다.
이것은, 만약 전체 내용을 검색할 때는 VARCHAR이 더 알맞고, 빠르다는 것이다.

TYPE 사용되는 바이트 예제
TINYTEXT(n) 최대 n (<=255) 문자열로 취급
TEXT(n) 최대 n (<=65535) 문자열로 취급
MEDIUMTEXT(n) 최대 n (<=16777215) 문자열로 취급
LONGTEXT(n) 최대 n (<=4294967295) 문자열로 취급

 

BLOB 데이터 타입

BLOB(Binary Large OBject)는 65535 바이트를 넘는 바이너리 데이터에 유용하며, 기본 값을 가질 수 없다. MySQL에서 대량의 데이터를 저장하려면 TEXT나 BLOB 타입을 사용하는데, 이 두 타입은 많은 부분에서 거의 똑같은 설정이나 방식으로 작동한다. 차이점은 TEXT 타입은 문자열을 저장하는 대용량 칼럼이라서 Character Set과 Collation을 가진다는 점이다.

TYPE 사용되는 바이트 예제
TINYBLOB(n) 최대 n (<=255) 바이너리 데이터로 취급
BLOB(n) 최대 n (<=65535) 바이너리 데이터로 취급
MEDIUMBLOB(n) 최대 n (<=16777215) 바이너리 데이터로 취급
LONGBLOB(n) 최대 n (<=4294967295) 바이너리 데이터로 취급

 

숫자형 데이터 타입
TYPE 사용되는 바이트 최소 값(signed/unsigned) 최대 값(signed/unsigned)
TINYINT 1 -128 / 0 127 / 255
SMALLINT 2 -32768 / 0 32767 / 65535
MEDIUMINT 3 -8388608 / 0 8388607 / 16777215
INT or INTEGER 4 -2147483648 / 0 2147483647 / 4294967295
BIGINT 8 -9223372036854775808 / 0 9223372036854775807 / 18446744073709551615
FLOAT 4 -3.40E+45 / (no unsigned) 3.40E+45 / (no unsigned)
DUBLE or REAL 8 -1.7976E+320 / (no unsigned) 1.7976E+320 / (no unsigned)

참고로 INT[(n)]에서 (n)의 의미는 ZEROFILL을 위한 값이다.

 
 
 
xxxxxxxxxx
 
 
 
 
id INT(5) ZEROFILL
 
 

이런식으로 열을 생성 했을 때, 5자리에 맞게 0이 들어간다.

참고1, 참고2, 참고3

 

날짜, 시간
TYPE 사용되는 바이트 값의 범위
YEAR 1 YEAR(2) : 70(1970) ~ 69(2069)
TIME 3 '-838:59:59' ~ '838:59:59
DATE 3 '1000-01-01' ~ '9999-12-31'
TIMESTAMP 4 '1970-01-01 00:00:01' ~ '2038-01-19 : 03:14:07'(UTC)
DATETIME 8 '1000-01-01 00:00:00' ~ '9999-12-31 23:59:59'

TIMESTAMP와 DATETIME의 차이는 TIMESTAMP는 저장시 UTC로 데이터를 저장하며 조회 시 설정된 time_zone으로 시간을 자동 변경해준다.

 

 

6. 검색 조건 지정하기

SELECT 문 사용시 WHERE을 통해 특정 조건에 맞는 데이터를 검색할 수 있다.

 

1) SELECT 구에서 열 지정하기

 
 
 
xxxxxxxxxx
 
 
 
 
SELCT 열1, 열2, ...
FROM 테이블명
 
 
 
 
 
xxxxxxxxxx
 
 
 
 
SELECT emp_no, first_name
FROM employees;
 
 

실행 결과 SELECT로 지정한 열만 출력하는 것을 확인할 수 있다.

 

2) WHERE 구에서 행 지정하기

테이블에 저장된 수많은 데이터 중 필요한 데이터만 검색하기 위해 WHERE 구를 사용한다.

 
 
 
xxxxxxxxxx
 
 
 
 
SELCT 열
FROM 테이블명
WHERE 조건식
 
 

WHERE 구 뒤의 조건에 일치하는 결과만 반환하게 된다. 조건식에 다양한 표현을 사용할 수 있다.

연산자 설명
\= 같음
<, >, <=, >= 수치비교 연산
!=, <> 다름
IN(값1, 값2, ...) ()안의 모든 값
BETWEEN a AND b a와 b사이의 모든 값
LIKE% 일부 문자열 일치
IS NULL NULL값인지 확인
 
 
 
​x
 
 
 
 
SELECT *
FROM employees
WHERE emp_no in(10001, 10002);    //emp_no = 10001 OR emp_no = 10002
​
SELECT *
FROM employees
WHERE birth_date BETWEEN '1950-01-01' AND '1959-12-31'
​
SELECT *
FROM employees
WHERE birth_date IS NULL;
 
 

 

 

7. 조건 조합하기

조건문에 논리 연산자를 추가하여 더 구체적인 조건을 명세할 수 있다.

 
 
 
xxxxxxxxxx
 
 
 
 
조건식1 AND 조건식2
조건식1 OR 조건식2
NOT 조건식
 
 

 

1) AND

 
 
 
xxxxxxxxxx
 
 
 
 
조건식1 AND 조건식2
 
 

조건식1과 조건식2를 모두 만족하는 행을 선택한다.

 
 
 
xxxxxxxxxx
 
 
 
 
SELECT *
FROM employees
WHERE gender = 'M' AND birth_date > '1950-01-01'
 
 
select_and

 

2) OR

 
 
 
xxxxxxxxxx
 
 
 
 
조건식1 AND 조건식2
 
 

조건식1, 조건식2 중 하나 이상을 만족하는 행을 선택한다.

 
 
 
xxxxxxxxxx
 
 
 
 
SELECT *
FROM employees
WHERE hire_date > '1986-01-01' OR birth_date > '1959-12-31'
 
 
select_or

 

3) AND, OR 주의점

AND와 OR 중 AND의 연산자 우선 순위가 더 높기 때문에 주의가 필요하다.

 
 
 
xxxxxxxxxx
 
 
 
 
WHERE a = 1 OR a = 2 AND b = 1 OR b = 2
=> WHERE a = 1 OR (a = 2 AND b = 1) OR b = 2
 
 

MySQL5.7 perator-precendence

 
 
 
xxxxxxxxxx
 
 
 
 
INTERVAL
BINARY, COLLATE
!
- (unary minus), ~ (unary bit inversion)
^
*, /, DIV, %, MOD
-, +
<<, >>
&
|
= (comparison), <=>, >=, >, <=, <, <>, !=, IS, LIKE, REGEXP, IN
BETWEEN, CASE, WHEN, THEN, ELSE
NOT
AND, &&
XOR
OR, ||
= (assignment), :=
 
 

 

4) NOT

 
 
 
xxxxxxxxxx
 
 
 
 
NOT 조건식
 
 

조건식의 T/F를 F/T로 반환한다.

 
 
 
xxxxxxxxxx
 
 
 
 
SELECT *
FROM employees
WHERE NOT emp_no = 10003;
 
 
select_not

 

 

8. 패턴매칭에 의한 검색

LIKE를 이용하여 문자열이 일부분을 비교하는 부분 검색을 할 수 있다.

\= 연산자는 데이터 값이 완전히 동일한지를 비교한다. 하지만 특정 문자나 문자열이 포함되어 있는지를 검색할 경우도 있다. 이런 경우 사용하는 방법이 패턴매칭 또는 부분 검색이다.

 

1) LIKE로 패턴 매칭하기

 
 
 
xxxxxxxxxx
 
 
 
 
열명 LIKE '패턴'
 
 

패턴을 정의할 때는 %, _를 이용한다.

text_table

테이블

 
 
 
xxxxxxxxxx
 
 
 
 
SELECT *
FROM sample
WHERE text LIKE 'SQL%';
 
 
sql%

'SQL%'는 'SQL'로 시작하는 텍스트를 가져오게 된다. 'SQL'이 포함된 모든 텍스트를 검색하려면 다음과 같이 해야한다.

 
 
 
xxxxxxxxxx
 
 
 
 
SELECT *
FROM sample
WHERE text LIKE '%SQL%';
 
 
%SQL%

1번 행은 'SQL'앞에 아무것도 없는데 검색이 되었다. 이는 %가 빈 문자열도 포함하기 때문이다. _는 빈문자열을 포함하지 않고 하나의 문자를 나타낸다.
LIKE로 %나 _를 검색하기 위해 이스케이프 문자로 \를 사용한다.

 
 
 
xxxxxxxxxx
 
 
 
 
'%\%%'
'%\_%'
 
 

문자 '는 ''로 쓴다. 이스케이프문자 \도 가능

또한 패턴 매칭을 위해 MySQL에서는 정규 표현식을 지원한댜.

LIKE 사용 시 인덱스가 사용되는지 고려해야한다. %가 앞에 붙을 경우, 인덱스를 사용하지 못하게 된다.

 
 
 
xxxxxxxxxx
 
 
 
 
# 개선전 index X
SELECT A.KOR_NM, A.STD_NO, A.RES_NO
FROM SREG110 A
WHERE KOR_NM LIKE '%홍길동%„
​
# %LIKE 비교 개선후
SELECT A.KOR_NM, A.STD_NO, A.RES_NO
FROM SREG110 A
WHERE KOR_NM LIKE '홍길동%„
#LIKE 사용 시 가급적이면 „%‟를 비교 값 앞에 붙이지 않는다.
 
 

 

 

인덱스를 타지 않는 쿼리

인덱스 컬럼 절을 변형한 경우

  • 수식이나 함수 등으로 인덱스 컬럼 절을 변형하였을 경우
  • 반드시 함수나 수식을 사용해야 하는 경우에는 인덱스 컬럼 부분에 적용하지 말고, 여기에 대입되는 컬럼이나 상수부분에 적용해야 한다.
 
 
 
xxxxxxxxxx
 
 
 
 
SELECT column_name FROM table_name WHERE TO_CHAR(column_name, 'YYYYMMDD') = '20130909';
> SELECT column_name FROM table_name WHERE column_name = TO_DATE('20130909', 'YYYYMMDD');
​
SELECT column_name FROM table_name WHERE column_name * 100 > 10000;
> SELECT column_name FROM table_name WHERE column_name = 10000 / 100; 
 
 

 

내부적으로 데이터 형 변환이 일어난 경우

  • 서로 대입되는 항목끼리 데이터 타입이 다르면 내부적인 형 변환에 의해 컬럼이 함수를 사용한 효과를 나타낸다.
 
 
 
xxxxxxxxxx
 
 
 
 
SELECT column_name FROM table_name WHERE column_name  = '20130909'; // DATE 타입의 column
> SELECT column_name FROM table_name WHERE column_name = TO_DATE('20130909', 'YYYYMMDD');
​
SELECT column_name FROM table_name WHERE column_name  = 100; // 문자 타입의 column
> SELECT column_name FROM table_name WHERE column_name = '100';
 
 

 

조건절에 NULL 또는 NOT NULL을 사용하는 경우

  • 기본적으로 인덱스를 구성한 컬럼 값이 전부 NULL이라면 인덱스는 이런 값을 저장하지 않는다.

따라서 NULL인 값이 많지 않아 인덱스를 통해 엑세스를 하고자 한다면 데이터 생성 시 디폴트로 0과 같이 데이터를 만들어주는 것이 좋다. 반대로, 만약 NOT NULL이 분석 대상이라면 해당 컬럼을 NULL 허용 컬럼으로 두는 것이 좋다.

 
 
 
xxxxxxxxxx
 
 
 
 
SELECT column_name FROM table_name WHERE column_name IS NULL;
SELECT column_name FROM table_name WHERE column_name IS NOT NULL;
> SELECT column_name FROM table_name WHERE column_name > '';
> SELECT column_name FROM table_name WHERE column_name >= 0;
 
 

 

부정형으로 조건을 사용한 경우

  • 부정문은 인덱스를 활용하지 못한다.
 
 
 
xxxxxxxxxx
 
 
 
 
SELECT column_name FROM table_name WHERE column_name != 30;
> SELECT column_name FROM table_name WHERE column_name < 30 AND column_name > 30;
# 또는 테이블을 한 번 더 읽어 NOT EXISTS를 사용
> SELECT column_name FROM table_name WHERE NOT EXISTS
> (SELECT column_name FROM table_name WHERE column_name = 30);
 
 

 

LIKE 연산자를 사용하였을 경우

  • LIKE 연산자를 이용하여 검색을 할 경우 %를 앞에 넣어 사용하게 되면 인덱스를 타지 않는다.
 
 
 
xxxxxxxxxx
 
 
 
 
SELECT column_name FROM table_name WHERE column_name LIKE '%S%';
> SELECT column_name FROM table_name WHERE column_name LIKE 'S%';
​
가능하면 INSTR을 사용하는 것도 나쁘지 않다.[MySQL INSTR() Function](https://www.w3schools.com/SQl/func_mysql_instr.asp)
​
INSTR('비교할 대상', '비교하고자하는 값', 비교를 시작할 위치, 검색된 결과의 순번);
SELECT column_name  FROM table_name WHERE INSTR(column_name  , 'cmp_value') > 0;
 
 

 

OR 조건 사용

SELECT column_name FROM table_name1 t1, table_name2 t2
WHERE (t1.column_name1 = t2.column_name1 OR t1.column_name2 = t2.column_name2)
AND t1.column_name3 = 'cmp_value';

> SELECT column_name FROM table_name1 t1, table_name2 t2
WHERE t1.column_name1 = t2.column_name1 AND t1.column_name3 = 'cmp_value';
UNION ALL
SELECT column_name FROM table_name1 t1, table_name2 t2
WHERE t1.column_name2 = t2.column_name2 AND t1.column_name3 = 'cmp_value';

참고

 

반응형
저작자표시 비영리 변경금지 (새창열림)
'DB/MySQL' 카테고리의 다른 글
  • [MySQL] 4. 데이터의 추가, 삭제, 갱신
  • [MySQL]3. 정렬과 연산
  • [MySQL] 1. 데이터베이스와 SQL
  • [MySQL] worckbench로 다이어그램 그리기
덴마크초코우유
덴마크초코우유
IT, 알고리즘, 프로그래밍 언어, 자료구조 등 정리
    반응형
  • 덴마크초코우유
    이것저것끄적
    덴마크초코우유
  • 전체
    오늘
    어제
    • 분류 전체보기 (117)
      • Spring Framework (2)
        • Spring (2)
        • JPA (2)
        • Spring Security (0)
      • Language (51)
        • Java (11)
        • Python (10)
        • JavaScript (5)
        • NUXT (2)
        • C C++ (15)
        • PHP (8)
      • DB (16)
        • MySQL (10)
        • Reids (3)
        • Memcached (2)
      • 개발 (1)
      • 프로젝트 (2)
      • Book (2)
      • PS (15)
        • 기타 (2)
        • 백준 (2)
        • 프로그래머스 (10)
      • 딥러닝 (8)
        • CUDA (0)
        • Pytorch (0)
        • 모델 (0)
        • 컴퓨터 비전 (4)
        • OpenCV (1)
      • 기타 (16)
        • 디자인패턴 (2)
        • UnrealEngine (8)
        • ubuntu (1)
        • node.js (1)
        • 블로그 (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 미디어로그
    • 위치로그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    CPP
    redis
    C++
    자바
    Unreal
    FPS
    mscoco
    C
    프로그래머스
    게임 개발
    NUXT
    select
    Unreal Engine
    JS
    map
    딥러닝
    클래스
    PS
    게임
    블루프린트
    알고리즘
    JavaScript
    memcached
    웹
    php
    언리얼엔진4
    Python
    MySQL
    pytorch
    파이썬
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
덴마크초코우유
[MySQL] 2. 테이블에서 데이터 검색
상단으로

티스토리툴바