스칼라 서브쿼리, 인라인 뷰 서브쿼리, 중첩 서브쿼리가 있는데
사용 위치에 따라서 부르는 이름이 다른 것뿐이다. 

1. 스칼라 서브쿼리는 SELECT 절에 위치한다.
SELECT 절은 원래 출력할 컬럼을 선택하기 위해서 존재한다. 

정확히 하나의 값. 단일 컬럼의 단일행을 반환한다. 만약 서브쿼리가 여러 행을 반환하면, 어떤 값을 선택할지 불확실해지기 때문에 오류가 발생함. 


2. 인라인뷰 서브쿼리는 FROM 절에 위치한다. 

FROM절은 원래 어떤 테이블에서 데이터를 가져온다는 것을 명시하기 위해서 존재한다. 
그래서 FROM 절에 오는 서브쿼리는 반드시 하나의 테이블로 리턴되어야 한다. VIEW와 사용하는 방식은 동일하다. VIEW는 데이터베이스에 정의되는 반면 서브쿼리는 서브쿼리가 실행될 때 정의된다는 차이점이 있다. 

 


3. 중첩(NESTED) 서브쿼리는 WHERE이나 HAVING 절에 위치한다. 

WHERE절은 원래 결과 집합을 특정한 조건을 가진 행으로 한정하기 위해서 사용한다.
HAVING은 GROUP BY의 WHERE...
그래서 WHRER 절 뒤에 오는 중첩 서브쿼리는 메인 쿼리 컬럼을 참조한다. 다중컬럼 또는 다중행을 반환할 수 있다. 

JOIN은 두 개 이상의 테이블을 특정 컬럼을 기준으로 결합하고자 할 때 사용한다. 

대표적으로 INNER JOIN과 OUTER JOIN이 있다. 

 

 

INNER JOIN

 

#내부 조인은 일반 조인 혹은 동등 조인이라고 하기도 한다.
칼럼명을 기준으로, 결합 조건을 만족하는 데이터만 출력한다. 

 

 

 


1. WHERE 절에서 JOIN하기

SELECT ~
FROM TABLE1, TABLE2
WHERE  TABLE1.속성 = TABLE2.속성

(세 개의 다른 테이블)
SELECT TABLE1.속성1, TABEL2. 속성2
FROM TABLE1, TABLE2, TABLE3
WHERE TABLE1.속성1 = TABLE2.속성1
AND TABLE2.속성2 = TABLE3. 속성2




 


2. FROM 절에서 JOIN하기

 

SELCT ~
FROM TABLE1 JOIN TABLE2
ON TABLE1.속성 = TABLE2.속성; 


(세 개의 다른 테이블)
FROM TABLE1
JOIN TABLE2
ON TABLE1.속성 = TABLE2.속성
JOIN TABLE3
ON TABLE2.속성 = TABLE3.속성;



이렇게 명시적으로 조인을 하겠다고 표시하고,

ON 뒤로 어떤 속성을 결합 조건으로 할건지 정하면 된다. 


JOIN이라고만 쓰면 내부 조인으로 자연스럽게 인식한다. 



 

OUTER JOIN

 

#외부 조인은 한쪽 테이블에 데이터가 없어도, 기준이 되는 테이블에 데이터가 있다면 모두 출력한다. 

 


LEFT JOIN, RIGHT JOIN, FULL OUTETR JOIN이 있다. 

MySQL에서는 full outer join을 구현하는 명령어가 없기 때문에 LEFT JOIN과 RIGHT JOIN의 합집합(UNION)을 이용해서 구하면 된다. 

LEFT JOIN은 왼쪽 테이블의 데이터를 모두 출력하고, 오른쪽 테이블의 데이터는 있으면 출력, 없으면 NULL로 표시한다. 

RIGHT JOIN은 반대로 오른쪽 테이블의 데이터를 모두 출력하고, 왼쪽은 있으면 출력, 없으면 NULL로 표시한다.



<FULL OUTER JOIN 예시>

SELECT residents.name AS resident_name, animals.name AS animal_name

FROM residents LEFT JOIN animals
ON residents.id = animals.owner_id

UNION

SELECT residents.name AS resident_name, animals.name AS animal_name
FROM residents RIGHT JOIN animals
on residents.pet_id = animals.id;



결과는 이렇게 나온다. 

 

