MongoDB Academy · 강의

중단 없이 스키마 발전시키기

운영 중인 컬렉션의 기존 검증기를 업데이트하고 문서를 새로운 형태에 맞게 보완하는 마이그레이션 스크립트를 작성합니다.

레슨 4/413개 단계

중단 없이 스키마 발전시키기은(는) CoddyKit의 무료 MongoDB Academy 강의입니다. 이것은 4개 중 4번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 MongoDB Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. MongoDB Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

스키마 발전의 과제

애플리케이션이 성장하면 요구 사항이 바뀌고 MongoDB 스키마도 발전해야 합니다. 관계형 데이터베이스와 달리, 마이그레이션 중 전체 테이블을 잠그는 차단형 ALTER TABLE을 실행할 수 없습니다. MongoDB의 유연성 덕분에 이전 문서 형태와 새로운 문서 형태가 같은 collection에 공존할 수 있지만, 스키마가 전환되는 동안 애플리케이션이 계속 작동하도록 신중한 마이그레이션 전략이 필요합니다.

1단계: 경고 모드에서 검증기 업데이트하기

모든 스키마 마이그레이션은 collection의 검증기를 새 스키마에 맞게 업데이트하는 것부터 시작하되, validationAction: 'warn'으로 설정하십시오. 그러면 기존의 규격 미준수 문서를 그대로 유지하고 오류 없이 업데이트할 수 있으며, 보완이 필요한 문서 수를 측정할 수 있습니다. 업데이트된 애플리케이션 코드에서 새로 기록하는 데이터는 새 스키마를 따르게 됩니다.

// Add a new required field 'phoneNumber' to the validator
db.runCommand({
  collMod: 'users',
  validator: {
    $jsonSchema: {
      bsonType: 'object',
      required: ['name', 'email', 'phoneNumber'],
      properties: {
        name:        { bsonType: 'string' },
        email:       { bsonType: 'string' },
        phoneNumber: { bsonType: 'string' }
      }
    }
  },
  validationLevel: 'moderate',
  validationAction: 'warn'
});

2단계: 애플리케이션 코드 업데이트하기

새 스키마에 맞는 문서를 기록하도록 업데이트된 애플리케이션 코드를 배포하십시오. 이제 새 문서에는 새로운 필드가 포함됩니다. 스키마가 변경되기 전에 기록된 기존 문서는 원래 형태로 collection에 남아 있습니다. 이 단계에서는 애플리케이션 코드가 두 문서 형태를 모두 처리해야 합니다. 예를 들어 새 필드가 없을 때 기본값을 제공할 수 있습니다.

// Application code that handles both old and new document shapes
async function getUserPhone(userId) {
  const user = await db.collection('users').findOne({ _id: userId });
  // Provide a fallback for documents written before the migration
  return user.phoneNumber || 'Not provided';
}

3단계: 데이터 보완 마이그레이션 스크립트 작성하기

데이터 보완 스크립트은 새 필드가 없는 모든 문서를 순회하며 기본값을 설정합니다. 리소스 잠금이나 서버 부하 급증을 피하려면 작은 묶음으로 실행하십시오. 효율성을 위해 ordered: false와 함께 bulkWrite를 사용하고, 중단된 경우 재개할 수 있도록 진행 상황을 로깅으로 추적하십시오.

// Backfill: set phoneNumber to '' for documents that lack it
const collection = db.collection('users');
const cursor = collection.find({ phoneNumber: { $exists: false } });

const batchSize = 500;
let batch = [];

for await (const doc of cursor) {
  batch.push({
    updateOne: {
      filter: { _id: doc._id },
      update: { $set: { phoneNumber: '' } }
    }
  });
  if (batch.length === batchSize) {
    await collection.bulkWrite(batch, { ordered: false });
    console.log('Processed', batchSize, 'docs');
    batch = [];
  }
}
if (batch.length) await collection.bulkWrite(batch, { ordered: false });
console.log('Backfill complete');

4단계: 엄격한 오류 모드로 전환하기

데이터 보완이 완료되고 모든 문서가 새 스키마를 따르는지 확인한 후 validationLevel을 strict로, validationAction을 error로 전환하십시오. 이 시점부터 스키마를 위반하는 모든 쓰기 작업이 거부됩니다. 전환 후 처음 몇 시간 동안 애플리케이션에서 예상치 못한 오류가 발생하는지 모니터링하여 데이터 보완 과정에서 놓친 예외적인 경우를 찾아내십시오.

// Enable full enforcement after backfill is verified
db.runCommand({
  collMod: 'users',
  validationLevel: 'strict',
  validationAction: 'error'
});
console.log('Full schema enforcement enabled');

필드 이름을 안전하게 변경하기

필드 이름을 변경하려면(예: fullName → name) 먼저 애플리케이션이 계속 fullName을 대체값으로 읽는 동안 새 문서에 name을 추가하십시오. 그런 다음 $rename 또는 $set을 사용하여 fullName을 name으로 복사하며 데이터를 보완하십시오. 마지막으로 애플리케이션이 name만 기록하고 읽도록 업데이트하고, 기존 문서에서 fullName을 제거하십시오.

// Backfill: rename fullName to name for all existing documents
db.users.updateMany(
  { fullName: { $exists: true }, name: { $exists: false } },
  [{ $set: { name: '$fullName' } }, { $unset: 'fullName' }]
);

스키마 버전 관리 패턴

복잡하고 장기간 실행되는 마이그레이션에는 모든 문서에 schemaVersion 필드를 추가하십시오. 애플리케이션 코드는 이 필드를 확인하고 문서를 처리하기 전에 이전 버전마다 변환 함수를 적용합니다. 새로 기록하는 데이터에는 항상 최신 schemaVersion이 포함됩니다. 이를 통해 통제되고 감사 가능한 업그레이드 경로를 확보하며 여러 세대의 스키마를 무기한 공존시킬 수 있습니다.

