Structured Query Language (구조적 질의 언어)의 줄임말로, 관계형 데이터베이스 시스템(RDBMS)에서 자료를 관리 및 처리하기 위해 설계된 언어이다.
SQL 문법은 크게 3가지의 종류로 나누어진다.
SQL은 대소문자를 가리지 않는다.
(단, 서버 환경이나 DBMS 종류에 따라 데이터베이스 또는 필드명에 대해 대소문자를 구분하기도 한다.)
SQL 명령은 반드시 세미콜론(;)으로 끝나야 한다.
고유의 값은 따옴표(’’)로 감싸준다.
ex) SELECT * FROM EMP WHERE NAME = ‘James’;
SQL에서 객체를 나타낼 때는 백틱(``)으로 감싸준다.
ex) SELECT COST
, TYPE
FROM INVOICE
;
주석은 일종의 도움말로, 주석 처리된 문장은 프로그램에서 동작하지 않는다. 한 줄 주석은 문장 앞에 —를 붙여서 사용한다.
ex) — SELECT * FROM EMP; 이 쿼리는 실행되지 않습니다.
여러 줄 주석은 /* */ 로 감싸준다.
ex)
/*
SELECT FROM EMP WHERE EMPID=(SELECT FROM EMP WHERE NAME=’홍길동’)
*/
특정 데이터 모델에 대해 특정 목적에 맞추어 구축되는 데이터베이스로서 현대적인 애플리케이션 구축을 위한 유연한 스키마를 갖추고 있다.
NoSQL 데이터베이스는 개발의 용이성, 기능성 및 확장성을 널리 인정받고 있다.
NoSQL 데이터베이스에서는 데이터의 액세스 및 관리를 위해 다양한 데이터 모델을 사용한다.
이러한 데이터베이스 유형은 큰 테이터 볼륨, 짧은 지연 시간과 유연한 데이터 모델이 필요한 애플리케이션에 최적화되었으며, 이는 다른 데이터베이스의 데이터 일관성 제약 일부를 완화함으로써 이루어진다.
간단한 서적 데이터베이스를 위한 스키마 모델 구축 사례를 고려해 보자:
NoSQL 데이터베이스는 탁월한 사용자 경험을 제공하기 위하여 유연성과 확장성을 비롯해 고성능의 매우 기능적인 데이터베이스를 필요로 하는 모바일, 웹이나 게이밍과 같은 다양한 현대적인 애플리케이션에 적합하다.
수십 년간, 애플리케이션 개발을 위해 가장 많이 사용된 데이터 모델은 Oracle, DB2, SQL Server, MySQL, PostgreSQL과 같은 관계형 데이터베이스에서 사용하는 관계형 데이터 모델이었다.
2000년대 중반에서 말에 이르러서야 다른 데이터 모델들이 채택되고 사용되는 현상이 눈에 띄기 시작했다.
이러한 새로운 데이터베이스와 데이터 모델 등급을 차별화하고 분류하기 위해 "NoSQL"이란 용어가 만들어졌다.
흔히 "NoSQL"이란 용어는 "비관계형"과 같은 의미로 사용된다.
다양한 기능을 가진 여러 유형의 NoSQL 데이터베이스가 있지만, 다음 표에서는 SQL과 NoSQL 데이터베이스의 몇 가지 차이점에 대해 보여준다.
RDBMS (관계형 데이터베이스 관리 시스템)
PostgreSQL, MySQL, SQLite, MS-SQL, Oracle 등
NoSQL : MongoDB, Cassandra, CouchDB, Google BigTable 등
같은 작업을 하더라도, 보다 적은 수의 SQL, 보다 높은 성능의 SQL
직접 SQL을 만들어 내기도 하지만, ORM(Object-Relational Mapping)을 통해 SQL을 생성/실행하기도 한다.
→ Not Magic.
중요) ORM을 쓰더라도, 내가 작성된 ORM 코드를 통해 어떤 SQL이 실행되고 있는지 파악을 하고 이를 최적화 할 수 있어야 한다.
→ django-debug-toolbar 적극 활용
# 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
Shell 접속
python manage.py shell
Model 을 import
>>> from blog.models import Post
>>> 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>
>>> Post.objects.all()
<QuerySet [<Post: This is a test title from django shell>]>
>>> 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>]>
>>> post = Post.objects.get(title__contains='updated')
>>> post.delete()
>>> Post.objects.all()
<QuerySet []>
# 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'
# 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'