1. 거주자 ID랑 동물 주인 ID가 같을 때 거주자 ID만 있으면 거주자 이름이랑 동물 이름을 출력한 것. 만약 residents.id가 2인데, animals.owner_id가 2인 행이 없다면? 동물 이름 대신 NULL이 반환된다.여기서 기준은 residents 테이블이기 때문이다. 

 

2. 거주자가 소유한 동물 ID랑 동물 ID가 같을 때 거주자의 이름과 동물의 이름을 출력한 것. 여기서 기준은 animals 테이블이므로, residents 테이블에서 residents.pet_id 중 일치하는 게 없으면 거주자 이름은  거주자 이름은 NULL로 나온다. 

 

3. 두 개를 UNION으로 합친다. 

UNION을 사용하기 위해서는 모든 컬럼의 개수와 순서, 데이터 형식이 동일해야 한다. 
UNION은 중복값을 제거하고, UNION ALL은 중복값을 그대로 보여준다. 중복 처리하는 과정이 없으므로 UNION ALL이 속도는 더 빠르다. 

 

결국 거주자 이름과 동물 이름이 모두 있는 경우, 거주자 이름만 있는 경우, 동물 이름만 있는 경우를 모두 출력할 수 있게 된다. 

코딩테스트 연습 - 조건에 맞는 도서 리스트 출력하기 | Programmers School

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

SELECT BOOK_ID, DATE_FORMAT(PUBLISHED_DATE, '%y-%m-%d') AS PUBLISHED_DATE
FROM BOOK
WHERE CATEGORY = '인문' AND YEAR(PUBLISHED_DATE) = 2021
ORDER BY PUBLISHED_DATE;

 

 

 

 

 

 

 

 

코딩테스트 연습 - 재구매가 일어난 상품과 회원 리스트 구하기 | Programmers School

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

SELECT USER_ID, PRODUCT_ID
FROM ONLINE_SALE
GROUP BY 1, 2
HAVING COUNT(PRODUCT_ID) > 1 
ORDER BY USER_ID ASC, PRODUCT_ID DESC;

#HAVING 절은 WHERE 절과 비슷하지만 
그룹 전체에만(즉, 그룹을 나타내는 결과 집합의 행에) 적용되는 반면
WHERE 절은 개별 행에 적용됩니다.

 

#

데이터 모델링 :
현실세계(사물/사건에 관한 양상)를 추상화, 단순화, 명확화하기 위해 일정한 표기법에 의해 표현하는 기법.
(현실세계를 추상화, 단순화, 명확화한 것이=데이터 모델)

-추상화: 현실세계를 일정한 형식에 맞추어 표현
-단순화: 현실세계를 약속된 규약에 의해 제한된 표기법이나 언어로 표현
-명확화: 누구나 이해하기 쉽도록 애매모호함이 없고 정확하게 기술

 

 

 


#
모델링의 세 가지 관점

-데이터 관점: 업무가 어떤 데이터와 관련이 있는지?
-프로세스 관점: 업무가 무엇을 해야하는지?
-상관관점: 일의 방법에 따라서 데이터가 어떻게 영향을 받는지?

 

 

 

 

 

#
데이터 모델이 제공하는 기능:


-시스템을 현재 또는 원하는 모습으로 가시화
-시스템의 구조와 행동을 명세화
-시스템을 구축하는 구조화된 틀 제공
-시스템을 구축하는 과정에서 결정한 것을 문서화
-다양한 영역에 집중하기 위해 다른 영역의 세부 사항은 숨기는 다양한 관점 제공
-특정 목표에 따라 구체화된 상세 수준의 표현 방법을 제공

 

 

 

 

 

#
데이터 모델링의 중요성


-파급효과 : 기초적인 작업으로 파급 효과가 크기 때문에 시스템 구축 작업 중에서 다른 어떤 설계 과정보다 데이터 설계가 중요.


-복잡한 정보 요구사항의 간결한 표현: 말과 글보다 훨씬 간결

 

-데이터 품질: 데이터 중복(고객 정보 등의 정보), 비유연성, 비일관성이 발생할 수 있다.

 

 

 

 

 

#
모델링의 3단계


현실세계에서 개념적 구조로 만드는 
개념데이터 모델링 :

추상화 수준 높음(상세하지 않음), 업무 중심적이고 가장 중요하고 포괄적인 수준의 모델링 진행. 

(전사적 데이터 모델링, EA수립 시 많이 사용)

 


개념적 구조에서 논리적 구조로 만드는 
논리데이터 모델링: 