// Insert new document with schema version
db.products.insertOne({
  schemaVersion: 2,
  name: 'Widget Pro',
  priceUSD: 49.99,
  categories: ['electronics']
});

// Application transformer
function normalise(doc) {
  if (doc.schemaVersion === 1) {
    // v1 used 'price' instead of 'priceUSD'
    doc.priceUSD = doc.price;
    delete doc.price;
    doc.schemaVersion = 2;
  }
  return doc;
}

새 선택적 필드를 안전하게 추가하기

새로운 선택적 필드를 추가하는 것은 가장 간단한 스키마 발전 방법입니다. 해당 필드를 required에 추가하지 않고 검증기의 properties만 업데이트하십시오. 기존 문서에는 필드가 없지만 필수가 아니므로 검증을 통과합니다. 데이터를 보완할 필요도 없습니다. 새 문서에는 필드를 포함할 수 있으며, 애플리케이션 코드는 안전한 대체 기본값을 사용하여 해당 필드를 읽습니다.

// Add optional 'avatarUrl' field to the validator
db.runCommand({
  collMod: 'users',
  validator: {
    $jsonSchema: {
      bsonType: 'object',
      required: ['name', 'email'],
      properties: {
        name:      { bsonType: 'string' },
        email:     { bsonType: 'string' },
        avatarUrl: { bsonType: 'string' }  // optional — no backfill needed
      }
    }
  }
});

스키마에서 필드 제거하기

필드를 폐기하려면 먼저 해당 필드가 필수였다면 required에서 제거한 다음, 더 이상 그 필드를 기록하지 않는 애플리케이션 코드를 배포하십시오. 시간이 지나면 새 문서에는 해당 필드가 포함되지 않습니다. 필요하다면 $unset을 사용하여 기존 모든 문서에서 필드를 제거하는 방식으로 데이터를 보완할 수 있지만, 필드가 저장 공간을 낭비하거나 혼란을 일으키는 경우에만 필요합니다.

// Remove the deprecated 'legacyCode' field from all documents
db.products.updateMany(
  { legacyCode: { $exists: true } },
  { $unset: { legacyCode: '' } }
);

다운타임 없는 마이그레이션 요약

다운타임 없는 스키마 마이그레이션의 핵심은 MongoDB가 같은 collection에서 서로 다른 문서 형태를 허용한다는 점입니다. 따라서 스키마를 변경하기 위해 데이터베이스를 오프라인으로 전환할 필요가 없습니다. 4단계 절차인 경고 모드 검증기, 애플리케이션 코드 업데이트, 데이터 보완, 엄격한 적용은 스키마 변경과 배포를 분리하고 전환 일정을 완전히 제어할 수 있게 해 줍니다.

마이그레이션 완료 여부 확인하기

strict 모드로 전환하기 전에 필수 필드가 누락된 문서가 하나도 없는지 확인하십시오. 간단한 개수 조회로 완료 여부를 확인할 수 있습니다. 아직 규격을 따르지 않는 문서가 있다면 데이터 보완 스크립트를 다시 실행하십시오. 이 확인 단계는 error 동작으로 전환한 후 갑자기 검증 오류가 발생하는 것을 방지합니다.

// Verify no users are missing the new required field
const missing = await db.collection('users').countDocuments({
  phoneNumber: { $exists: false }
});
console.log('Documents missing phoneNumber:', missing);
// Should be 0 before enabling strict enforcement

빠른 확인

이 레슨에서 배운 MongoDB 및 NoSQL 데이터베이스 개념을 제대로 이해했는지 테스트해 보십시오.

레슨 요약

이 레슨에서는 다음을 배웠습니다. 4단계 마이그레이션 절차(warn → 애플리케이션 업데이트 → 데이터 보완 → strict)는 다운타임을 없앱니다. 스키마 버전 관리 패턴을 사용하면 여러 문서 형태를 무기한 공존시킬 수 있습니다. 또한 엄격한 적용 전에 검증하면 예상치 못한 오류를 방지할 수 있습니다. 다음으로는 쿼리에 실제로 필요한 필드만 가져오는 프로젝션과 필드 선택을 살펴보겠습니다.

무료로 시작

AI 튜터와 함께 JavaScript을(를) 배우세요 — 무료

브라우저에서 실제 코드를 작성하고 실행하며, 24/7 AI 튜터로부터 즉각적인 도움을 받고, 웹이나 앱에서 중단한 부분부터 계속 학습하세요.

코스
30
레슨
120

자주 묻는 질문

“중단 없이 스키마 발전시키기” 강의는 무료인가요?

네 — “중단 없이 스키마 발전시키기” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 MongoDB Academy 강의 전체를 잠금 해제할 수 있습니다. MongoDB Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

“중단 없이 스키마 발전시키기”에서 뭘 배우나요?

운영 중인 컬렉션의 기존 검증기를 업데이트하고 문서를 새로운 형태에 맞게 보완하는 마이그레이션 스크립트를 작성합니다. 브라우저에서 직접 실행하는 실습 코드로 MongoDB Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

MongoDB Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 MongoDB Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 4번째 강의입니다.

“중단 없이 스키마 발전시키기” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 MongoDB Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 MongoDB Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. 컬렉션에 검증기 추가
  2. 유형, 필수 필드, 열거형 제약 조건
  3. 검증 수준과 작업
  4. 중단 없이 스키마 발전시키기
← MongoDB Academy(으)로 돌아가기