메인 콘텐츠로 건너뛰기
블로그 데이터베이스 장고와 SQL : 데이터베이스 확장을위한 다이나믹 듀오

장고와 SQL : 데이터베이스 확장을위한 다이나믹 듀오

ScaleDatabaseswithDjangoandSQL-BlogHeader

응용 프로그램의 요구 사항을 충족하도록 데이터베이스를 확장하고 최적화하는 것은 중요한 과제가 될 수 있습니다. 내 최근 블로그를 읽지 않은 경우 장고가 무거운 짐을 들어 올릴 수있는 방법 Python 그리고 SQL 데이터베이스 응용 프로그램, 나는 당신이 그것을 체크 아웃하는 것이 좋습니다. 그러나 TL : DR 버전은 SQL이 SQL 데이터베이스에 최적화되어 있다는 것입니다. Python 그렇지 않으며 장고 는이 두 언어를 함께 사용할 때 마찰, 복잡성 및 코드가 적은보다 효과적인 응용 프로그램을 빌드하는 데 도움이되는 훌륭한 중개자입니다.

따라서 장고는 데이터베이스 앱을 만드는 데 많은 노력을 기울이지 만 데이터베이스의 일상적인 관리 및 모니터링에 대한 책임은 여전히 있습니다. 이러한 관리 작업 중 일부는 Linode 관리 데이터베이스와 같은 서비스를 사용하여 클라우드 공급자에게 지연될 수 있지만 확장할 때 다음과 같은 새로운 장애물이 발견될 수 있습니다.

  • 데이터베이스 마이그레이션. 기존 데이터베이스를 데이터베이스 구성표의 제어된 변경으로 원하는 새 상태로 변환합니다.
  • 다중 데이터베이스 배포. 성능을 최적화하기 위해 개발자는 세분화된 기능에 대해 별도의 데이터베이스를 사용하도록 애플리케이션을 설계할 수 있습니다. 예를 들어 기본 읽기/쓰기 데이터베이스와 공통 쿼리에 대한 읽기 복제본 데이터베이스가 있습니다.

데이터베이스 중 하나가 SQL을 사용하는 경우 장고를 사용하여 마찰을 줄이고 상당한 양의 데이터를 처리하면서 훨씬 쉽게 작업 할 수 있습니다.

이 두 가지 주요 데이터베이스 관리 개념에 대한 소개는 데이터베이스 이해 전자 책 및 새로운 교육 비디오 시리즈에있는 프로덕션 준비가 된 Django 응용 프로그램을 구축하기위한 단계별 지침과 쌍을 이룹니다. 어느 학습 경로이든 장고가 SQL 무거운 짐을 덜어주는 데 도움이됩니다.

데이터베이스 마이그레이션
시작할 때 주어진 열에 대해 데이터 형식을 올바르게 가져 오는 것은 특히 데이터 요구 사항이 시간이 지남에 따라 필연적으로 변경되기 때문에 약간 까다로울 수 있습니다. 제목 필드의 길이가 80자에 불과하다면 어떨까요? 항목이 데이터베이스에 추가 된 시점을 정확하게 추적 할 수 있도록 타임 스탬프 필드를 추가해야하는 경우 어떻게해야합니까?

테이블을 만든 후 변경하면 몇 가지 이유로 인해 꽤 지저분해질 수 있습니다.

  • 기존 값으로 무엇을합니까?
  • 기존 행에 새 열/필드에 대한 데이터가 누락된 경우 어떻게 해야 합니까?
  • 열/필드를 제거하면 어떻게 되나요? 데이터는 어떻게 되나요?
  • 이전에 존재하지 않았던 관계 (예 : 외래 키)를 추가하면 어떻게됩니까?

운 좋게도 장고 개발자에게는 다음과 같은 것이 있습니다. makemigrations 그리고 migrate.

그것이 어떻게 작동하는지 살펴 보겠습니다.