구축하고자 하는 업무의 키, 속성, 관계등을 정확하게 표현한다. 한번 구축해놓으면 재사용성이 높음

 


논리에서 물리로
물리데이터 모델링: 

실제로 데이터베이스에 이식할 수 있도록 성능, 저장 등 물리적 성격 고려하여 설계한다.

 

 

 

 

 

#
프로젝트 생명 주기는 정보전략계획- 분석- 설계- 개발- 테스트- 전환/이행 단계이다.


이 중 개념적 데이터 모델링: 정보전략계획, 분석단계에서 일어나고
논리적 데이터 모델링: 분석단계, 물리적 데이터 모델링: 설계 단계에서 일어난다.

 

 

 

 

 

#
데이터 독립의 필요성


오늘 날씨와 내일 날씨가 다르니까, 이 세상의 데이터는 끊임없이 증가한다. --> 데이터 중복성 증가--> 데이터 복잡도 증가


사용자 요구사항도 끊임없이 발생함. - 유지보수 비용 증가 - 요구사항 대응 저하


데이터 독립성 개념은 사용자가 보는 화면과 데이터베이스 간의 독립성을 유지하기 위해서 출현하였다. 

 

 

 

 

 

 

#
데이터 독립성을 유지하기 위한 3단계 구조


외부 단계와 개념적 단계의 독립성은 논리적 데이터 독립성으로 유지된다. 
내부적단계와 개념적 단계/외부 단계의 독립성은 물리적 데이터 독립성으로 유지된다.

외부 스키마(사용자 관점)
개념 스키마(연결고리 , 통합관점)
내부 스키마(물리적 관점)

논리적 독립성: 개념스키마가 변경되어도 내부스키마는 그대로임.
물리적 독립성: 내부스키마가 변경되어도 개념, 외부 스키마는 그대로임. 

 

 

 

 

 

#

데이터베이스 3단계 구조에서의 사상(매핑)


외부적, 개념적 사상: 논리적 사상. 외부적 뷰와 개념적 뷰의 상호 호환성을 정의함.
개념적, 내부적 사상: 물리적 사상. 개념적 뷰와 저장된 데이터베이스의 상호 관련성을 정의함.

*** 중간에 매핑 과정이 있기 때문에 만약 내부 데이터베이스가 바뀌어도 사상만 바꾸면 개념 스키마가 그대로 남아있는 것. 반대로 사용자가 접근하는 형식에 따라 다른 타입의 필드를 가질 수 있는데, 사상만 바꾸면 개념 스키마 즉 개념적 뷰의 필드 타입에는 변화가 없음.

 

 

 

 

#

데이터 모델링 용어


* 어떤 것? 
복수/집합 개념은 엔터티, 개별/단수 개념은 인스턴스
ex)고객 = 엔터티, 홍길동= 인스턴스

*어떤 것 간의 연관
고객과 고객이 주문한 상품이 페어링 되는 관계..

* 어떤 것의 성격
속성- ex)주문금액, 주문 일시, 배송지.. 
속성값- ex) 2만 9천원, 3월 1일...

 

 

 

 

#
데이터 모델링 작업 순서


1. 엔터티 그리기
2. 엔터티 배치
3. 엔터티 간 관계 설정
4. 관계명 기술
5. 관계의 참여도 기술
6. 관계의 필수 여부 기술

IE 표기법과 BARKER 표기법이 있음.

 

 

 

 

#

데이터 모델링의 이해관계자
프로젝트 개발자(제일 중요), 현업업무 전문가, 전문 모델러, DBA
관계자 모두가 적어도 모델을 정확하게 해석할 수 있을 정도의 데이터 모델링 지식을 갖춰야 함.

 

 

 

 

#
좋은 데이터 모델?


완전성

중복 배제

업무 규칙-데이터 모델 분석만으로도 비즈니스 로직이 이해가 되어야 함

데이터 재사용

의사소통

통합성-동일한 데이터는 유일하게 정의해서 다른 영역에서 참조해야 함(한 정보는 한 곳에서만 관리함)

 

 

 

 

https://youtu.be/aiMSluMNzI8


USE market_db;
SELECT * FROM member;
SHOW INDEX FROM member; 
SHOW TABLE STATUS LIKE 'member';
(인덱스 하나도 없는 상태 확인.)
 
<인덱스 생성>
 
1) 인덱스 생성

