2020년 10월 29일

업데이트:


Database

한 조직에 필요한 정보를 여러 응용 시스템에서 공용할 수 있도록 논리적으로 연관된 데이터를 모으고 중복되는 데이터를 최소화하여 구조적으로 통합/저장해놓은 것이다.


정의

  1. 공용 데이터(Shared Data) : 공동으로 사용되는 데이터
  2. 통합 데이터(Integrated Data) : 중복 최소화로 중복으로 인한 데이터 불일치 현상 제거
  3. 저장 데이터(Stored Data) : 컴퓨터 저장장치에 저장된 데이터
  4. 운영 데이터(Operational Data) : 조직의 목적을 위해 사용되는 데이터

특징

  1. 실시간 접근성(Real Time accessibility) : 사용자가 데이터 요청 시 실시간으로 결과를 서비스한다.
  2. 계속적인 변화(Continuos change) : 데이터 값은 시간에 따라 항상 바뀐다.
  3. 동시 공유(Concurrent Sharing) : 서로 다른 업무 또는 여러 사용자에게 동시 공유된다.
  4. 내용에 따른 참조(Reference by content) : 데이터의 물리적 위치가 아닌 데이터 값에 따라 참조한다.

DBMS(DataBase Management System)

데이터베이스에서 데이터 추출, 조작, 정의 제어 등을 할 수 있게 해주는 데이터베이스 전용 관리 프로그램이다.


기능

  1. 데이터 추출(Retrieval) : 사용자가 조회하는 데이터 혹은 응용 프로그램의 데이터 추출
  2. 데이터 조작(Manipulation) : 데이터를 조작하는 소프트웨어가 요청하는 데이터 삽입, 수정, 삭제 지원
  3. 데이터 정의(Definition) : 데이터의 구조를 정의하고 데이터 구조에 대한 삭제 및 변경 기능을 수행
  4. 데이터 제어(Control) : DB 사용자를 생성하고 모니터링하며 접근을 제어한다. 백업과 회복, 동시성 제어 등의 기능을 지원한다.

DBMS 사용 시 이점

  1. 데이터 독립화
    데이터와 응용 프로그램을 분리시킴으로써 상호 영향 정도를 줄일 수 있다.
  2. 데이터 중복 최소화, 데이터 무결성 보장
    중복되는 데이터를 최소화 시키면 데이터 무결성이 손상될 가능성이 줄어듦 중복되는 데이터를 최소화 시키면 필요한 저장공간의 낭비를 줄일 수 있다.
  3. 데이터 보안 향상
    응용 프로그램은 DBMS를 통해 DBMS가 허용하는 데이터에만 접근이 가능하며 권한에 맞게 데이터 접근을 제한하거나, 데이터를 암호화시켜 저장이 가능하다.
  4. 관리 편의성 향상
    다양한 방법으로 데이터 백업이 가능하며 장애 발생 시 데이터 복구가 가능하다.

DBMS 유형

  • 계층형 데이터베이스
    트리 형태의 계층적 구조를 가진 데이터베이스로 최상위 계층의 데이터부터 검색하는 구조를 갖는다.
  • 네트워크형 데이터베이스
    하위 데이터들끼리의 관계까지 정의할 수 있는 구조로, 설계 및 구현이 복잡하고 어렵다.
  • 관계형 데이터베이스
    모든 데이터를 2차원 테이블 형태로 표현하고, 테이블 사이의 비즈니스적 관계를 도출하는 구조를 갖는다. 데이터의 중복을 최소화 할 수 있으며 업무 변화에 대한 적응력이 우수하다.
  • 객체-관계형 데이터베이스
    1. 사용자 정의 타입 지원
    2. 참조(Reference) 타입 지원
    3. 중첩 테이블 지원
    4. 대단위 객체의 저장 및 추출 가능
    5. 객체간의 상속관계 지원

SQL(Structured Query Language)

관계형 데이터베이스에서 데이터를 조회하거나 조작하기 위해 사용하는 표준 검색 언어로, 원하는 데이터를 찾는 방법이나 절차를 기술하는 것이 아닌 조건을 기술하여 작성한다.