다음은 Django 데이터 모델 예제입니다.

class BlogArticle(models.Model):
    user = models.ForeignKey(User, default=1, on_delete=models.SET_DEFAULT)
    title = models.CharField(max_length=120)
    slug = models.SlugField(blank=True, null=True)
    content = models.TextField(blank=True, null=True)
    publish_timestamp = models.DateTimeField(
        auto_now_add=False,
        auto_now=False,
        blank=True,
        null=True,
    )

필드를 추가해 보겠습니다.

updated_by = models.ForeignKey(
        User, related_name="editor", null=True, blank=True, on_delete=models.SET_NULL
)

이 필드를 사용하면 모델을 변경할 마지막 사용자를 추적할 수 있습니다. 

모델을 업데이트해 보겠습니다.

class BlogArticle(models.Model):
    user = models.ForeignKey(User, default=1, on_delete=models.SET_DEFAULT)
    title = models.CharField(max_length=120)
    slug = models.SlugField(blank=True, null=True)
    content = models.TextField(blank=True, null=True)
    publish_timestamp = models.DateTimeField(
        auto_now_add=False,
        auto_now=False,
        blank=True,
        null=True,
    )
    # our new field
    updated_by = models.ForeignKey(
        User, related_name="editor", null=True, blank=True, on_delete=models.SET_NULL
    )

이제이 파일을 저장 한 후에이 파일을 저장하십시오. BlogArticle 클래스는 (models.py), 데이터베이스에이 변경 사항이 발생했음을 어떻게 알릴 수 있습니까?

두 가지 방법이 있습니다.

  1. python manage.py makemigrations
  2. python manage.py migrate

이 두 명령이 수행하는 작업에 대해 설명하겠습니다.

python manage.py 임시 이주

python manage.py makemigrations 에서 변경 사항을 찾습니다. 전체 models.py Django 프로젝트에서 파일을 저장하고 변경 사항을 찾습니다. 변경 사항이 발견되면 새로운 python 파일이 생성됩니다. 제안된 변경 사항 우리의 SQL 데이터베이스 필요 만들 수 있습니다. 제안 된 변경 사항은 다음과 같습니다.

from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

    dependencies = [
        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
        ('articles', '0001_initial'),
    ]

    operations = [
        migrations.AddField(
            model_name='article',
            name='updated_by',
            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='editor', to=settings.AUTH_USER_MODEL),
        ),
    ]

물론 이것은 또 다른 것입니다. Python 파일. 이 파일은 우리 (개발자)가 데이터베이스에서 어떤 일이 일어나 야하는지 알려줍니다. 그것은 다음과 같이 쓰여졌습니다. Python 응집력을 유지하고 장고 ORM의 내장 기능을 활용하기 위해 SQL이 아닙니다.

그러나 왜 이것이 일어나 하는 것에 대한 파일입니까? 글쎄, 이것에 대한 몇 가지 이유가 있습니다 :

  • 우리가 그것이 일어나기 전에 일어나 할 일을 검토해야한다면, 우리는 그것을 여기에서 잡을 수 있습니다.
  • makemigrations 명령은 그렇지 않습니다 로 확인 이 변경 사항이 있는지 확인하는 데이터베이스 깡통 심지어 일어납니다.
  • 데이터베이스는 이러한 요구 사항에 맞게 이미 변경되었을 수 있습니다 (데이터베이스를 관리하는 사람 / 무엇과 관련된 여러 요인에 따라 다름).
  • 프로덕션 데이터베이스를 변경하기 전에 테스트를 실행해야하는 경우 지금 당장은 그렇게하는 것이 놀라운 시간이 될 것입니다.

이 변경 사항이 유효하다고 가정하면 (우리가 말할 수있는 한) 변경 사항을 커밋 할 수 있습니다.

python manage.py 마이그레이션