CREATE INDEX idx_member_addr
ON member (addr);
    
SHOW INDEX FROM member;

SHOW TABLE STATUS LIKE 'member';
인덱스 만들고 다시 실행했는데 인덱스 정보가 안 보임.

---->
ANALYZE TABLE member;  
이걸 해야 인덱스가 적용된다.

SHOW TABLE STATUS LIKE 'member';
인덱스 생긴 거 확인 가능.
 
 
 
2) 유니크  인덱스 생성
 
CREATE UNIQUE INDEX idx_member_mem_name
ON member (mem_name);
유니크 인덱스는 중복값이 없어야 한다.

SHOW INDEX FROM member;

INSERT INTO member VALUES('MOO', '마마무', 2, '태국', '001', '12341234', 155, '2020.10.10');
ANALYZE TABLE member;
멤버 이름이 같은 데이터_ 유니크 인덱스가 있어서 삽입 불가능.
 
 
 
3) 인덱스 사용해서 검색

SELECT mem_id, mem_name, addr
FROM member
        WHERE mem_name = '에이핑크';
인덱스 사용해서 검색했음. 인덱스는 where절, 열 이름이 나와야 쓸 수 있음.


4) 인덱스를 사용하려면, WHERE 절에 뒤에 쓰는 열에 아무 가공을 하면 안된다.  
 
CREATE INDEX idx_member_mem_number
ON member (mem_number);
ANALYZE TABLE member;

SELECT mem_name, mem_number
FROM member
    WHERE mem_number >= 7;
    인덱스가 있든 없든 결과는 동일하게 나옴.
    execution plan 에 들어가서 결과 나오는 과정을 보면 
    index range scan --> query block #1 이런 식의 과정이 확인 됨.
   
SELECT mem_name, mem_number
FROM member
    WHERE mem_number >= 1;
    결과값으로 테이블의 모든 행이 출력됨.
    이 경우 execution plan 보면 인덱스 사용하지 않음. 
    어떤 방식이 더 효과적인지 자동으로 계산을 하는 것. 
   
SELECT mem_name, mem_number
FROM member
        WHERE mem_number*2 >= 14;
멤버 수가 7 이상인 거랑 똑같은 결과가 나오지만, 인덱스를 사용하지 않음.
 
SELECT mem_name, mem_number
FROM member
        WHERE mem_number >= 14/2;
        
이렇게 2를 뒤로 넘기면 인덱스 사용한다. 
--> WHERE절에 가공을 하지 않으면 더 효율적으로 정보를 불러올 수 있다.
 
 

5) 인덱스 제거

DROP INDEX idx_member_mem_name ON member;
DROP INDEX idx_member_addr ON member;
DROP INDEX idx_member_mem_number ON member;

 ALTER TABLE member
DROP PRIMARY KEY;
이건 PK, FK로 지금 buy 테이블과 연결되어 있기 때문에 안 지워짐.

SELECT table_name, constraint_name
 FROM information_schema.referential_constraints
     WHERE constraint_schema = 'market_db' ;
market_db의 외래키 이름 확인하는 구문. 

ALTER TABLE buy
DROP FOREIGN KEY buy_ibfk_1;
    
ALTER TABLE member
DROP PRIMARY KEY;
    
FK먼저 지우고 다시 mem 테이블의 PK 지우기 --> 잘 지워짐.

[SQL 기초 강의] 16강.인덱스의 내부 작동 원리와 구조, 인덱스에서 데이터 검색하기 - YouTube

 

<클러스터형 인덱스 구성하기 연습>


USE market_db;
CREATE TABLE cluster
( mem_id CHAR(8),
  mem_name VARCHAR(10)
);
INSERT INTO cluster VALUES('TWC', '트와이스');
INSERT INTO cluster VALUES('BLK', '블랙핑크');
INSERT INTO cluster VALUES('WMN', '여자친구');
INSERT INTO cluster VALUES('OMY', '오마이걸');
INSERT INTO cluster VALUES('GRL', '소녀시대');
INSERT INTO cluster VALUES('ITZ', '잇지');
INSERT INTO cluster VALUES('RED', '레드벨벳');
INSERT INTO cluster VALUES('APN', '에이핑크');
INSERT INTO cluster VALUES('SPC', '우주소녀');
INSERT INTO cluster VALUES('MMU', '마마무');

SELECT * FROM cluster;
입력한 순서대로, 인덱스 없는 상태.