분류 용도 명령어                    
DQL(Data Query Language) 데이터 검색 SELECT                    
DML(Data Manipulation Language) 데이터 조작 INSERT, UPDATE, DELETE                    
DDL(Data Definition Language) 데이터 정의 CREATE, DROP, ALTER                    
TCL(Transaction Control Language) 트랜잭션 제어 COMMIT, ROLLBACK                    



SELECT

데이터를 조회한 결과를 Result Set이라고 하는데 SELECT 구문에 의해 반환된 행들의 집합을 의미한다. Result Setd은 0개 이상의 행이 포함될 수 있고, Result Set은 특정한 기준에 의해 정렬이 가능하다. 한 테이블의 특정 컬럼, 특정 행, 특정 행/컬럼 또는 여러 테이블의 특정 행/컬럼이 조회 가능하다.

-- 작성 방법
SELECT 컬럼명[, 컬럼명, ...]
FROM 테이블명
WHERE 조건식;



오라클 실습

-- EMPLOYEE 테이블의 모든 사원 정보를 모두 조회
SELECT * FROM EMPLOYEE;

-- EMPLOYEE 테이블의 모든 사원의 사번, 이름 조회
SELECT EMP_ID, EMP_NAME FROM EMPLOYEE;

-- EMPLOYEE 테이블에서 모든 사원의 이름, 이메일, 전화번호 조회
SELECT EMP_NAME, EMAIL, PHONE FROM EMPLOYEE;

-- 1. JOB 테이블의 모든 정보 조회
SELECT * FROM JOB;
-- 2. JOB 테이블의 직급명만 조회
SELECT JOB_NAME FROM JOB;
-- 3. DEPARTMENT 테이블의 모든 정보 조회
SELECT * FROM DEPARTMENT;
-- 4.EMPLOYEE 테이블의 이름, 이메일, 전화번호, 고용일 조회
SELECT EMP_NAME, EMAIL, PHONE, HIRE_DATE FROM EMPLOYEE;
-- 5. EMPLOYEE 테이블의 고용일, 사원명, 월급 조회
SELECT HIRE_DATE, EMP_NAME, SALARY FROM EMPLOYEE;

----------------------------------------------------------------------------------

-- 컬럼 값 산술 연산 
-- SELECT 시 컬럼명 입력 부분에 계산이 필요한 컬럼명 + 숫자, 연산자를 이용하여
-- 원하는 계산 결과를 조회할 수 있음

-- EMPLOYEE 테이블에서 사원들의 이름, 급여, 연봉 조회
SELECT EMP_NAME, SALARY, SALARY * 12 FROM EMPLOYEE;

-- EMPLOYEE 테이블에서 사원의 이름과 보너스가 반영된 연봉 조회

-- (SALARY + SALARY * BONUS) * 12
SELECT EMP_NAME, SALARY * (1+BONUS) * 12 FROM EMPLOYEE;
-- DB에서 산술 연산 시 NULL 값이 포함되어 있다면 결과는 무조건 NULL


-- EMPLOYEE 테이블에서 사원의 이름, 고용일, 근무 일수 조회
-- * DATE 타입끼리의 산술 연산,
-- DATE, NUMBER 타입의 산술 연산이 가능함
-- SYSDATE : 현재 시간을 조회하는 키워드
SELECT EMP_NAME, HIRE_DATE, SYSDATE - HIRE_DATE
FROM EMPLOYEE;

---------------------------------------------------------------------

/* 컬럼 별칭
 컬럼명 [AS] 별칭      / 컬럼명 "별칭"  / 컬럼명 AS "별칭"
 특수문자, 띄어쓰기 X /   특수문자, 띄어쓰기 O("" 쓰면 특문 가능)
 
*/

-- EMPLOYEE 테이블에서 사원의 이름, 입사일, 근무일수 조회
-- 컬럼명이 모두 이름, 입사일, 근무일수로 별칭 지정
SELECT EMP_NAME AS 이름, HIRE_DATE 입사일, SYSDATE - HIRE_DATE "근무 일수" FROM EMPLOYEE;


--------------------------------------------------------------------------------------

-- 리터럴
-- 임의로 지정한 문자열을 SELECT절에 사용하면
-- 테이블에 존재하는 데이터처럼 사용할 수 있음
-- 리터럴의 표기 기호는 ''(홀따옴표)
-- 리터럴은 RESULT SET의 모든 결과 행에 반복적으로 표시됨.