python manage.py migrate 우리를 위해 데이터베이스를 변경하려고 시도 할 것입니다 - 모든 필드, 열, 테이블, 외래 키, 당신은 그것을 명명 - 장고는 데이터베이스가 우리가 의도 한 방식으로 업데이트되도록 돕기 위해 우리를 위해 작업을 수행 할 것입니다.

장고는 여러 가지 이유로 이러한 변경을 수행하지 못할 수 있습니다 . 새로운 Django 개발자의 경우, 이것은 거의 항상 필드와 열을 추가 및 제거하고 마이그레이션을 올바르게 실행하지 못하기 때문입니다.

올바르게 완료되면 python manage.py migrate 우리와 일치하는 안정적인 시스템을 보장합니다. Python 우리의 SQL 테이블과 함께 코드, 따라서 우리에게 장고와 SQL 데이터베이스 모두 제공하는 모든 굉장함을 허용.

이것이 어떻게 우리에게 더 많은 유연성을 제공합니까?

Python 에는 SQL이 적용되지 않는 광범위한 응용 프로그램이 있습니다. 구조화 된 쿼리 언어에는 이름에 작성된 제한 사항이 있습니다. SQL 만으로 Pixar 애니메이션을 만드는 사람은 누구입니까?

좋아,이 모든 것은 단순함을 말하는 것입니다. Python 실제로 개발자가 SQL의 힘을 채택하고 아마도 그것을 모른 채 채택 할 수 있도록 도와줍니다.

관리되는 데이터베이스와 장고가 의미있는 이유

장고를 포함한 웹 응용 프로그램을 만들 때 몇 가지 사항을 결정해야합니다.

  • 어떤 데이터 스토리지 솔루션을 원하십니까? MySQL, Postgres, MongoDB, Redis, 오브젝트 스토리지 등
  • 데이터 스토리지 솔루션을 어떻게 실행/통합할 것인가?
  • 중단 또는 가동 중지 시간으로부터 어떻게 복구합니까?
  • 스토리지 솔루션을 어떻게 유지할 것인가?
  • 스토리지 솔루션을 어떻게 보호할 것인가?
  • 스토리지 솔루션을 어떻게 백업합니까?

이러한 질문에 대한 답변은 프로젝트가 복잡해짐에 따라 변경될 수 있지만 모두 자체 관리와 타사 관리 중 하나를 결정하는 동일한 위치에서 시작됩니다.

자체 관리:

  • 장점 : 제어 및 비용.
  • (중요) 단점 : 당신은 모든 것에 책임이 있습니다.

관리 서비스는 종종 처음부터 더 많은 비용이 드는 반면, 자체 관리는 필요한 것에 최적화 된 원하는 Linux 배포판을 사용할 수 있음을 의미합니다. 여기에는 팀이 수정한 MySQL의 분기된 버전을 실행하는 것이 포함될 수 있습니다. 서비스 운영에 비용을 절감 할 수 있지만 유지 관리하는 데 항상 더 많은 시간이 걸립니다.

타사 관리 데이터베이스: 

예, 달러와 센트가 약간 더 비쌀 수도 있지만 유지 보수하는 데 훨씬 적은 시간이 걸릴 것입니다. 이 옵션과 관리되는 데이터 스토리지 솔루션은 내 웹 응용 프로그램을위한 사실상의 선택입니다. 이 예제에서는 이미 Django를 사용하여 데이터베이스 트랜잭션을 관리하고 있습니다. SQLAlchemy는 또한 FastAPI, Flask 및 기타 여러 프레임 워크와 함께 사용되는이 강점을 공유합니다. 이미 SQL 쓰기를 아웃소싱하는 경우 Python 패키지, SQL 서버를 실행하는 아웃소싱을하지 않는 이유는 무엇입니까?