ALTER TABLE cluster
ADD CONSTRAINT
    PRIMARY KEY (mem_id);
    
SELECT *FROM cluster;
아이디를 기본키로 지정---> 클러스터형 인덱스가 만들어져, 아이디의 알파벳 순으로 정렬 됨. 



<보조 인덱스 구성하기 연습>

CREATE TABLE second
(  mem_id CHAR(8),
   mem_name VARCHAR(10)
   );

INSERT INTO second VALUES('TWC', '트와이스');
INSERT INTO second VALUES('BLK', '블랙핑크');
INSERT INTO second VALUES('WMN', '여자친구');
INSERT INTO second VALUES('OMY', '오마이걸');
INSERT INTO second VALUES('GRL', '소녀시대');
INSERT INTO second VALUES('ITZ', '잇지');
INSERT INTO second VALUES('RED', '레드벨벳');
INSERT INTO second VALUES('APN', '에이핑크');
INSERT INTO second VALUES('SPC', '우주소녀');
INSERT INTO second VALUES('MMU', '마마무');
SELECT * FROM second;

인덱스 없이 테이블만 만든 것. 입력 순서대로 정렬

ALTER TABLE second
ADD CONSTRAINT
        UNIQUE (mem_id);
        
SELECT * FROM second;

유니크 키 지정으로 보조 인덱스를 생성해도, 데이터의 순서 바뀌지 않음. 
내부적으로 인덱스(찾아보기 기능)이 생겼고, 페이지 번호와 위치가 저장된 것이다. 

 

 

정보 검색 시, 클러스터형 인덱스가 더 효율적이라고 함.

[SQL 기초 강의] 15강. 인덱스의 개념과 장단점, 클러스터형 인덱스와 보조 인덱스 - YouTube

 

USE market_db ;

CREATE TABLE table1 (
    col1 INT PRIMARY KEY,
    col2 INT,
    col3 INT 
);
SHOW INDEX FROM table1; 


키네임에 프라이머리 있으면 자동으로 클러스터형 인덱스가 만들어진다. 그 열에 입력된 값 기준으로 사전식 정렬.



CREATE TABLE table2 (
    col1 INT PRIMARY KEY,
    col2 INT UNIQUE,
    col3 INT UNIQUE
);
SHOW INDEX FROM table2;


여기서 프라이머리 키인 컬럼 1은 클러스터 인덱스, 컬럼2, 컬럼3는 보조 인덱스로 봄. 

둘 다 자동으로 생성되는 인덱스이다.
유니크 조건이 여러 열에 붙을 수 있듯, 보조 키도 여러개 만들 수 있음.
프라이머리키와 클러스터형 인덱스는 테이블 당 하나만 만들 수 있다. 

 

 


USE market_db;
DROP TABLE IF EXISTS buy, member;
CREATE TABLE member
( mem_id CHAR(8),
  mem_name VARCHAR(10),
  mem_number INT,
  addr CHAR(2)
);

INSERT INTO member VALUES('TWC', '트와이스', 9, '서울');
INSERT INTO member VALUES('BLK', '블랙핑크', 4, '경남');
INSERT INTO member VALUES('WMN', '여자친구', 6, '경기');
INSERT INTO member VALUES('OMY', '오마이걸', 7, '서울');

SELECT * FROM member;


새로운 멤버 테이블 만들었다. 인덱스 없이(PK 지정 안 하고) 무작위로 입력하면, 입력한 순서 그대로 테이블에서 보인다.

 

 


ALTER TABLE member
ADD CONSTRAINT
    PRIMARY KEY(mem_id);
SELECT *FROM member;


프라이머리 키 다시 지정한 후 불러오면 멤버 아이디가 알파벳 순으로 정렬되는 걸 확인할 수 있다.
클러스터형 인덱스가 자동으로 생성된 것.

 

 

ALTER TABLE member DROP PRIMARY KEY ; 
다시 기본 키를 제거하고
ALTER TABLE member
ADD CONSTRAINT
    PRIMARY KEY(mem_name);
새로운 기본 키를 멤버 이름 열에 부여하면
SELECT * FROM member;
멤버 이름 순으로 다시 정렬되는 걸 확인할 수 있다.

 


INSERT INTO member VALUES ('GRL', '소녀시대', 8, '서울');
이 상태에서 소녀시대 행을 새로 입력하면
SELECT * FROM member;
블핑, 여자친구 사이에 삽입이 되었다. ㄱㄴㄷ 순으로.

 

 