-- EMPLOYEE 테이블에서 
-- 사번, 사원명, 급여, 단위(데이터 : 원) 조회
SELECT EMP_ID, EMP_NAME, SALARY, '원' AS 단위 FROM EMPLOYEE;


-- DISTINCT
-- 컬럼에 포함된 중복값을 한번만 표시하고자 할 때 사용

-- EMPOLYEE 테이블에서 직원의 직급 코드를 조회
SELECT JOB_CODE FROM EMPLOYEE;

-- EMPLOYEE 테이블에서 직원의 직급 코드를 중복 없이 조회
SELECT DISTINCT JOB_CODE FROM EMPLOYEE;

-- *DISTINCT 주의 사항
-- -> DISTINCT SELECT절 하나당 한 번만 사용 가능
SELECT DISTINCT JOB_CODE, DISTINCT, DEPT_CODE FROM EMPLOYEE;

// DISTINCT 뒤쪽에 작성된 컬럼명을 모두 중복값을 제거하여 출력함
SELECT DISTINCT JOB_CODE,  DEPT_CODE FROM EMPLOYEE;

-----------------------------------------------------

-- WHERE 절
-- 조회할 테이블에서 조건이 맞는 값을 가진 행을 골라내는 구문

-- WHERE절에는 TRUE, FALSE가 나올 수 있는 비교 연산자가 사용됨
-- >, <, >=, < =
-- = (같다), !=, ^=, <> (같지 않다.)

-- EMPLOYEE 테이블에서 부서코드가 'D9'인 직원의 사번, 이름, 부서코드 조회
SELECT EMP_ID, EMP_NAME, DEPT_CODE FROM EMPLOYEE WHERE DEPT_CODE = 'D9';


-- EMPLOYEE 테이블에서 급여가 4백만원 이상인 직원 이름, 급여 조회
SELECT EMP_ID, SALARY FROM EMPLOYEE
WHERE SALARY >= 4000000;

-- EMPLOYEE 테이블에서 부서코드가 'D9'이 아닌 사원의 이름, 부서 코드 조회
SELECT EMP_NAME, DEPT_CODE FROM EMPLOYEE WHERE DEPT_CODE != 'D9';

-- EMPLOYEE 테이블에서 퇴사한 사원의 이름, 전화번호, 부서코드 조회
SELECT EMP_NAME, PHONE, DEPT_CODE FROM EMPLOYEE WHERE ENT_YN = 'Y';


--------------------------------------------------------------------

-- 1. EMPLOYEE 테이블에서 SAL_LEVEL S1인 사원의 이름, 월급, 고용일, 연락처 조회
SELECT EMP_NAME 이름, SALARY 월급, HIRE_DATE 고용일, PHONE 연락처 FROM EMPLOYEE WHERE SAL_LEVEL = 'S1';
-- 2. EMPLOYEE 테이블에서 월급이 3000000원 이상인 사원의 이름, 월급, 고용일 조회
SELECT EMP_NAME 이름, SALARY 월급, HIRE_DATE 고용일 FROM EMPLOYEE WHERE SALARY >= 3000000;
-- 3. EMPLOYEE 테이블에서 연봉이 5천만원 미만인 사원의 이름, 월급, 연봉, 고용일 조회
SELECT EMP_NAME 이름, SALARY 월급, SALARY * 12 연봉, HIRE_DATE FROM EMPLOYEE WHERE SALARY * 12 < 50000000;


--------------------------------------------------------------------------------------------------

-- 논리 연산자(AND / OR) 
-- 여러가지 조건이 있을 경우 사용하는 연산자

-- EMPLOYEE 테이블에서 부서코드가 'D6'이고 급여를 200만 이상 받는 직원의 사번, 이름, 부서코드, 급여 조회
SELECT EMP_ID, EMP_NAME, DEPT_CODE, SALARY FROM EMPLOYEE WHERE DEPT_CODE = 'D6' AND SALARY >= 2000000;


-- EMPLOYEE 테이블에서 부서코드가 'D6'이거나 급여를 200만 이상 받는 직원의 사번, 이름, 부서코드, 급여 조회
SELECT EMP_ID, EMP_NAME, DEPT_CODE, SALARY FROM EMPLOYEE WHERE DEPT_CODE = 'D6' OR SALARY >= 2000000;

