SQL, 데이터 분석!

SQL, 데이터 분석!

바로 보고 실습하는 SQL, 입문부터 활용까지!

09 일대일(1:1), 다대다(N:M) 관계

# 일대일, 다대다 관계 ## 개념 --- #### 다양한 관계들 DB속 데이터는 PK와 FK의 연결을 통해 다양한 관계를 가진다. 이들은 크게 1:N, 1:1, M:N으로 나뉜다. ![홍팍-SQL-데이터의-관계](http://drive.google.com/uc?export=view&id=1TJeI3O3n_NTFpueh83donv4BOTRA1vv0) #### 일대일(1:1) 관계 예를 들어, 국가와 수도는 일대일(One-to-One) 관계다. 한 국가에 여러 수도가 존재하지 않고, 거꾸로 한 수도 또한 여러 나라에 속하지 않는다. 이를 DB화 한다면, FK를 어느 테이블에 두어야 할까? 일반적으로 포함된 쪽 또는 덜 사용되는 쪽에 놓는게 좋다. ![홍팍-sql-일대일-관계-one-to-one](http://drive.google.com/uc?export=view&id=1TMOuRcnBPxHM4bQGy0yui8rmmU4chDZk) #### 다대다(M:N) 관계 다대다(Many-to-Many) 관계는 양방향에서 모두 다수로 연결될 수 있다. 쇼핑몰을 예로 들자. 고객은 다양한 상품을 주문할 수 있고, 상품 또한 다양한 고객으로부터 주문될 수 있다. 이를 DB화 하려면, 두 관계를 잇는 중간 테이블이 필요하다. 중간 테이블에는 양측을 잇기 위한 두 FK가 필요하다. ![홍팍-sql-다대다-관계-many-to-many](http://drive.google.com/uc?export=view&id=1TPLh0JNBLUAT286__igDC47ps8q8i45i) #### 인스타그램의 예 인스타그램 사용자(users)와 각 사용자별 설정(settings) 값은 1:1 관계이다. 각 설정값이 계정에 속하는 개념이므로, FK는 설정 테이블에 두는게 좋다. ![홍팍-sql-인스타그램-일대일-관계-예](http://drive.google.com/uc?export=view&id=1TSoM4WwhUpjalRtDq3mbja6n1vZiLkMr) 인스타그램 사용자(users)와 사진(photos)은 "사진 게시"를 통해 일대다 관계이지만, "좋아요 등록"을 통해서는 다대다 관계가 된다. 한 사용자는 다양한 사진에 좋아요를 누를 수 있고, 거꾸로 하나의 사진은 다양한 유저들로부터 좋아요를 받을 수 있다. ![홍팍-sql-다대다-관계-many-to-many-인스타그램-예](http://drive.google.com/uc?export=view&id=1TVAoBHAjrI2_7FFWm8cBGuqeShIdsXY_) ## 실습 --- #### 테이블 생성 ``` -- settings 테이블 생성 CREATE TABLE settings ( id SERIAL PRIMARY KEY, -- PK private BOOLEAN, -- true/false adding_photos VARCHAR(15), -- AUTO, MANUAL user_id INTEGER UNIQUE REFERENCES users(id) -- FK: 개인설정 유저(1:1 연결) ); -- likes 테이블 생성(사용자와 사진을 다대다 연결) CREATE TABLE likes ( id SERIAL PRIMARY KEY, -- PK user_id INTEGER REFERENCES users(id), -- FK: 좋아요를 누른 사람(1:N 연결) photo_id INTEGER REFERENCES photos(id) -- FK: 좋아요된 사진(1:N 연결) ); ``` #### 레코드 생성 ``` -- settings 레코드 생성 INSERT INTO settings(private, adding_photos, user_id) VALUES (FALSE, 'MANUAL', 1), -- 유저#1 (FALSE, 'AUTO', 2), -- 유저#2 (TRUE, 'AUTO', 3) -- 유저#3 ; -- likes 레코드 생성 INSERT INTO likes(user_id, photo_id) VALUES -- 사진#1에 달린 좋아요 (1, 1), -- 유저#1 (2, 1), -- 유저#2 -- 사진#2에 달린 좋아요 (1, 2), -- 유저#1 (2, 2), -- 유저#2 (3, 2), -- 유저#3 -- 사진#3에 달린 좋아요 (1, 3), -- 유저#1 (3, 3) -- 유저#3 ; ``` ## 훈련 --- #### 다음 테이블을 참고하여 질문에 답하시오. ![홍팍-SQL-입문-데이터의-관계-일대일-다대다-좋아요-문제](http://drive.google.com/uc?export=view&id=1Smd2Gpq39OHBQPLQ5Xa8GhDtezFMAHE9) 1. 좋아요가 가장 많이 달린 사진은 무엇? 2. 좋아요가 가장 적은 사진은 무엇? 3. 좋아요를 가장 많이 누른 사용자는, 공개 계정으로 설정돼있는가? 4. 다음 쿼리의 수행을 막으려면, FK인 user_id 컬럼에 어떤 조건을 주어야 하는가? ``` INSERT INTO settings(private, adding_photos, user_id) VALUES (FALSE, 'AUTO', 3), (FALSE, 'AUTO', 3), (FALSE, 'AUTO', 3) ; ``` 5. 다음 쿼리가 의미하는 바는 무엇? ``` INSERT INTO likes(user_id, photo_id) VALUES (1, 1), (1, 1), (1, 1), (1, 1) ; ```