SQL과 ORM

최동혁·2022년 12월 6일
0

Django

목록 보기
2/11

SQL과 ORM

SQL이란?

SQL

Structured Query Language (구조적 질의 언어)의 줄임말로, 관계형 데이터베이스 시스템(RDBMS)에서 자료를 관리 및 처리하기 위해 설계된 언어이다.

SQL 문법의 종류

SQL 문법은 크게 3가지의 종류로 나누어진다.

  • DDL (Data Definition Language, 데이터 정의 언어) 각 릴레이션을 정의하기 위해 사용하는 언어 (CREATE, ALTER, DROP)
  • DML(Data Manipulation Language, 데이터 조작 언어) 데이터를 추가/수정/삭제하기 위한, 즉 데이터 관리를 위한 언어 (SELECT, INSERT, UPDATE …)
  • DCL(Data Control Langugae, 데이터 제어 언어) 사용자 관리 및 사용자 별로 릴레이션 또는 데이터를 관리하고 접근하는 권한을 다루기 위한 언어 (GRANT, REVOKE…)

SQL 언어적 특성

  1. SQL은 대소문자를 가리지 않는다.

    (단, 서버 환경이나 DBMS 종류에 따라 데이터베이스 또는 필드명에 대해 대소문자를 구분하기도 한다.)

  2. SQL 명령은 반드시 세미콜론(;)으로 끝나야 한다.

  3. 고유의 값따옴표(’’)로 감싸준다.

    ex) SELECT * FROM EMP WHERE NAME = ‘James’;

  4. SQL에서 객체를 나타낼 때는 백틱(``)으로 감싸준다.

    ex) SELECT COST, TYPE FROM INVOICE;

  5. 주석은 일종의 도움말로, 주석 처리된 문장은 프로그램에서 동작하지 않는다. 한 줄 주석은 문장 앞에 —를 붙여서 사용한다.

    ex) — SELECT * FROM EMP; 이 쿼리는 실행되지 않습니다.

  6. 여러 줄 주석은 /* */ 로 감싸준다.

    ex)

    /*

    SELECT FROM EMP WHERE EMPID=(SELECT FROM EMP WHERE NAME=’홍길동’)

    */

NoSQL

NoSQL 데이터베이스란?

특정 데이터 모델에 대해 특정 목적에 맞추어 구축되는 데이터베이스로서 현대적인 애플리케이션 구축을 위한 유연한 스키마를 갖추고 있다.

NoSQL 데이터베이스는 개발의 용이성, 기능성 및 확장성을 널리 인정받고 있다.

NoSQL(비관계형) 데이터베이스의 작동 방식

NoSQL 데이터베이스에서는 데이터의 액세스 및 관리를 위해 다양한 데이터 모델을 사용한다.

이러한 데이터베이스 유형은 큰 테이터 볼륨, 짧은 지연 시간과 유연한 데이터 모델이 필요한 애플리케이션에 최적화되었으며, 이는 다른 데이터베이스의 데이터 일관성 제약 일부를 완화함으로써 이루어진다.

간단한 서적 데이터베이스를 위한 스키마 모델 구축 사례를 고려해 보자:

  • 관계형 데이터베이스에서, 서적 레코드는 흔히 숨겨져(또는 "정규화되어") 별도의 테이블에 보관되고, 관계는 기본 및 외래 키 제약 조건으로 정의된다. 이 예시에서 서적 테이블에는 ISBN책 제목, 및 에디션 번호 열이 있으며, 저자 테이블에는 저자 ID 및 저자명 열이 있고, 마지막으로 저자-ISBN 테이블에는 저자 ID 및 ISBN 열이 있다. 관계형 모델은 중복성을 줄이도록 정규화되고 일반적으로 저장에 최적화된 데이터베이스에서 데이터베이스가 테이블 사이에서 참조 무결성을 실현할 수 있도록 고안되었다.
  • NoSQL 데이터베이스에서, 서적 레코드는 보통 JSON 문서로 저장된다. 각각의 서적에 대해, 항목, ISBN책제목에디션 번호저자명, 및 저자 ID가 단일 문서 내에 속성으로 저장된다. 이 모델에서, 데이터는 직관적 개발과 수평 확장성에 최적화된다.

NoSQL 데이터베이스를 사용해야 하는 이유

NoSQL 데이터베이스는 탁월한 사용자 경험을 제공하기 위하여 유연성과 확장성을 비롯해 고성능의 매우 기능적인 데이터베이스를 필요로 하는 모바일, 웹이나 게이밍과 같은 다양한 현대적인 애플리케이션에 적합하다.

  • 유연성: NoSQL 데이터베이스는 일반적으로 유연한 스키마를 제공하여 보다 빠르고 반복적인 개발을 가능하게 해준다. 이같은 유연한 데이터 모델은 NoSQL 데이터베이스를 반정형 및 비정형 데이터에 이상적으로 만들어 준다.
  • 확장성: NoSQL 데이터베이스는 일반적으로 고가의 강력한 서버를 추가하는 대신 분산형 하드웨어 클러스터를 이용해 확장하도록 설계되어있다. 일부 클라우드 제공자들은 완전관리형 서비스로서 이런 운영 작업을 보이지 않게 처리한다.
  • 고성능: NoSQL 데이터베이스는 특정 데이터 모델 및 액세스 패턴에 대해 최적화되어 관계형 데이터베이스를 통해 유사한 기능을 충족하려 할 때보다 뛰어난 성능을 얻게 해준다.
  • 고기능성: NoSQL 데이터베이스는 각 데이터 모델에 맞춰 특별히 구축된 뛰어난 기능의 API와 데이터 유형을 제공한다.

SQL (관계형) vs. NoSQL(비관계형) 데이터베이스 비교