자, 의 효과를 감안할 때 Python ORM (Django ORM 및 SQLAlchemy와 같은)은 가능할 때마다 관리되는 데이터베이스 및 / 또는 관리되는 데이터 스토리지 서비스를 사용하는 것이 좋습니다.

  • 개발 시간 단축
  • 관리 시간 단축
  • 회복 시간 단축
  • 서비스 중단 감소
  • 배포 및 개발 복잡성 감소
  • 데이터베이스 마이그레이션의 복잡성 감소(다른 서비스에서)
  • SQL 개발자를 위한 반복적/비효율적/비효율적인 활동 감소
  • DevOps/Ops 복잡성 감소
  • 비 SQL 개발자의 효율성 향상
  • 배포 및 개발 속도 향상
  • 신뢰성 향상(서비스 수준 계약에 의해 뒷받침되는 경우가 많음)
  • 보안 강화
  • 향상된 유지 보수성
  • 백업 및 중복성 증가
  • 비용의 한계 증가

Linode에서 관리되는 MySQL 데이터베이스 클러스터 와 Linode Object Storage (CSS, JavaScript, 이미지, 비디오 등과 같은 파일 저장용)를 사용하는 사고 방식으로 위의 목록을 만들었습니다. 실질적으로 말해서, 이러한 서비스를 사용하면 장고, FastAPI, 플라스크로 우수한 웹 응용 프로그램을 구축하는 데 집중할 수 있습니다. Node.js, 또는 무엇이든간에. 다른 말로하면, 우리는 사용자가 실제로 원하는 도구와 소프트웨어를 구축하는 데 초점을 맞 춥니 다. 아시다시피, 진정한 가치는 그들에게 어디에 있습니까?

MySQL, PostgreSQL, Redis, and Django

오랫동안 장고의 선도적 인 데이터베이스는 PostgreSQL이었습니다. 나는 이것이 대부분 Postgres 내에서만 JSONField를 사용할 수 있기 때문이라고 주장 할 것이다. 장고 3.2 + 및 MySQL 5.7.8 +를 사용하면 JSONField를 MySQL에서도 사용할 수 있습니다.

이것이 왜 중요한가?

JSON과 같은 구조화되지 않은 데이터를 저장하는 것은 사용자 생성 콘텐츠를 처리하거나 다른 콘텐츠의 데이터를 저장할 때 종종 필요합니다. API 서비스. 방법을 살펴 보겠습니다.

from django.db import models

class Pet(models.Model):
    name = models.CharField(max_length=200)
    data = models.JSONField(null=True)

    def __str__(self):
        return self.name

이 애완 동물과 관련하여 저장하려는 데이터는 다음과 같습니다.

pet1 = {
    "name": "Bruno",
    "type": "Rat",
    "nickname": "We don't talk about it",
    "age": 2,
    "age_interval": "months"
}

pet2 = {
    "name": "Tom",
    "type": "Cat",
    "breed": "Mixed"
    "age": 4,
    "age_interval: "years",
    "favorite_food": [{"brand": "Acme", "flavor": "Tuna" }]
}

pet3 = {
    "name": "Stewey",
    "type": "Dog",
    "breed": "unknown"
    "age": 34,
    "age_interval: "dog years",
    "nickname": "Football"
}

이 데이터는 우리가 언제 필요할 수도 있는지를 보여줍니다. JSONField . 우리는 모든 애완 동물 이름을 저장할 수 있습니다 ( name key) 및 나머지는 JSONField에 저장되도록 유지합니다. 멋진 점 JSONFields 이러한 다양한 스키마를 사용하더라도 다른 표준 Django 필드와 마찬가지로 쿼리 할 수 있습니까?

장고 개발자들 사이에서 MySQL 또는 PostgreSQL을 사용할 데이터베이스에 대한 논쟁이 계속되고 있습니다. 가장 오랜 시간 동안 JSONField가 PostgreSQL에서만 사용할 수 있었기 때문에 항상 PostgreSQL을 선택했으며 더 이상 그렇지 않습니다. 나는 하나를 골라서 더 이상 당신의 필요를 충족시키지 못할 때까지 그것을 고수한다고 말합니다.