-- EMPLOYEE 테이블에서 급여를 350만 이상 600만 이하로 받는 직원의 사번, 이름, 급여, 부서코드, 직급코드 조회
SELECT EMP_ID, EMP_NAME, SALARY, DEPT_CODE, JOB_CODE FROM EMPLOYEE WHERE SALARY >= 3500000 AND SALARY <= 6000000 ;

-- EMPLOYEE 테이블에 부서코드가 D5 또는 D9인 사원 중 고용일이 2002년 1월 1일보다 빠른 사원의
-- 사번, 이름, 부서코드, 고용일 조회
SELECT EMP_ID, EMP_NAME, DEPT_CODE, HIRE_DATE FROM EMPLOYEE WHERE (DEPT_CODE = 'D5' OR DEPT_CODE = 'D9') AND HIRE_DATE < '02/01/01';

-- AND가 OR 연산보다 우선 순위가 높음


-- 컬럼명 BETWEEN A AND B >> A 이상 B 이하
-- EMPLOYEE 테이블에서 급여를 350만 이상 600만 이하로 받는 직원의 사번, 이름, 급여, 부서코드, 직급코드 조회 
SELECT EMP_ID, EMP_NAME, SALARY, DEPT_CODE, JOB_CODE FROM EMPLOYEE WHERE SALARY BETWEEN 3500000 AND 6000000;


-- NOT (논리 부정 연산자)
-- EMPLOYEE 테이블에서 급여를 350 미만 600만 초과로 받는 사원의 사번, 이름, 급여, 부서코드, 직급 코드 조회
SELECT EMP_ID, EMP_NAME, SALARY, DEPT_CODE, JOB_CODE FROM EMPLOYEE WHERE SALARY NOT BETWEEN 3500000 AND 6000000;


-- EMPLOYEE 테이블에서 입사일이 '90/01/01' ~ '99/12/31'인 사원의 
-- 이름, 입사일 조회
SELECT EMP_NAME, HIRE_DATE FROM EMPLOYEE WHERE HIRE_DATE BETWEEN '90/01/01' AND '99/12/31';
SELECT EMP_NAME, HIRE_DATE FROM EMPLOYEE WHERE HIRE_DATE NOT BETWEEN '90/01/01' AND '99/12/31';

-- 연결 연산자(||)
-- 여러 컬럼을 하나의 컬럼처럼 연결하거나 컬럼 + 리터럴의 형태를 만들 수 있는 연산자

-- EMPLOYEE 테이블에서 사번, 이름, 급여를 연결해서 조회
SELECT EMP_ID || EMP_NAME || SALARY FROM EMPLOYEE;

-- EMPLOYEE 테이블에서 모든 사원의 이름, 급여 조회
-- 단, 급여 뒤에 '(원)' 단위 붙여서 조회
SELECT EMP_NAME, SALARY || '(원)' 급여 FROM EMPLOYEE;


-----------------------------------------------------------------------------------

-- LIKE (★★★★★★)
/*
비교하려는 값이 지정한 특정 패턴을 만족시키는 데이터를 조회할 때 사용
비교대상컬럼명 LIKE '문자 패턴'
패턴 1) %
'김%' (김으로 시작하는 값)
'%김' (김으로 끝나는 값)
'%김%' (김이라는 글자가 포함되는 값)
패턴 2) _(언더바)
'_' (한 글자)
'__' (두 글자)
'김__' (김으로 시작하는 세 글자)
0101234[1]234
PHONE LIKE _______1%
*/

-- EMPLOYEE 테이블에서 성이 '전'씨인 사원의 사번, 이름, 부서코드 조회
SELECT EMP_ID, EMP_NAME, DEPT_CODE FROM EMPLOYEE WHERE EMP_NAME LIKE '전%';


-- EMPLOYEE 테이블에서 이름에 '하'가 포함된 사원의 사번, 이름, 부서코드 조회
SELECT EMP_ID, EMP_NAME, DEPT_CODE FROM EMPLOYEE WHERE EMP_NAME LIKE '%하%';

-- EMPLOYEE 테이블에서 전화번호 4번째 자리가 7로 시작하는 사원의 사번, 이름, 전화번호 조회
SELECT EMP_ID, EMP_NAME, PHONE FROM EMPLOYEE WHERE PHONE LIKE '___7%';

