관계형 데이터베이스
관계형 데이터베이스는 관계들의 모음 또는 이차원 테이블의 모음이다.
파일 시스템과 데이터베이스 시스템의 차이점
- 데이터의 무결성을 지켜준다.
- 데이터의 공유
- 데이터의 정확성과 일관성
- 중복성의 제거
- 불일치를 피할 수 있다.
- 표준화가 가능하다.
- 데이터의 독립성 보장 -개념화 기법 발달
- 각 테이블들은 고유한 이름을 갖는다.
- 중복 문제의 해결 기법 제공: 정규형
- 데이터의 조작언어의 발달: SQL
- 관계형 데이터베이스는 테이블(table)들의 모음으로 구성
- 각 행은 일련의 값들 사이의 관계(relationship)
관계형 데이터베이스는 SQL(Structured Query Language)문을 사용하여 이용되고 수정한다.
SQL문 이란?
데이터베이스로부터 데이터를 조회, 삭제, 수정, 변경 등의 작업을 수행할 때 사용하는 언어이다.
ER 모델링의 장점
- 조직에 대한 정보를 정확하고 자세하게 문서화할 수 있다.
- 정보 요구사항의 범위를 명확히 기술할 수 있다.
- 데이터베이스 설계를 쉽게 이해할 수 있는 표본을 제공할 수 있다.
- 복수 응용프로그램의 통합화를 위한 효과적 프레임워크를 제공한다.
일반적 개념 | 모델링 | DB객체 |
데이터의 집합, relation, 관계집합(relationship set) |
개체집합(Entity set) 엔티티(Entity) |
테이블(table) |
관계집합 중 어떤 행(row) | 튜플(Tuple) | 레코드(Record) |
관계집합 중 어떤 열(column) | 속성(Attribute) | 필드(Filed) |
- 후보키 (Cadidate key)
- 행(튜플)을 유일하게 식별할 수 있는 키
- 기본키가 될 수 있는 후보를 후보키라고 한다.
- 기본키 (Primary key)
- 후보키 중에서 선택한 주가 되는 키
- 행(튜플)을 유일하게 식별할 수 있는 키
- not null, 중복 X
- 대체키 (Alternate key)
- 후보키가 둘 이상일 때 기본키를 제외한 나머지 후보키
- 슈퍼키 (Super key)
- 테이블(relation) 내에 있는 속성들의 집합으로 구성된 키(2개로 이루어진 키)
- 외래키 (Foreign key)
- 참조되는 테이블(릴레이션)의 기본키와 대응되어 참조관계를 표현하는 키
- 외래키로 지정되면 참조 테이블의 기본키에 없는 값은 입력할 수 없다.
SQL 계정 생성 및 권한 부여
ALTER USER hr ACCOUNT UNLOCK IDENTIFIED BY hr;
SQL 문장
문장 | 설명 | |
DML | SELECT | 데이터베이스로부터 데이터를 검색(조회)한다. |
INSERT | DML(Data Manipulation Language)로 분류된다. 개별적으로 데이터베이스 테이블에서 새로운 행을 입력(INSERT)하고, 기존의 행을 변경(UPDATE)하며, 기존의 행을 제거(DELETE) 한다. |
|
UPDATE | ||
DELETE | ||
DDL | CREATE | DDL(Data Definition Language)로 분류된다. 테이블로부터 데이터 구조를 생성(CREATE), 변경(ALTER), 제거(DROP)한다. 또는 이름을 변경(RENAME)하거나 구조만 남기고 모든 데이터를 삭제(TRUNCATE)한다. |
ALTER | ||
DROP | ||
RENAME | ||
TRUNCATE | ||
TCL | COMMIT | TCL(Transaction Control Language)로 분류된다. DML 명령문으로 만든 변경을 관리하며, 데이터 변경은 논리적 트랜잭션으로 함께 그룹화 될 수 있다. |
ROLLBACK | ||
SAVEPOINT | ||
DCL | GRANT | DCL(Data Control Language)로 분류된다. 데이터베이스에 접근하고 객체들을 사용할 수 있도록 권한을 주거나 회수한다. |
REVOKE |
Selection
- 질의에 대해 리턴하고자 하는 테이블의 행을 선택하기 위해 SQL의 selection 기능을 사용할 수 있다. 보고자 하는 행을 선택적으로 제한하기 위해 다양한 방법을 사용할 수 있다.
Join
- 공유 테이블 양쪽의 열에 대해 링크를 생성하여 다른 테이블에 저장되어 있는 데이터를 함께 가져오기 위해 SQL의 join 기능을 사용할 수 있다.
SELECT [DISTINCT] { * | column [[AS] alias], ... }
FROM table;
- SELECT: 하나 이상의 열을 나열한다.
- DISTINCT: 중복을 제거한다.
- *: 모든 열을 선택한다.
- coulmn: 명명된 열을 선택한다.
- AS: 열 별칭(alias)을 지정한다.
- alias: 선택된 열을 다른 이름으로 변경한다.
- FROM table: 열을 포함하는 테이블을 명시한다.
SELECT *
FROM employees;
SELECT employee_id, first_name, last_name
FROM employees;
SELECT email, phone_number, hire_date
FROM employees;
- 컬럼을 조회하는 위치에서 * / + - (사칙연산) 기호를 연산해서 사용할 수 있다.
SELECT employee_id, first_name, last_name, salary, salary + salary * 0.1
FROM employees;
SELECT department_id, commission_pct
FROM employees;
- alias (컬럼명의 이름을 변경해서 조회)
SELECT first_name as 이름, last_name as 성, salary as 급여
FROM employees;
- 홑따옴표로 문자를 표현하고, 문자열 안에 홑따옴표를 표현하려면 ''를 두번 연속으로 사용한다.
- ||로 연결할 수 있다.
SELECT first_name || ' ' || last_name || '''s salary is $' || salary as 급여내역
FROM employees;
- distinct (중복 행 제거)
SELECT DISTINCT department_id
FROM employees;
- ROWNU: 쿼리에 의해 반환되는 행 번호를 출력
- ROWID: 데이터베이스에서 행의 주소값을 반환
SELECT ROWNUM, ROWID, employee_id
FROM employees;
- WHERE절 비교 (데이터 값은 대/소문자를 구분한다.)
SELECT first_name, last_name, job_id
FROM employees
WHERE job_id = 'IT_PROG';
SELECT *
FROM employees
WHERE last_name = 'king';
SELECT *
FROM employees
WHERE last_name = 'King';
SELECT *
FROM employees
WHERE department_id = 90;
SELECT *
FROM employees
WHERE salary >= 15000;
SELECT *
FROM employees
WHERE hire_date = '04/01/30';
- 데이터 행 제한(BETWEEN, IN, LINK)
SELECT *
FROM employees
WHERE salary BETWEEN 15000 AND 20000;
SELECT *
FROM employees
WHERE hire_date BETWEEN '03/01/01' AND '03/12/31';
SELECT *
FROM employees
WHERE salary >= 15000
AND salary <= 20000;
SELECT *
FROM employees
WHERE manager_id IN (100, 101, 102);
SELECT *
FROM employees
WHERE job_id IN ('IT_PROG', 'AD_VP');
SELECT first_name, hire_date
FROM employees
WHERE hire_date LIKE '03%';
SELECT first_name, hire_date
FROM employees
WHERE hire_date LIKE '%15';
SELECT first_name, hire_date
FROM employees
WHERE hire_date LIKE '%05%';
SELECT first_name, hire_date
FROM employees
WHERE hire_date LIKE '___05%';
SELECT *
FROM employees
WHERE manager_id is null;
SELECT *
FROM employees
WHERE commission_pct is null;
SELECT *
FROM employees
WHERE commission_pct is not null;
SELECT *
FROM employees
WHERE job_id = 'IT_PROG'
OR job_id = 'FI_MGR'
AND salary >= 6000;
- AND가 OR보다 연산순위가 높기 때문에 salary의 값이 다르게 조회할 수 있는 것을 확인할 수 있다.
SELECT *
FROM employees
WHERE (job_id = 'IT_PROG'
OR job_id = 'FI_MGR')
AND salary >= 6000;
- 데이터의 정렬 (SELECT 구문의 가장 마지막에 배치된다.)
- ASC: 오름차순(ascending)
- DESC: 내림차순(descending)
SELECT *
FROM employees
ORDER BY hire_date ASC;
SELECT *
FROM employees
ORDER BY hire_date DESC;
SELECT *
FROM employees
WHERE job_id = 'IT_PROG'
ORDER BY first_name ASC;
SELECT *
FROM employees
WHERE salary >= 5000
ORDER BY employee_id DESC;
SELECT first_name, salary * 12 as pay
FROM employees
ORDER BY pay ASC;
SQL Quiz01
1. 모든 사원의 사원번호, 이름, 입사일, 급여를 출력한다.
2. 모든 사원의 이름과 성을 붙여 출력한다. 열 별칭은 name로 지정한다.SELECT employee_id, first_name, hire_date, salary FROM employees;
SELECT first_name || ' ' || last_name as name FROM employees;
3. 50번 부서 사원의 모든 정보를 출력한다.
4. 50번 부서 사원의 이름, 부서번호, 직무아이디를 출력한다.SELECT * FROM employees WHERE department_id = 50;
SELECT first_name, department_id, job_id FROM employees WHERE department_id = 50;
5. 모든 사원의 이름, 급여 그리고 300달러 인상된 급여를 출력한다.
6. 급여가 10000보다 큰 사원의 이름과 급여를 출력한다.SELECT first_name, salary, salary + 300 FROM employees;
SELECT first_name, salary FROM employees WHERE salary > 10000;
7. 보너스를 받은 사원의 이름과 직무, 보너스율을 출력한다.
8. 2003년도 입사한 사원의 이름과 입사일 그리고 급여를 출력한다. (BETWEEN 연산자 사용)SELECT first_name, job_id, commission_pct FROM employees WHERE commission_pct is not null;
9. 2003년도 입사한 사원의 이름과 입사일 그리고 급여를 출력한다. (LIKE 연산자 사용)SELECT first_name, hire_date, salary FROM employees WHERE hire_date BETWEEN '03/01/01' AND '03/12/31';
10. 모든 사원의 이름과 급여를 급여가 많은 사원부터 적은 사원순서로 출력한다.SELECT first_name, hire_date, salary FROM employees WHERE hire_date LIKE '03%';
11. 위 질의를 60번 부서의 사원에 대해서만 질의한다. (컬럼: department_id)SELECT first_name, salary FROM employees ORDER BY salary DESC;
12. 직무아이디가 IT_PROG 이거나, SA_MAN인 사원의 이름과 직무아이디를 출력한다.SELECT first_name, salary FROM employees WHERE department_id = 60 ORDER BY salary DESC;
SELECT first_name, job_id FROM employees WHERE job_id = 'IT_PROG' OR job_id = 'SA_MAN';
13. Steven King 사원의 정보를 "Steven King 사원의 급여는 24000달러 입니다" 형식으로 출력한다.SELECT first_name, job_id FROM employees WHERE job_id IN ('IT_PROG', 'SA_MAN');
SELECT first_name || ' ' || last_name || '사원의 급여는 ' || salary || '달러 입니다' AS info FROM employees WHERE first_name = 'Steven' AND last_name = 'King';
14. 매니저(MAN) 직무에 해당하는 사원의 이름과 직무아이디를 출력한다. (컬럼: job_id)
15. 매니저(MAN) 직무에 해당하는 사원의 이름과 직무아이디를 직무아이디 순서대로 출력한다.SELECT first_name, job_id FROM employees WHERE job_id LIKE '%MAN';
SELECT first_name, job_id FROM employees WHERE job_id LIKE '%MAN' ORDER BY job_id ASC;
함수
- SQL의 함수를 사용해서 데이터 값을 간편하게 조작하여 사용할 수 있다.
- 데이터 계산 수행
- 개별적인 데이터 항목 수정
- 행의 그룹에 대해 결과 조작
- 출력을 위한 날짜와 숫자 형식 설정
- 열의 데이터타입 변환
- 단일행 함수
- 단일행 함수에는 여러 유형들이 있으며, 단일 행에서만 적용이 가능하고 행별로 하나의 결과를 리턴한다.
- 문자, 숫자, 날짜, 변환
- 단일행 함수에는 여러 유형들이 있으며, 단일 행에서만 적용이 가능하고 행별로 하나의 결과를 리턴한다.
- 다중행 함수
- 복수의 행을 조작해서 행의 그룹당 하나의 결과를 리턴한다.
- 데이터 값을 조작한다.
- 인수(argument)를 받고 하나의 결과를 리턴한다.
- 리턴될 각각의 행에 적용된다.
- 행별로 하나의 결과를 리턴한다.
- 데이터타입을 수정할 수 있다.
- 중첩(nested)될 수 있다.
- 단일행 함수 종류에는 문자 함수, 숫자 함수, 날짜 함수, 변환 함수 등이 있다.
- 문자 함수는 문자 입력을 받고 문자와 숫자 값 모두를 리턴할 수 있다.
- 숫자 함수는 숫자 입력을 받고 숫자 값을 리턴한다.
- 날짜 함수는 날짜 데이터타입의 값에 대해 수행한다.
- 숫자를 리턴하는 MONTHS_BETWEEN 함수를 제외한 모든 날짜 함수는 날짜 데이터타입의 값을 리턴한다.
- 변환 함수는 어떤 데이터타입의 값을 다른 데이터타입의 값으로 변환한다.
- 그 외 함수에는 NVL, NVL2, LNNVL, NULLIF, COALESCE, DECODE 등이 있다.
- lower(소문자), initcap(앞글자만 대문자), upper(대문자)
SELECT 'abcDEF', lower('abcDEF'), upper('abcDEF')
FROM dual;
- dual이라는 테이블은 sys가 소유하는 오라클의 표준 테이블로 오직 한 행에 한 컬럼만 담고 있는 dummy 테이블이다.
- 일시적인 산술 연산이나 날짜 연산 등을 위로 주로 사용되며, 모든 사용자가 접근할 수 있다.
SELECT last_name, lower(last_name), initcap(last_name) , upper(last_name)
FROM employees;
SELECT last_name
FROM employees
WHERE lower(last_name) = 'kim';
- length(길이), instr(문자 찾기)
SELECT 'abcdef' AS ex, LENGTH('abcdef'), INSTR('abcdef', 'a')
FROM dual;
SELECT first_name, LENGTH(first_name), INSTR(first_name, 'a')
FROM employees;
- substr(문자열 자르기), concat(문자 연결)
SELECT 'abcdef' AS ex, SUBSTR('abcdef', 1, 2), CONCAT('abc', 'def')
FROM dual;
SELECT first_name AS ex, SUBSTR(first_name, 1, 3), CONCAT(first_name, last_name)
FROM employees;
- LPAD, RPAD (좌, 우측 지정문자열로 채우기)
SELECT LPAD('abc', 10, '*')
FROM dual;
SELECT RPAD('abc', 10, '*')
FROM dual;
- LTRIM(), RTRIM(), TRIM() 공백 제거
- LTRIM, RTRIM은 좌/우측에 지정한 문자 제거
SELECT LTRIM('javascript_java', 'java')
FROM dual;
SELECT RTRIM('javascript_java', 'java')
FROM dual;
SELECT TRIM(' java ')
FROM dual;
- REPLACE(문자열 치환)
SELECT REPLACE('my dream is a president','president','doctor')
FROM dual;
SELECT REPLACE(CONCAT('hello', 'world'), ' ', '')
FROM dual;
SQL Quiz02
문제 1.
EMPLOYEES 테이블에서 이름, 입사일자 컬럼으로 변경해서 이름순으로 오름차순 출력한다.
조건1) 이름 컬럼은 first_name, last_name을 붙여서 출력한다.
조건2) 입사일자 컬럼은 xx/xx/xx로 저장되어 있는데, xxxxxx 형태로 변경해서 출력한다.
SELECT CONCAT(first_name, last_name) AS 이름, REPLACE(hire_date,'/','') AS 입사일자 FROM employees ORDER BY 이름 ASC;
문제 2.
EMPLOYEES 테이블에서 phone_number 컬럼은 ###.###.#### 형태로 저장되어 있는데, 처음 세 자리는 숫자 대신 서울 지역번호 (02)를 붙여 전화번호를 출력한다.
문제 3.SELECT CONCAT('(02)', SUBSTR(phone_number, 4, LENGTH(phone_number))) AS phone_number FROM employees;
EMPLOYEES 테이블에서 job_id가 IT_PROG인 사원의 이름(first_name)과 급여(salary)를 출력한다.
조건1) 비교하기 위한 값은 소문자로 입력해야 한다. (힌트: lower 사용)
조건2) 이름은 앞 3문자까지 출력하고 나머지는 *로 출력한다. 이 열의 열 별칭은 name이다. (힌트: rpad와 substr 또는 substr 그리고 length 사용)
조건3) 급여는 전체 10자리로 출력하되 나머지 자리는 *로 출력한다. 이 열의 열 별칭은 salary이다. (힌트: lpad사용)
SELECT RPAD(SUBSTR(first_name, 1, 3), LENGTH(first_name), '*') AS name, LPAD(salary, 10, '*') as salary FROM employees WHERE lower(job_id) = 'it_prog';
숫자 함수
- ROUND(반올림)
-- 소수점 1번째 위치 반올림, 0번째 위치 반올림, 좌측 1번째 위치 반올림
SELECT ROUND(3.1415, 1), ROUND(45.923, 0), ROUND(45.923, -1)
FROM dual;
- TRUNC(절사)
- 정해진 소수점 자리수까지 잘라낸다.
SELECT TRUNC(3.1415, 1), TRUNC(45.923, 0), TRUNC(45.923, -1)
FROM dual;
- ABS(절대값)
SELECT ABS(-34)
FROM dual;
- CEIL(올림), FLOOR(내림)
SELECT CEIL(3.14), FLOOR(3.14)
FROM dual;
- MOD(나머지)
SELECT 10 / 2, MOD(10,2)
FROM dual;
날짜 함수
- 오라클은 세기, 년, 월, 일, 시간, 분, 초의 내부 숫자형식으로 날짜를 저장한다.
- 디폴트 날짜 형식은 'DD-MON-YY'이며, 시스템에 따라 'YY/MM/DD'가 될 수 있다.
- SYSDATE는 현재의 날짜를 변환하는 함수이다.
- SYSTIMESTAMP는 현재의 날짜와 시간을 반환하는 함수이다.
- DUAL은 SYSDATE를 보기 위해 사용된 dummy 테이블이다.
SELECT sysdate
FROM dual;
SELECT systimestamp
FROM dual;
- 날짜 연산
SELECT first_name, sysdate - hire_date
FROM employees;
SELECT first_name, hire_date, (sysdate - hire_date) / 7 AS week
FROM employees; -- 주수
SELECT first_name, hire_date, (sysdate - hire_date) / 365 AS week
FROM employees; -- 년수
-- 날짜 반올림
SELECT ROUND(sysdate)
FROM dual;
SELECT ROUND(sysdate, 'year')
FROM dual; -- 년 기준으로 반올림
SELECT ROUND(sysdate, 'month')
FROM dual; -- 월 기준으로 반올림
SELECT ROUND(sysdate, 'day')
FROM dual; -- 일 기준으로 반올림 (해당 주 일요일 날짜)
-- 날짜 절사
SELECT TRUNC(sysdate)
FROM dual;
SELECT TRUNC(sysdate, 'year')
FROM dual;
SELECT TRUNC(sysdate, 'month')
FROM dual;
SELECT TRUNC(sysdate, 'day')
FROM dual; -- 일 기준으로 절사 (해당 주 일요일 날짜 기준)
암시적 형변환
- 값 할당(assignment) 시, 오라클은 자동으로 표와 같이 변환할 수 있다.
From | To | 비고 |
VARCHAR2 또는 CHAR | NUMBER | 표현식 계산의 경우 |
VARCHAR2 또는 CHAR | DATE | 표현식 계산의 경우 |
NUMBER | VARCHAR2 | |
DATE | VARCHAR2 |
- VARCHAR2 또는 CHAR를 NUMBER로 변환
- VARCHAR2 또는 CHAR를 DATE로 변환
- NUMBER를 VARCHAR2로 변환
- DATE를 VARCHAR2로 변환
변환 함수 | 설명 |
TO_CHAR(number[, 'fmt']) | 숫자를 포맷 모델 fmt를 사용하여 VARCHAR2 문자 스트링으로 변환한다. |
TO_CHAR(date[, 'fmt']) | 날짜를 포맷 모델 fmt를 사용하여 VARCHAR2 문자 스트링으로 변환한다. |
TO_NUMBER(char[, 'fmt']) | 숫자를 포함하는 문자 스트링을 숫자로 변환한다. |
TO_DATE(char[, 'fmt']) | 날짜를 나타내는 문자 스트링을 명시된 fmt에 따라서 날짜 값으로 변환한다. (fmt가 생략되면 DD-MON-YY 형식이다.) |
- 날짜를 문자로 TO_CHAR(값, 형식)
SELECT TO_CHAR(sysdate)
FROM dual;
SELECT TO_CHAR(sysdate, 'YYYY-MM-DD HH:MI:SS')
FROM dual;
SELECT TO_CHAR(sysdate, 'YY-MM-DD PM HH:MI:SS')
FROM dual;
-- 사용하고 싶은 문자를 ""를 묶어서 전달한다.
SELECT first_name, TO_CHAR(hire_date, 'YYYY"년" MM"월" DD"일"')
FROM employees;
- 숫자를 문자로 TO_CHAR(값, 형식)
SELECT TO_CHAR(20000, '99999')
FROM dual;
-- 주어진 자릿수에 숫자를 모두 표기하지 못할 경우 #으로 표시된다.
SELECT TO_CHAR(20000, '9999')
FROM dual;
SELECT TO_CHAR(20000.21, '99999.9')
FROM dual;
SELECT TO_CHAR(20000.21, '99999.99')
FROM dual; -- 소수점 자리수 지정 가능.
SELECT TO_CHAR(20000, '99,999')
FROM dual;
SELECT TO_CHAR(salary, '$999,999') AS salary
FROM employees;
SELECT TO_CHAR(salary, 'L999,999') AS salary
FROM employees;
- 문자를 숫자로 TO_NUMBER(값, 형식
SELECT '2000' + 2000 FROM dual; -- 자동 형변환
SELECT TO_NUMBER('2000') + 2000 FROM dual; -- 명시적 형 변환
SELECT '$3,300' + 2000 FROM dual; -- 에러
SELECT TO_NUMBER('$3,300', '$9,999')+ 2000 FROM dual;
- 문자를 날짜로 변환하는 함수 TO_DATE(값, 형식)
SELECT TO_DATE('2021-11-23') FROM dual; -- 기본 패턴
SELECT sysdate - TO_DATE('2021-11-23') FROM dual; -- 날짜로 변환해야 연산이 가능
SELECT TO_DATE('2020/12/25', 'YY/MM/DD') FROM dual;
SELECT TO_DATE('2021-03-31 12:23:50', 'YYYY-MM-DD HH:MI:SS') FROM dual;
-- 주어진 문자열은 모두 변환해야 한다.
SELECT TO_DATE('2021-03-31 12:23:50', 'YYYY-MM-DD') FROM dual; -- 에러
SQL Quiz
- xxxx년 xx월 xx일 문자열 형식으로 변환한다.
- 조회 컬럼명은 dateInfo로 한다.
SELECT TO_CHAR( TO_DATE('20050102', 'YYYY/MM/DD'), 'YYYY"년" MM"월" DD"일"' ) AS dateInfo FROM dual;
'Database > Oracle' 카테고리의 다른 글
[국비] SQL 내용정리 Day05 (0) | 2021.12.11 |
---|---|
[국비] SQL 내용정리 Day04 (0) | 2021.12.09 |
[국비] SQL 내용정리 Day03 (0) | 2021.12.08 |
[국비] SQL 내용정리 Day02 (0) | 2021.12.07 |
Oracle Data Base 11g / SQL Developer 설치 (0) | 2021.11.11 |
댓글