그러나 우리는 무엇을 위해 Redis를 사용합니까?

Redis는 매우 빠르며 임시 데이터베이스 (잠시 후 자세히 설명), 캐싱 서비스 및 / 또는 메시징 큐로 자주 사용되는 메모리 내 데이터 저장소입니다. 임시 데이터베이스라고 부르는 이유는 메모리 내에 있기 때문입니다. 메모리는 종종 디스크 스토리지보다 비용이 많이 들기 때문에 데이터를 메모리에 장기간 저장하는 것은 종종 불가능합니다.

Redis와 Django에 대한 나의 주요 사용 사례는 캐싱 및 큐잉입니다.

캐싱: 사용자가 많이 방문하는 여러 웹 페이지가 있다고 가정 해 봅시다. 이러한 페이지의 데이터가 가능한 한 빨리 사용자에게 표시되기를 원합니다. 장고의 캐싱 시스템인 Redis는 이 작업을 매우 쉽게 수행할 수 있게 해줍니다. 이러한 페이지 내의 데이터는 SQL 데이터베이스에서 렌더링될 있지만 Redis는 캐시에서 렌더링된 데이터를 저장할 수 있습니다. 즉, Redis를 SQL과 함께 사용하면 SQL 데이터베이스에 대한 쿼리 양을 줄이면서 응답 속도를 높일 수 있습니다.

큐: Redis의 또 다른 인기있는 사용 사례는 장기 실행 작업을 다른 프로세스로 오프로드하는 것입니다 (종종 Python 셀러리라는 패키지). 이렇게 해야 하는 경우 Redis를 다른 시간에 완료해야 하는 작업의 대기열로 사용할 수 있습니다.

예를 들어 지난 다섯 년 동안 모든 거래에 대한 보고서가 필요한 사용자가 있는 경우 소프트웨어가 실제로 해당 보고서를 생성하는 데 몇 시간이 걸릴 수 있습니다. 분명히 아무도 몇 시간 동안 기계를 응시하지 않을 것입니다. 따라서 우리는이 요청을 사용자로부터 Redis 대기열로 오프로드합니다. Redis에 도착하면 실제로 보고서를 생성하기 위해 작업자 프로세스 (장고와 함께 Celery를 사용하는 것과 같은)를 실행할 수 있습니다. 보고서가 완료되면 얼마나 오래 걸렸든 사용자에게 알림이 전송됩니다. 이 알림은 다른 알림과 마찬가지로 셀러리/장고 작업자 프로세스와 결합된 Redis 대기열을 통해서도 수행할 수 있습니다.

이것은 Redis와 MySQL 실제로 서로를 잘 보완한다는 것을 말하는 것입니다. Linode Marketplace를 통해 자체 관리되는 Redis 데이터베이스 서버를 배포할 수 있습니다.

Object Storage

마지막으로 사용하는 것이 좋습니다 데이터 관련 관리 서비스는 Linode 객체 스토리지입니다. 개체 저장소는 저장해야 할 수 있는 다른 모든 종류의 데이터를 담당합니다. 예를 들어, MySQL의 비디오에 모든 바이트를 저장하지 않습니다. 대신 해당 비디오와 관련된 메타데이터를 저장하고 비디오를 개체 저장소에 저장합니다.

다음은 개체 저장소를 사용하는 몇 가지 사항입니다.

  • 계단식 스타일시트(CSS)
  • 자바 스크립트 (예 : React.js, Vue.js, 바닐라.js 등)
  • 영상
  • 이미지(원시 및 압축)
  • CSV, XLSX
  • 데이터베이스 백업
  • Docker 컨테이너 이미지 계층(자체 관리되는 경우)
  • 학습된 기계 학습 알고리즘의 반복
  • Terraform 상태 파일
  • PDF(크고 작은 PDF)
  • 자주 다운로드(또는 업로드)해야 하는 모든 영구 파일