-- EMPLOYEE 테이블에서 EMAIL 중 '_' 기호 앞이 세글자인 사원의 사번, 이름, 이메일 조회
SELECT EMP_ID, EMP_NAME, EMAIL FROM EMPLOYEE WHERE EMAIL LIKE '___#_%' ESCAPE '#';

SELECT EMP_ID, EMP_NAME, EMAIL FROM EMPLOYEE WHERE EMAIL NOT LIKE '___#_%' ESCAPE '#';


-- ESCAPE OPTIONS 
-- LIKE의 와일드카드 기호와, 검색하려는 기호가 동일할 경우
-- 검색기호를 인식시키기 위해서 사용하는 구문



-- EMPOLYEE 테이블에서 성이 '김'씨가 아닌 사원의 모든 정보 조회
SELECT * FROM EMPLOYEE WHERE EMP_NAME NOT LIKE '김%';

--EMPLOYEE 테이블에서 이름 끝이 '연'으로 끝나는 사원 이름 조회
SELECT * FROM EMPLOYEE WHERE EMP_NAME LIKE '%연';

-- EMPLOYEE 테이블에서 전화번호 처음 세 자리가 010이 아닌 사원의 이름, 전화번호 조회
SELECT EMP_NAME, PHONE FROM EMPLOYEE WHERE  PHONE NOT LIKE '010%';

-- EMPLOYEE 테이블에서 메일주소 '_'의 앞이 네 글자이면서 DEPT)CODE가 D9 또는 D6이고
-- 고용일이 90/01/01 ~ 00/12/01이고, 급여가 270만 이상인 사원의 전체 조회

SELECT * FROM EMPLOYEE WHERE EMAIL LIKE '____$_%'  ESCAPE '$'  AND
(DEPT_CODE = 'D9' OR DEPT_CODE = 'D6') AND 
HIRE_DATE BETWEEN '90/01/01' AND '00/12/01'XDV AND
SALARY >= 2700000;

--------------------------------------------------------------------------------------------

-- IS NULL : 컬럼 값이 NULL인 경우
-- IS NOT NULL : 컬럼 값이 NULL이 아닌 경우

-- EMPOLYEE 테이블에서 보너스를 받지 않는 사원의 사번, 이름, 급여, 보너스 조회
SELECT EMP_ID, EMP_NAEM, SALARY, BONUS 
FROM EMPLOYEE
WHERE BONUS IS NULL;


-- EMPLOYEE 테이블에서 사수(직속 상관)이 없고, 부서코드도 없는 사원의
-- 사원명, 사수 사번, 부서코드 조회
SELECT EMP_NAME, MANAGER_ID, DEPT_CODE
FROM EMPLOYEE
WHERE MANAGER_ID IS NULL AND DEPT_CODE IS NULL;



-- IN
-- 비교하려는 컬럼값과 목록(괄호 내부)에 일치하는 값이 있다면 TRUE를 반환하는 연산자
-- 컬럼명 IN(A, B, C, D); 

-- EMP_NAME = '이오리' OR EMP_NAME = '하동운' OR EMP_NAME = '유재식'
-- MEPLOYEE 테이블에서 부서코드가 D6, D7, D9인 사원의 사번, 이름, 도서코드, 급여 조회
SELECT EMP_ID, EMP_NAME, DEPT_CODE, SALARY FROM EMPLOYEE WHERE DEPT_CODE = 'D6' OR DEPT_CODE = 'D8' OR DEPT_CODE = 'D9';


-- IN 사용
SELECT EMP_ID, EMP_NAME, DEPT_CODE, SALARY 
FROM EMPLOYEE
WHERE DEPT_CODE IN('D6', 'D8', 'D9');


-- 연산자 우선순위
/*
1. 산술 
2. 연결 ||
3. 비교 
4. IS NULL, LIKE, IN
5. BETWEEN A AND B
6. NOT
7. AND
8. OR
*/

--------------------------------------------------------------------------------------------------------------------------------------------------------

-- ORDER BY절(★★★★★) 
 -- SELECT한 결과의 집합(RESULT SET)을 정렬할 때 사용하는 구문
 -- SELECT 구문 제일 마지막 줄에 작성
  -- SELECT문 해석 순서 중에서도 제일 마지막
  
  