보조인덱스UNIQUE, 고유 키로 지정하면 생성된다. 
클러스터 형 인덱스를 사전 만들기에 비유한다면, 
보조 인덱스는 용어 사전이 아니라 줄글로 된 책의 인덱스를 만드는 것과 비슷하다. 
책의 내용을 다시 정렬하는 것이 아니라, 맨 뒤에 <찾아보기>를 추가하는 방식이다. 

USE market_db;
DROP TABLE IF EXISTS member;
CREATE TABLE member
( mem_id CHAR(8),
  mem_name VARCHAR(10),
  mem_number INT,
  addr CHAR(2)
);

INSERT INTO member VALUES('TWC', '트와이스', 9, '서울');
INSERT INTO member VALUES('BLK', '블랙핑크', 4, '경남');
INSERT INTO member VALUES('WMN', '여자친구', 6, '경기');
INSERT INTO member VALUES('OMY', '오마이걸', 7, '서울');

SELECT * FROM member;

 

인덱스 없이 새로운 테이블 만들기.

 

 


ALTER TABLE member
ADD CONSTRAINT
    UNIQUE (mem_id);
SELECT * FROM member;


유니크 키를 추가한 뒤 멤버 테이블을 조회해도, 내용, 순서가 바뀌지 않았다. 보조 인덱스가 생성된 것이다.

 

 


ALTER TABLE member
ADD CONSTRAINT
    UNIQUE (mem_name);
SELECT * FROM member;


두번째 유니크 키를 지정함. 책 뒤에 찾아보기는 여러 버전으로 만들 수 있으므로.

 

 

 


INSERT INTO member VALUES ('GRL', '소녀시대' ,8, '서울');
SELECT * FROM member;


새로운 행은 그냥 맨 뒤에 추가된다.

[SQL 기초 강의] 14강. 가상의 테이블: 뷰(생성, 수정, 삭제) - YouTube

 

USE market_db;
SELECT mem_id, mem_name, addr FROM member;

이렇게 써서 테이블을 조회하나

USE market_db;
CREATE VIEW v_member
AS
SELECT mem_id, mem_name, addr FROM member;
    
SELECT * FROM v_member;

이렇게 써서 뷰를 조회하나 똑같은 결과로 보인다. 

 

 


SELECT mem_name, addr FROM v_member
WHERE addr IN ('서울', '경기');
    
SELECT B. mem_id, M.mem_name, B.prod_name, M.addr

CREATE VIEW v_memberbuy
AS
SELECT B.mem_id, M.mem_name, B.prod_name, M.addr, 
CONCAT(M.phone1, M.phone2) '연락처'
FROM buy B
INNER JOIN member M
            ON B.mem_id = M.mem_id; 

 

복잡한 조건의 쿼리문을 뷰로 생성해 놓으면 다음에 불러오기 편하다. 
            

 


SELECT * FROM v_memberbuy WHERE mem_name = '블랙핑크';

 

블랙핑크에 관한 특정 정보(아이디, 이름, 구매물품, 주소, 전화번호)를 보고 싶을 때, 보안에도 유용. 

v_memberbuy라는 뷰에서 불러오면 블핑의 멤버 수, 평균 키 같은 정보는 나오지 않는다. 

 

 

 


 USE market_db;
 CREATE VIEW v_viewtest1
 AS
SELECT B.mem_id 'Member ID', M.mem_name AS 'Member Name',
B.prod_name "product Name",
            CONCAT(M.phone1, M.phone2) AS "Office Phone"
FROM buy B
INNER JOIN member M
            ON B.mem_id = M.mem_id;

 

불러올 열에 새로운 이름을 붙여 주었다.

SELECT DISTINCT `Member ID`, `Member name`FROM v_viewtest1;

 

새로운 열 이름으로 정보를 불러오고 싶을 때는 기존의 작은 따옴표가 아니라 키보드 1 버튼 왼쪽에 있는 거?로 이름을 묶어주면 된다. 

 

 

ALTER VIEW v_viewtest1
AS
SELECT B.mem_id '회원 아이디', M.mem_name AS '회원 이름',
B.prod_name "제품 이름",
CONCAT(M.phone1, M.phone2) AS "연락처"
FROM buy B
INNER JOIN member M
                ON B.mem_id = M.mem_id;
                
