web/django

데이터베이스 핵심 개념들

민사민서 2024. 5. 13. 23:18

 

기본키

- 테이블에서 행의 식별자로 이용되는 열을 (key)또는 기본 키(primary key)라고 합니다

- 테이블에서 한 행을 고유하게 식별할 수 있는 정보를 의미

 

외래키

- onetomany, manytomany 등의 관계에서 다른 테이블을 가리키기 위해 가지고 있는 다른 테이블의 Primary key

- foreign key는 하나의 테이블에서 고유하게 존재하는 개념이 아니라, 두 테이블의 관계에서 비롯된 개념

 

OneToOne

테이블의 한 행과 다른 테이블의 한 행이 1:1로 대응되는 관계입니다.

일반적으로는 아래와 같은 상황에 사용될 수 있습니다.

  • 한 테이블에 데이터를 몰아넣는 게 효율적이지 않을 때
  • 보안을 위해 일부 데이터를 따로 관리하고자 할 때

onetoone 관계에서 두 테이블을 연결하기 위해서는 반드시 primary key를 이용해야 함

 

=> 장고에서는 models.OneToOneField() 사용

OneToMany

두 테이블의 각 record가 1:1로 대응되지 않고 1:N(일대다) 관계로 대응되는 경우

예시로 학생 테이블과 학과 테이블 (학생 N명이 학과 1개에 대응)

  • 학생 테이블에 학과 테이블의 primary key를 추가함으로써 두 테이블의 연관 관계 관리할 수 있음
  • 반대로 학과 테이블에 학생 테이블의 primary key(학번) 추가하는 경우는 불가능함. 같은 과 학생 2명 이상 존재하는 경우 표시 불가하기 때문

=> 장고에서는 models.ForeignKey() 사용, N에 대응되는 테이블에 사용한다

ManyToMany

학생 테이블과 강의 테이블이 존재하고, 우리가 수강신청을 하는 상황을 생각해봅시다. 한 명의 학생이 여러 강의를 수강신청할 수 있고, 하나의 강의를 수강하는 학생이 여럿일 수 있죠.

  • 이 경우 각 테이블의 primary key만 모아서 새로운 테이블을 구성하는 것

엄밀히 얘기하면 다대다 관계는 그 자체로 나타내지는 것이 아니라 일대다 관계 두 개로 쪼개져서 나타납니다. 학생과 수강신청 테이블은 일대다 관계를 맺으며 여기서 학생의 primary key학번이 수강신청의 foreign key로 들어가구요. 또한 과목과 수강신청 역시 일대다 관계를 맺으며 수강신청의 primary key과목번호가 수강신청의 foreign key로 들어가게 됩니다. 결과적으로 학생 (1 : n) 수강신청 (n : 1) 강의과 같은 형태를 띄는 것이죠.

 

ERD(Entity Relationship Diagram)

https://www.erdcloud.com/

 

ERDCloud

Draw ERD with your team members. All states are shared in real time. And it's FREE. Database modeling tool.

www.erdcloud.com

데이터베이스의 테이블들 간 관계를 나타내는 다이어그램 그리는 사이트

 

ORM (Object Relational Mapping)

객체와 관계형 데이터베이스의 데이터를 자동으로 매핑(연결)해주는 것

접근객체 지향 프로그래밍은 클래스를 사용하고, 관계형 데이터베이스는 테이블을 사용

객체 모델과 관계형 모델 간에 불일치가 존재하는데 ORM을 통해 객체와 테이블 간의 관계를 바탕으로 불일치를 해결

클래스와 함수를 사용해서 데이터베이스를 생성하고 접근하는 기술

 

ORM은 SQL의 쿼리로 번역된다!! 실제로 테스트해보면

(.venv) C:\Users\Runner\Desktop\컴공자료\멋쟁이사자처럼\seminar\week08\django-seminar>python manage.py shell
Python 3.11.3 (tags/v3.11.3:f3909b8, Apr  4 2023, 23:49:59) [MSC v.1934 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from django.contrib.auth.models import User
>>> str(User.objects.all().query)
'SELECT "auth_user"."id", "auth_user"."password", "auth_user"."last_login", "auth_user"."is_superuser", "auth_user"."username", "auth_user"."first_name", "auth_user"."last_name", "auth_user"."email", "auth_user"."is_staff", "auth_user"."is_active", "auth_user"."date_joined" FROM "auth_user"'

 

Post model에서 post1 레코드를 하나 생성하면 Post object를 리턴

>>> from post.models import Post
>>> post1 = Post.objects.create(title="title1", content="content")
>>> post1
<Post: title1>

 

Post.objects.all()해서 DB의 모든 Post 객체를 보여달라하면 ORM은 QuerySet을 반환.

django 안에 존재하는 타입(파이썬 타입이 x). DB와 python의 중간다리 역할이므로 list( ) 를 씌우면 list type으로 바뀐다~

>>> Post.objects.all()
<QuerySet [<Post: title1>]>
>>> type(list(Post.objects.all()))
<class 'list'>