수십 년간, 애플리케이션 개발을 위해 가장 많이 사용된 데이터 모델은 Oracle, DB2, SQL Server, MySQL, PostgreSQL과 같은 관계형 데이터베이스에서 사용하는 관계형 데이터 모델이었다.

2000년대 중반에서 말에 이르러서야 다른 데이터 모델들이 채택되고 사용되는 현상이 눈에 띄기 시작했다.

이러한 새로운 데이터베이스와 데이터 모델 등급을 차별화하고 분류하기 위해 "NoSQL"이란 용어가 만들어졌다.

흔히 "NoSQL"이란 용어는 "비관계형"과 같은 의미로 사용된다.

다양한 기능을 가진 여러 유형의 NoSQL 데이터베이스가 있지만, 다음 표에서는 SQL과 NoSQL 데이터베이스의 몇 가지 차이점에 대해 보여준다.

데이터베이스와 SQL

데이터베이스의 종류

RDBMS (관계형 데이터베이스 관리 시스템)

PostgreSQL, MySQL, SQLite, MS-SQL, Oracle 등

NoSQL : MongoDB, Cassandra, CouchDB, Google BigTable 등

데이터베이스에 쿼리하기 위한 언어 → SQL

같은 작업을 하더라도, 보다 적은 수의 SQL, 보다 높은 성능의 SQL

직접 SQL을 만들어 내기도 하지만, ORM(Object-Relational Mapping)을 통해 SQL을 생성/실행하기도 한다.

→ Not Magic.

중요) ORM을 쓰더라도, 내가 작성된 ORM 코드를 통해 어떤 SQL이 실행되고 있는지 파악을 하고 이를 최적화 할 수 있어야 한다.

→ django-debug-toolbar 적극 활용

ORM 이란?

객체(Object)와 관계형 데이터베이스(Relational)을 연결(Mapping)해 주는 것을 의미함.

간단하게 설명하면 데이터베이스의 테이블을 객체(Object)와 연결하여 테이블에 CRUD(Creat, Read, Update, Delete)를 할 때, SQL 쿼리를 사용하지 않고도, 가능하게 하는 것.

ORM을 사용하여 데이터 베이스에 CRUD 예시

# models.py

from django.db import models
from django.utils import timezone

class Post(models.Model):
    author = models.ForeignKey('auth.User', on_delete=models.CASCADE)
    title = models.CharField(max_length=100)
    content = models.TextField()
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    published_at = models.DateTimeField(blank = True, null = True)

    def publish(self):
        self.published_at = timezone.now()
        self.save()

    def __str__(self):
        return self.title
  1. Shell 접속

    python manage.py shell
  2. Model 을 import

    >>> from blog.models import Post

데이터의 생성 (Create)

>>> Post.objects.create(author=admin, title='This is a test title from django shell'
, content='This is a test title from django shell. This is a test title from django 
shell.')
<Post: This is a test title from django shell>

데이터 생성 확인 (Read)

>>> Post.objects.all()
<QuerySet [<Post: This is a test title from django shell>]>

데이터의 갱신 (Update)

>>> post = Post.objects.get(title='This is a test title from django shell')
>>> post.title = 'This is a test title updated from django shell'
>>> post.save()
>>> Post.objects.get(title__contains='updated')
<QuerySet [<Post: This is a test title updated from django shell>]>
>>> Post.objects.filter(title__contains='updated')
<QuerySet [<Post: This is a test title updated from django shell>]>

데이터의 삭제(Delete)

>>> post = Post.objects.get(title__contains='updated')
>>> post.delete()
>>> Post.objects.all()
<QuerySet []>

ORM : get()과 filter()

get()

  • 쿼리에 맞는 객체 하나([0]번째) 만 반환해준다.
  • filter().first()와 같다.
  • 쿼리에 맞는 결과가 없을 시 DoesNotExist 에러가 발생한다.
# ORM
>>> User.objects.get(id=1)   # Return : Object
-- SQL
SELECT * FROM accounts_user WHERE id=1;
# 예시
>>> qs = User.objects.get(id=1)
>>> str(qs.query)
-------------------------------------------------------------------------
AttributeError                               Traceback (most recent call last)
<ipython-input-9-173d883653f5> in <module>
----> 1 str(qs.query)

AttributeError: 'User' object has no attribute 'query'

>>> str(qs)
'abc@gmail.com'
  • qs는 get()을 이용해 반환 받은 객체이다.
  • 그렇기 때문에 .query 속성을 가지지 않아서 접근할 수 없다.
  • str()을 이용해 뽑은 객체가 이메일로 대표된 이유는 User 모델 클래스의 str() 메소드 리턴값이 이용되기 때문이다.
  • get()이 반환하는 유형이 객체이므로 .속성 으로 객체가 가진 다른 속성 값에는 접근이 가능하다.

filter()

  • 조건에 맞는 쿼리셋(객체 여러개)을 반환한다.
  • 쿼리셋에는 .query 속성이 존재하므로 str() 함수와 함께 ORM을 sql문으로 확인할 수 있다.
# ORM
>>> User.objects.filter(id=1)   # Return : QuerySet
-- SQL
SELECT * FROM accounts_user WHERE id=1;
>>> qs = User.objects.filter(id=1)
>>> str(qs.query)
'SELECT `accounts_user`.`id`, `accounts_user`.`last_login`, 
`accounts_user`.`is_superuser`, `accounts_user`.`is_staff`, ..........,
`accounts_user`.`email`, `accounts_user`.`password` 
FROM `accounts_user`
WHERE `accounts_user`.`id` = 4'

장고 ORM인 모델은 RDB만을 지원

장고 3.0.2 기준으로 기본 제공되는 backends

profile
항상 성장하는 개발자 최동혁입니다.

0개의 댓글