- SQL REVIEW
- 집합(SET)
- 우리는 두 개의 테이블을 집합연산 할 수 있다.
- UNION 은 중복 확인을 위해 전체 점색 후 정렬하여 검사를 수행 하기 때문에 성능에 좋지 않다.
- 정규화(Nomalization)와 역정규화(Denormalization)
1. 정규화의 개념
- 관계형 DBMS 설계에서 중복을 최소화하게 데이터를 구조화 하는 프로세스
- 자료 중복으로 인해 이상 현상(Anomaly)이 발생 할 수 있어 이를 최소화 하는 것이 정규화의 목적
Anomaly | Description |
삭제 이상 | 튜플 삭제시 원치 않는 데이터도 삭제되어 연쇄삭제 문제가 발생하는 것. |
삽입 이상 | 튜플 삽입시 특정 속성에 해당 값이 없어 NULL값을 입력해야 하는 현상. |
갱신 이상 | 튜플 수정시 데이터 일부만 수정(갱신)되어 데이터 불일치(Inconsistency) 문제 발생 |
2. 정규화의 목적
- 데이터 구조의 안저엉 및 무결성 유지
- 어떤 릴레이션이라도 DB내에서 표현 가능
- 효과적인 검색 알고리즘 생성
- 데이터 중복을 배제하여, 이상발생 방지 및 자료 저장 공간의 최소화 가능
- 데이터 삽입 시, 릴레이션 재구성할 필요성을 줄인다.
- 데이터 모형의 단순화 가능
- 속성의 배열 상태 검증 가능
- 개체와 속성의 누락 여부 확인 가능
- 자료 검색과 추출의 효율성 추구
3. 정규화의 과정
- 정규화 과정은 총 여섯 과정이 있다.
- 그 중 실제로는 3NF까지만 사용 한다.
- 3NF가 되면 정규화가 된 것으로 간주 한다.
- 각 정규형은 이전 단계들을 기본적으로 모두 만족 해야만 한다.
- 정규화는 이상 현상을 최소화 하기 위해 테이블을 쪼개는 작업 이다.
- 하지만 지나친 정규화는 쿼리를 복잡하게 만들고 성능을 저하 시킨다.
- 그래서 테이블을 합하는 작업을 역 정규화라고 한다.
1) 1NF(NORMAL FORM)
- 모든 항목에 도메인이 원자값 이어야 한다.
- 중복되는 데이터가 없어야 한다.
2) 2NF(NORMAL FORM)
- 개체의 속성이 한 식별자에 종속 되어야 한다.
- 이를 부분 함수적 종속 제거라고 한다.
3) 3NF(NORMAL FORM)
- 연도로 인해 우승국이 결정되고, 우승국으로 인해 감도깅 결정되는 경우
- 이 경우 이행 함수 종속성 이라고 한다.
- 우승국이 변경되면 불필요 하게 감독까지 변경 되어야 한다.
- 우승국만 변경하면 갱신 이상 발생.
- 동물원 관리 DB 생성 실습해보기
-- 동물원 관리 DB
-- 1. 동물분류(AC)
CREATE TABLE Animal_Categories (
AC_CODE NCHAR(1), --PK
AC_NAME NVARCHAR2(10) NOT NULL, --UQ
CONSTRAINT PK_AC_CODE PRIMARY KEY(AC_CODE),
CONSTRAINT UQ_AC_NAME UNIQUE(AC_NAME)
);
-- 제약조건 설정 연습(위에서 이미 설정했으니 안해도 된다.)
ALTER TABLE Animal_Categories
ADD CONSTRAINT PK_AC_CODE PRIMARY KEY(AC_CODE);
ALTER TABLE Animal_Categories
MODIFY AC_NAME NOT NULL;
ALTER TABLE Animal_Categories
ADD CONSTRAINT UQ_AC_NAME UNIQUE(AC_NAME);
-- 동의어(SYNONYM) 생성
-- 동의어는 DML에서만 사용 가능하다. DDL에서는 사용 불가능
-- DDL : ALTER, CREATE, DROP
CREATE SYNONYM AC FOR Animal_Categories;
SELECT * FROM AC; -- 확인
-- 2. 동물(ANIMAL) : AN
CREATE TABLE ANIMAL(
AN_CODE NCHAR(2),
AN_NAME NVARCHAR2(10) NOT NULL,
AN_QTY NUMBER(2,0) DEFAULT 1 NOT NULL,
AN_ACCODE NCHAR(1) NOT NULL,
-- 테이블단에 기본키, 왜래키 설정
CONSTRAINT PK_AN_CODE PRIMARY KEY(AN_CODE),
CONSTRAINT UQ_AN_NAME UNIQUE(AN_NAME),
CONSTRAINT FK_AN_ACCODE FOREIGN KEY(AN_ACCODE)
REFERENCES Animal_Categories(AC_CODE)
-- 부모컬럼은 PK이거나 UQ해야한다.
);
-- 동의어(SYNONYM) 생성
CREATE SYNONYM AN FOR ANIMAL;
SELECT * FROM AN;
-- DEFAULT(위에서 했으니 MODIFY 인것을 참고만 하자)
ALTER TABLE ANIMAL
MODIFY AN_QTY DEFAULT 1;
-- DUMMY DATA INSERT TO AC
INSERT INTO AC VALUES(1,'포유류');
INSERT INTO AC VALUES(2,'조류');
INSERT INTO AC VALUES(3,'양서류');
INSERT INTO AC VALUES(4,'어류');
SELECT * FROM AC;
-- DUMMY DATA INSERT TO AN
INSERT INTO AN VALUES(1,'원숭이',10,1);
INSERT INTO AN VALUES(2,'꼬끼리',2,1);
INSERT INTO AN VALUES(3,'타조',3,2);
INSERT INTO AN VALUES(4,'사자',5,1);
INSERT INTO AN VALUES(5,'하이에나',4,1);
INSERT INTO AN VALUES(6,'도마뱀',3,3);
INSERT INTO AN VALUES(7,'공작새',5,2);
INSERT INTO AN VALUES(8,'양',23,1);
INSERT INTO AN VALUES(9,'펭귄',10,2);
SELECT * FROM AN;
COMMIT;
-- 3. 먹이분류(FeedCategories) : FC
CREATE TABLE Feed_Categories(
FC_CODE NCHAR(1),
FC_NAME NVARCHAR2(10) NOT NULL,
CONSTRAINT PK_FC_CODE PRIMARY KEY(FC_CODE),
CONSTRAINT UQ_FC_NAME UNIQUE(FC_NAME)
);
- 동의어 생성
CREATE SYNONYM FC FOR Feed_Categories;
-- DUMMY DATE INSERT INTO Feed_Categories
INSERT INTO FC VALUES(1,'과일');
INSERT INTO FC VALUES(2,'육류');
INSERT INTO FC VALUES(3,'여류');
INSERT INTO FC VALUES(4,'음료');
INSERT INTO FC VALUES(5,'풀');
SELECT * FROM FC;
-- 4. 먹이 공급 회사(벤더) (FeedVender) : FV
CREATE TABLE Feed_Vender(
FV_CODE NCHAR(1),
FV_NAME NVARCHAR2(10) NOT NULL,
CONSTRAINT PK_FV_CODE PRIMARY KEY(FV_CODE)
);
-- 동의어 생성
CREATE SYNONYM FV FOR Feed_Vender;
-- DUMMY DATE INSERT INTO Feed_Vender
INSERT INTO FV VALUES(1,'양마나');
INSERT INTO FV VALUES(2,'마시써');
INSERT INTO FV VALUES(3,'신선해');
SELECT * FROM FV;
-- 5. 동물먹이(AnimalFeed) : AF
CREATE TABLE Animal_Feed(
AF_CODE NCHAR(1),
AF_NAME NVARCHAR2(10) NOT NULL,
AF_COST NUMBER(6,0) DEFAULT 1000 NOT NULL,
AF_QTY NUMBER(4,0) DEFAULT 1000 NOT NULL,
AF_UNIT NVARCHAR2(5) DEFAULT 'kg' NOT NULL,
AF_FVCODE NCHAR(1) NOT NULL,
AF_FCCODE NCHAR(1) NOT NULL,
CONSTRAINT PK_AF_CODE PRIMARY KEY(AF_CODE),
CONSTRAINT FK_AF_FVCODE FOREIGN KEY(AF_FVCODE)
REFERENCES Feed_Vender(FV_CODE),
CONSTRAINT FK_AD_FCCODE FOREIGN KEY(AF_FCCODE)
REFERENCES Feed_Categories(FC_CODE)
);
-- 동의어 생성
CREATE SYNONYM AF FOR AnimalFeed;
-- 테이블명 변경
ALTER TABLE AnimalFeed RENAME TO Animal_Feed;
SELECT * FROM AF;
-- 이전 시노님 삭제 및 시노님 생성
DROP SYNONYM AF;
CREATE SYNONYM AF FOR Animal_Feed;
-- DUMMY DATE INSERT INTO Animal_Feed
INSERT INTO AF VALUES(1,'바나나',2000,DEFAULT,DEFAULT,1,1);
INSERT INTO AF VALUES(2,'생닭',3000,DEFAULT,'마리',2,2);
INSERT INTO AF VALUES(3,'건초',10000,DEFAULT,DEFAULT,3,5);
INSERT INTO AF VALUES(4,'물고기',3000,DEFAULT,'마리',2,3);
INSERT INTO AF VALUES(5,'우유',2500,DEFAULT,'L',1,4);
INSERT INTO AF VALUES(6,'사과',5000,DEFAULT,DEFAULT,3,1);
-- 중간 데이터 INSERT 확인
SELECT * FROM AC;
SELECT * FROM FC;
SELECT * FROM AN;
SELECT * FROM FV;
SELECT * FROM AF;
- 물리적 저장
COMMIT;
-- 6. 사육사(ZooKeeper) : ZK
CREATE TABLE Zoo_Keeper(
ZK_CODE NCHAR(2),
ZK_NAME NVARCHAR2(10) NOT NULL,
ZK_HIREDATE DATE DEFAULT SYSDATE NOT NULL,
CONSTRAINT PK_ZK_CODE PRIMARY KEY(ZK_CODE)
);
-- 동의어 생성
CREATE SYNONYM ZK FOR Zoo_Keeper;
-- DUMMY DATA INSERT INTO Zoo_Keeper
INSERT INTO ZK VALUES(1,'이주성',DEFAULT);
INSERT INTO ZK VALUES(2,'이순신',DEFAULT);
INSERT INTO ZK VALUES(3,'이성계','2020/01/01');
INSERT INTO ZK VALUES(4,'이방원','2019/12/31');
SELECT * FROM ZK;
-- 7. 담당동물(AnimalManager) : AM
CREATE TABLE Animal_Manager(
AM_ZKCODE NCHAR(2),
AM_ANCODE NCHAR(2),
CONSTRAINT PK_AM_ZK_ANCODE PRIMARY KEY(AM_ZKCODE, AM_ANCODE),
CONSTRAINT FK_AM_ZKCODE FOREIGN KEY(AM_ZKCODE)
REFERENCES Zoo_Keeper(ZK_CODE),
CONSTRAINT FK_AM_ANCODE FOREIGN KEY(AM_ANCODE)
REFERENCES ANIMAL(AN_CODE)
);
-- 동의어 생성
CREATE SYNONYM AM FOR Animal_Manager;
-- DUMMY DATA INSERT INTO Animal_Manager
INSERT INTO AM VALUES(1,4);
INSERT INTO AM VALUES(1,5);
INSERT INTO AM VALUES(2,3);
INSERT INTO AM VALUES(2,7);
INSERT INTO AM VALUES(2,9);
INSERT INTO AM VALUES(3,1);
INSERT INTO AM VALUES(3,2);
INSERT INTO AM VALUES(3,8);
INSERT INTO AM VALUES(4,2);
INSERT INTO AM VALUES(4,6);
SELECT * FROM AM;
-- 확인
SELECT * FROM AC;
SELECT * FROM FC;
SELECT * FROM AN;
SELECT * FROM FV;
SELECT * FROM AF;
SELECT * FROM ZK;
SELECT * FROM AM;
COMMIT;
-- ZOODB 관련 문제
-- Q1. 포유류 동물리스트 및 마리수 검색
-- 포유류, 사자, 마리
SELECT AC.AC_NAME, AN.AN_NAME, AN.AN_QTY
FROM AC JOIN AN
ON AC.AC_CODE = AN.AN_ACCODE
WHERE AC.AC_CODE='1';
-- Q2. 포유류 총 마리수
-- 포유류, XXX마리
SELECT AC.AC_NAME, SUM(AN.AN_QTY)
FROM AC JOIN AN
ON AC.AC_CODE = AN.AN_ACCODE
GROUP BY AC.AC_NAME
HAVING AC.AC_NAME='포유류';
-- Q3. 조류중(GROUP BY)에서 최대 개체수를 가진 동물이름 및 마리수 검색
1. 서브쿼리
선생님)
SELECT AN.AN_NAME, AN.AN_QTY
FROM AN
WHERE AN.AN_ACCODE =2
AND AN.AN_QTY=(
SELECT MAX(AN.AN_QTY)
FROM AN
WHERE AN.AN_ACCODE=2);
나)
SELECT AN_NAME, AN_QTY FROM
(SELECT AN_NAME, AN_QTY
FROM AN
WHERE AN_ACCODE = 2
ORDER BY AN_QTY DESC)
WHERE ROWNUM=1;
2. 조인문
SELECT AC.AC_NAME,AN.AN_NAME,AN.AN_QTY
FROM AC JOIN AN
ON AC.AC_CODE=AN.AN_ACCODE
WHERE ac.ac_name='조류'
AND AN.AN_QTY>=(SELECT MAX(AN.AN_QTY)
FROM AC JOIN AN
ON AC.AC_CODE=AN.AN_ACCODE
WHERE AC.AC_NAME='조류');
-- Q4. 동물 카테코리별로 최대 개체수를 가진 동물이름 및 마리수 검색
-- 다시해보기
CREATE OR REPLACE VIEW AC_MAX_VIEW
AS
SELECT AN_ACCODE,MAX(AN_QTY) MAX_QTY
FROM AN
GROUP BY AN_ACCODE;
-- 방법1
SELECT AC.AC_NAME, AN.AN_NAME, AN.AN_QTY
FROM AN JOIN AC_MAX_VIEW M
ON AN.AN_ACCODE=M.AN_ACCODE AND AN.AN_QTY=M.MAX_QTY
JOIN AC
ON AN.AN_ACCODE=AC.AC_CODE;
-- 방법2 : JOIN & 서브쿼리
SELECT ac.ac_name, an.an_NAME, AN.AN_QTY
FROM AN JOIN AC
ON an.an_accode=ac.ac_code
WHERE (an.an_accode, an.an_QTY) IN(SELECT * FROM AC_MAX_VIEW);
-- Q5. 먹이중에서 과일들의 단가 및 개수 리스트 검색
-- 나)
SELECT AF.AF_NAME, AF.AF_COST, AF.AF_QTY
FROM FC JOIN AF
ON fc.fc_code=AF.AF_FCCODE
WHERE FC.FC_NAME='과일';
-- 선생님)
SELECT AF.AF_NAME, AF.AF_COST, AF.AF_QTY
FROM AF
WHERE AF.AF_FCCODE IN(SELECT fc.fc_CODE FROM FC
WHERE fc.fc_NAME = '과일');
-- Q6. 과일중에서 단가가 가장 싼 과일 이름, 단가 검색
SELECT AF.AF_NAME, AF.AF_COST
FROM AF
WHERE AF.AF_FCCODE = 1 -- 조건1
AND AF.AF_COST=( -- 조건2
SELECT MIN(AF.AF_COST)
FROM AF
WHERE AF.AF_FCCODE=1);
SELECT AF.AF_NAME, AF.AF_COST
FROM AF
WHERE AF.AF_FCCODE = 1 -- 조건1
AND AF.AF_COST=( -- 조건2
SELECT MIN(AF.AF_COST)
FROM AF
WHERE AF.AF_FCCODE=(SELECT FC_CODE FROM FC WHERE FC_NAME='과일'));
-- Q7. '양마나' 벤더가 공급하는 먹이이름 검색
SELECT AF_NAME
FROM AF
WHERE AF_FVCODE=1;
SELECT FV.FV_NAME, AF.AF_NAME
FROM FV JOIN AF
ON FV.FV_CODE = AF.AF_FVCODE
WHERE AF.AF_FVCODE=1;
SELECT AF_NAME
FROM AF
WHERE AF_FVCODE = (SELECT FV_CODE FROM FV
WHERE FV_NAME='양마나');
-- Q8. 마시써 벤더가 공급하는 먹이 카테고리(육류,어류) 리스트 검색
SELECT FV.FV_NAME,FC.FC_NAME, AF.AF_NAME
FROM AF JOIN FV
ON FV.FV_CODE = AF.AF_FVCODE
JOIN FC
ON FC.FC_CODE = AF.AF_FCCODE
WHERE FV_CODE=2;
-- Q9. 이주성 사육사가 담당하는 동물이름 검색
SELECT ZK.ZK_NAME, AN.AN_NAME
FROM AM JOIN ZK
ON AM.AM_ZKCODE = ZK.ZK_CODE
JOIN AN
ON AM.AM_ANCODE = AN.AN_CODE
WHERE ZK.ZK_CODE = 1;
'ICIA 수업일지' 카테고리의 다른 글
2021.07.12 수업일지 (0) | 2021.07.17 |
---|---|
2021.07.09 수업일지 (0) | 2021.07.12 |
2021.07.07 수업일지 (0) | 2021.07.10 |
2021.07.06 수업일지 (0) | 2021.07.10 |
2021.07.05 수업일지 (0) | 2021.07.10 |