나는 처음 Python Django ORM으로 처음 데이터 관련한 문법을 익혔고 SQL문을 공부하면서 Djnago ORM과 비교하면서 공부한걸 블로깅 하려 한다.
먼저 테이블 구조를 보자면 교집합인 부분은 users.id 와 carts.user_id
users
carts
users 와 carts에 들어있는 데이터
JOIN은 집합과 관계가 있고 집합마다 JOIN방식이 달라진다.
집합에는 곱집합, 교집합, 합집합 등 여러가지가 있는데
INNER JOIN = 교집합, OUTER JOIN = 합집합만 다뤄보겠다.
교집합 = INNER JOIN의 형태로 데이터를 불러오게 되고 INNER JOIN으로 불러오는 조건은 2개의 테이블이 참조관계에 있고 Foreign KEY의 옵션이 NULL = False 일경우 이다.
(Django 의 경우 on_delete=models.CASCADE 도 포함)
SQL문 과 값
SELECT * FROM carts INNERT JOIN users ON (users.id=carts.user_id) SELECT * FROM carts,users WHERE (users.id=carts.user_id) 둘다 같은 방식이며 2번째 줄 방식이 더 구식이라 한다.
합집합 = OUTER JOIN 의 형태로 데이터를 불러오게 되고
2개의 테이블이 참조관계에 있지만 Foreign KEY 의 옵션이
NULL = False 여야 함
LEFT OUTER JOIN의 경우 부모와 자식테이블을 JOIN 할때 부모를 참조하는 자식 값이 없을때도 모든 부모테이블의 값을 불러오게 하기위함이다.
SQL문 과 값
SELECT * FROM carts LEFT OUTER JOIN users ON (users.id=carts.user_id)
INNER JOIN과 OUTER JOIN으로 가져온 값을 보면 이상한 점이 하나 있다.
그건 id 컬럼값이 중복 된다는 건데 두테이블 다 id라는 컬럼이 있고 JOIN을 했을때 두테이블을 합치는 과정에서 생긴건데 그럴경우
SELECT users.id AS user_pk FROM carts INNERT JOIN users ON (users.id=carts.user_id) SELECT users.id AS user_pk FROM carts LEFT OUTER JOIN users ON (users.id=carts.user_id)
이런식으로 users.id 의 별명을 바꿔주면 된다.
select_related의 경우 정참조의 상황에서 쓰이고 SQL내부에서 JOIN해서 가져오며 쿼리는 1번 날림
1 : 1 정참조 관계 INNER JOIN
1 : 1 정참조 관계 LEFT OUTER JOIN
M : 1 정참조 관계 INNER JOIN
NULL = TRUE 의경우 LEFT OUTER JOIN
NULL = FALSE or on_delete=models.CASCADE 의경우 INNER JOIN
Cart.object.all().select_related("user")
1 : M 역참조 관계 Python LEVEL 에서 INNER JOIN
M : M 역참조 관계 Python LEVEL 에서 INNER JOIN
M : 1 정참조 관계 Python LEVEL 에서 INNER JOIN
prefetch_related의 경우 1+N번의 쿼리를 날리고 가져온다음
Python LEVEL에서 JOIN을 하며 INNER JOIN으로 참조,역참조 값을 가져온다.
User.objects.all().prefetch_related("cart_set")
참조
역참조
둘다 구식의 INNER JOIN 형태로 가져온다.
TIL 후기
Python Django 로 개발하면서 django-extensions로 쿼리문 날아가는걸 봤을때 join을 보고 궁금했고 공부하고 싶었는데 뭔가 간지러운 부분을 긁은것 같아 속시원했다.
좋은 글 잘 읽고갑니다!
LEFT OUTER JOIN에 대한 설명에서 오탈자가 있는것 같아요~ Null = True 일때 outer join이요!