-- [작성법]
/*
SELECT 컬럼명, [컬럼명, ..] 
FROM 테이블명
[WHERE 조건식]
[ORDER BY 컬럼명 | 별칭 | 컬럼 순서  정렬 방법(오름차순, 내림차순) [ NULLS FIRST  |  LAST ];
*/

  -- EMPLOYEE 테이블에서 모든 사원의 이름, 급여, 부서코드를 이름 오름차순으로 출력
  SELECT  EMP_NAME, SALARY, DEPT_CODE
  FROM EMPLOYEE
  ORDER BY EMP_NAME /*ASC*/ ; -- 오름차순이 기본값
  
  
    SELECT  EMP_NAME, SALARY, DEPT_CODE
  FROM EMPLOYEE
  ORDER BY 1;  -- 조회한 컬럼 중 첫 번째(EMP_NAME)를 기준으로 정렬
  
  
  -- EMP_NAME 내림차순
      SELECT  EMP_NAME, SALARY, DEPT_CODE
  FROM EMPLOYEE
  ORDER BY 1 DESC;
  
  
  -- EMPLOYEE 테이블에서 모든 사원의 이름, 연봉, 부서코드를 부서코드 내림차순으로 정렬하여 조회
  SELECT EMP_NAME, SALARY * 12 AS 연봉,  DEPT_CODE
  FROM EMPLOYEE 
  ORDER BY DEPT_CODE DESC NULLS LAST; /*NULLS FIRST가 기본값*/
  
  
  
    -- EMPLOYEE 테이블에서 모든 사원의 이름, 연봉, 부서코드를 연봉 내림차순으로 정렬하여 조회
  SELECT EMP_NAME, SALARY * 12 AS 연봉,  DEPT_CODE
  FROM EMPLOYEE 
  ORDER BY 연봉  DESC NULLS LAST; /*NULLS FIRST가 기본값*/
  
  
      -- EMPLOYEE 테이블에서 모든 사원의 이름, 연봉, 부서코드를 연봉 내림차순으로 정렬하여 조회
      -- 단, 연봉이 4천만 이상인 사람만 조회
      
  SELECT EMP_NAME, SALARY * 12 AS 연봉,  DEPT_CODE
  FROM EMPLOYEE 
 WHERE SALARY * 12 >= 40000000 -- WHERE절에는 별칭 사용 불가
  ORDER BY 2  DESC NULLS LAST; /*NULLS FIRST가 기본값*/



문제

-- SQL01_SELECT(Basic).pdf 풀기
-- 3번, 10번 제외

-- 1번
SELECT DEPARTMENT_NAME "학과 명", CATEGORY 계열 
FROM TB_DEPARTMENT;

-- 2번
SELECT DEPARTMENT_NAME || '의 정원은 ' || CAPACITY || '명 입니다.' AS "학과별 정원"  FROM TB_DEPARTMENT;

-- 3번
SELECT STUDENT_NAME FROM TB_STUDENT
WHERE (ABSENCE_YN = 'Y') 
AND (DEPARTMENT_NO = '001') 
AND (STUDENT_SSN  LIKE  '_______2%');


-- 4번
SELECT STUDENT_NAME FROM TB_STUDENT 
WHERE STUDENT_NO   IN ('A513079', 'A513090', 'A513091', 'A513110', 'A513119') 
ORDER BY STUDENT_NO DESC;

-- 5번
SELECT DEPARTMENT_NAME , CATEGORY  FROM TB_DEPARTMENT 
WHERE CAPACITY  BETWEEN 20 AND 30;

-- 6번
SELECT PROFESSOR_NAME FROM TB_PROFESSOR 
WHERE DEPARTMENT_NO IS NULL;

-- 7번
SELECT * FROM TB_STUDENT WHERE DEPARTMENT_NO IS NULL;

-- 8번
SELECT CLASS_NO FROM TB_CLASS WHERE PREATTENDING_CLASS_NO IS NOT NULL ;

-- 9번
SELECT DISTINCT CATEGORY FROM TB_DEPARTMENT ORDER BY CATEGORY ASC ;

-- 10번
SELECT STUDENT_NO, STUDENT_NAME, STUDENT_SSN 
FROM TB_STUDENT
WHERE ENTRANCE_DATE LIKE '02%' 
AND STUDENT_ADDRESS LIKE '전주%'
AND ABSENCE_YN = 'N';

태그:

카테고리:

업데이트:

댓글남기기