SELECT DISTINCT `회원 아이디`, `회원 이름` FROM v_viewtest1; 

 

ALTER VIEW 기능을 이용하여 이렇게 새로운 이름을 한글로 지정할 수도 있다.
                

 

DROP VIEW v_viewtest1;

USE market_db;
CREATE OR REPLACE VIEW v_viewtest2
AS
SELECT mem_id, mem_name, addr FROM member;
    
DESCRIBE v_viewtest2;
DESCRIBE member;

 

describe ~ 누르면 각 열의 이름, 타입, 널 값, 키 값 등 확인 가능함.

 

 


SHOW CREATE VIEW v_viewtest2;

 

뷰를 만들었던 쿼리문 확인하고 싶을 때 이렇게 입력하면 된다. 

 

 


UPDATE v_member SET addr = '부산' WHERE mem_id= 'BLK' ;
SELECT * FROM v_member;

 

뷰를 통한 데이터 수정이 잘 되었다.

 

 


INSERT INTO v_member(mem_id, mem_name, addr) VALUES('BTS', '방탄소년단', '경기') ; 


이 경우에는 수정이 되지 않았는데, 기존 테이블에서 not null값인 멤버 수 등의 정보가 빠졌기 때문에 얘네만 입력할 수는 없는 것. 뷰를 통해서 데이터는 입력이 될 수도 있고 안 될 수도 있고, 이렇게 인서트 하는 것은 바람직하지 않음. 

 

 

 


CREATE VIEW v_height167
AS
SELECT * FROM member WHERE height >= 167 ;

 

SELECT * FROM v_height167;

 

키가  167 이상인 멤버만 보여주는 뷰

 


ALTER VIEW v_height167
AS
SELECT * FROM member WHERE height >= 167
WITH CHECK OPTION ; 

 

위드 체크 옵션 구문으로 뷰의 조건에 맞는 값만 입력이 되도록 하는 게 좋다. 

 

 

INSERT INTO v_height167 VALUES('TOB', '텔레토비', '4', '영국', NULL, NULL, 140, '1999-05-05');


텔레토비는 167이 안돼서 자동으로 입력이 불가하다고 나옴. 만약 체크 옵션을 쓰지 않으면 입력은 되지만 실제로 보이지는 않는다.

 



DROP TABLE IF EXISTS buy, member;

뷰와 관계없이 테이블은 지울 수 있다.


SELECT * FROM v_height167;

그러면 뷰는 더이상 조회가 안 됨. 


CHECK TABLE v_height167;
왜 뷰가 조회 안 되는지 확인 가능

CREATE TABLE buy
( num            INT AUTO_INCREMENT NOT NULL PRIMARY KEY,
  mem_id      CHAR(8) NOT NULL,
  prod_name CHAR(6) NOT NULL,
  FOREIGN KEY(mem_id) REFERENCES member(mem_id)
);

 

member 테이블의 PRIMARY KEY인 mem_id를 참조하여 buy 테이블의 FOREIGN KEY mem_id 지정.

 

DROP TABLE IF EXISTS buy;
CREATE TABLE buy
( num  INT AUTO_INCREMENT NOT NULL PRIMARY KEY,
  mem_id CHAR(8) NOT NULL,
  prod_name CHAR(6) NOT NULL
);
ALTER TABLE buy
  ADD CONSTRAINT
  FOREIGN KEY(mem_id) REFERENCES member(mem_id);

 

이미 만들어진 buy테이블에 외래키 지정하기.

 

<1>

 

DROP TABLE IF EXISTS gate_table;
CREATE TABLE gate_table (id INT AUTO_INCREMENT PRIMARY KEY, entry_time DATETIME);

id 는 프라이머리 키고, 자동으로 올라가는 오토 인크리먼트 숫자, entry_time은 날짜+시간으로 표현


SET @curDATE = CURRENT_TIMESTAMP();


PREPARE myQuery FROM 'INSERT INTO gate_table VALUES(NULL, ?)';

동적 SQL문 준비.. gate_table에 값을 넣을 건데 id 칸은 오토 인크리먼트니까 비워두고, entry_time 칸에는 EXECUTE할 때마다 입력값이 입력되게 할 것임.

EXECUTE myQuery USING @curDATE;
DEALLOCATE PREPARE myQuery;

SELECT * FROM gate_table;

 

EXECUTE한 날짜, 시간이 실시간으로 입력됨.

 

+ Recent posts