요약

이 글을 읽은 후에는 웹 응용 프로그램 프로젝트에서 관리 서비스의 힘을 활용하려는 동기를 느끼시기 바랍니다. 장고는 SQL 데이터베이스 위에 웹 응용 프로그램을 구축하기위한 훌륭한 솔루션이지만 확실히 유일한 것은 아닙니다. SQL 및 SQL 서버의 내부를 자세히 살펴보고 싶다면 장고가 할 수있는 일의 대부분을 처리하기 위해 장고를 활용하는 성공적인 응용 프로그램이 얼마나 많은지 확인하는 것이 가치있는 운동이라고 생각합니다.

다음은 Linode에서 관리되는 MySQL을 사용하여 장고를 멋지게 만드는 몇 가지 (또는 많은) 하이라이트입니다.

  • 장고는 당신을 위해 무거운 SQL 리프팅을 수행합니다 (Flask / FastAPI를위한 SQLAlchemy와 같은 도구도 마찬가지입니다)
  • 장고는 원시 SQL 명령도 가능하게합니다 (SQLAlchemy와 같은 도구도 마찬가지입니다)
  • 장고는 초보자가 SQL 명령을 배울 수 있도록 도와줍니다.
  • 장고는 MySQL과 PostgreSQL에 대한 내장 지원을 가지고 있습니다 (db 관련 외에도 python 클라이언트)
  • 프로덕션 배포 속도 향상
  • 신뢰성 및 복구 가능성 향상
  • 개발 및 프로덕션 환경이 데이터베이스 기술과 거의 정확하게 일치하도록 지원
  • 컨테이너 기반 장고를보다 쉽고 안정적으로 만듭니다.
  • 단일 노드 배포에서 다중 노드로의 확장 또는 쿠버네티스로의 완전한 전환 잠금 해제
  • 새로운 장고를 위해 더 쉬운/Python 프로덕션 등급 시스템을 사용하는 개발자
  • 여러 곳에서 데이터베이스 공유 python-based 앱은 더 쉽고 안전합니다 (예 : 장고 기반 MySQL 데이터베이스에서 / Django 기반 MySQL 데이터베이스로 읽기 / 쓰기와 같은 FastAPI 응용 프로그램).
  • 장고의 JSONField는 이제 MySQL을 사용하여 지원되었습니다 (이전에는 PostgreSQL 만)
  • 테스트 용이성(CI/CD 또는 로컬 개발 환경에서)
  • 장고 요구를 충족하기 위한 스케일
  • 단일 Django 프로젝트에서 여러 데이터베이스에 대한 지원 : MySQL을 기본 읽기 / 쓰기 데이터베이스로 사용하고 공통 쿼리에 MySQL 읽기 복제본 데이터베이스를 사용합니다.
  • 엄격한 액세스 제어(Linode Private IP, 로컬 개발)
  • 연결에 SSL 인증서 필요(배포에 복잡성을 추가하지만 보안도 강화함)
  • 개인 연결 사용(동일한 지역, 연결 비용 절감)

관리되는 MySQL 데이터베이스, CI / CD를위한 GitHub 액션과 함께 Linode에 장고 응용 프로그램을 배포하는 현대적인 접근 방식에 관심이 있다면, Terraform그리고 Ansible, 무료 단계별 교육 콘텐츠의 톤에 점프 :

시작하는 데 도움이 되도록 기업가 코딩 GitHub 에는 시리즈의 각 단계와 함께 제공되는 코드 리포지토리가 있습니다. 행운을 빕니다, 그리고 트위터 @JustinMitchel을 통해 일이 어떻게 진행되고 있는지 알려주세요.


내용

댓글 남기기

이메일 주소는 게시되지 않습니다. 필수 필드가 표시됩니다 *