Anforderungsanalyse und Schemaentwurf
Lernende übertragen Anwendungsanforderungen in ein MongoDB-Schema, entscheiden zwischen Einbettung und Referenzierung und wenden geeignete Design-Patterns an.
Anforderungsanalyse und Schemaentwurf ist eine kostenlose MongoDB Academy-Lektion auf CoddyKit. Dies ist Lektion 1 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des MongoDB Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der MongoDB Academy-Kurs umfasst insgesamt 4 Lektionen.
Das Abschlussprojekt: Entwurf einer echten Anwendung
In dieser Abschlusslektion wenden Sie Ihr gesamtes Wissen aus dem MongoDB-Kurs an, um eine produktionsreife Anwendung von Grund auf zu entwerfen. Wir erstellen eine Multi-Vendor-E-Commerce-Plattform – eine Domäne, die umfangreich genug ist, um Entscheidungen zwischen Einbetten und Referenzieren, die Indexplanung, den Entwurf von Aggregationen und Sicherheitsaspekte zu behandeln. Der Prozess beginnt mit der Anforderungsanalyse, die alle nachfolgenden Schemaentscheidungen bestimmt.
Schritt 1: Funktionale Anforderungen erfassen
Beginnen Sie damit, die zentralen Entitäten und Vorgänge der Anwendung aufzulisten. Für unsere E-Commerce-Plattform sind dies: Entitäten – Users, Vendors, Products, Orders, Reviews, Carts; Vorgänge – Produkte nach Kategorie durchsuchen, nach Schlüsselwörtern suchen, Bestellungen aufgeben, Zahlungen verarbeiten, Lieferungen verfolgen und Bewertungen verfassen. Jeder Vorgang entspricht einer oder mehreren MongoDB-Abfragen, und diese Abfragen bestimmen die Schemaentscheidungen.
// Requirement analysis output (pseudocode spec)
const requirements = {
reads: [
'Get product by slug (very high frequency)',
'List products by category + sort/filter (high frequency)',
'Search products by keyword (high frequency)',
'Get order history for a user (medium frequency)',
'Get order detail (medium frequency)'
],
writes: [
'Create order (medium frequency)',
'Update order status (medium frequency)',
'Add product review (low frequency)',
'Update product inventory (high frequency)'
]
}Schritt 2: Zugriffsmuster identifizieren
Zugriffsmuster sind die konkreten Abfragen, die Ihre Anwendung ausführen wird. Dokumentieren Sie sie vor dem Entwurf des Schemas präzise – das Schema sollte den Abfragen dienen, nicht umgekehrt. Erfassen Sie für jedes Muster: die Filterfelder, Sortierfelder, projizierten Felder und die geschätzte Häufigkeit. Häufig verwendete Muster bestimmen die Indexierungs- und Einbettungsentscheidungen. Bei selten verwendeten Mustern kann der zusätzliche Aufwand durch Joins oder eine Aggregationspipeline akzeptabel sein.
// Access pattern register
const accessPatterns = [
{
name: 'Product page',
filter: { slug: 1 },
projection: 'all except internal fields',
frequency: 'very high',
decision: 'index on slug; embed top 5 reviews'
},
{
name: 'Category listing',
filter: { categoryId: 1, price: 1 },
sort: { price: 1, createdAt: -1 },
frequency: 'high',
decision: 'compound index { categoryId, price, createdAt }'
}
]Die Products-Collection entwerfen
Das Produktdokument wird im System am häufigsten gelesen. Wenden Sie die gelernten Muster an: Computed Pattern für vorab berechnete Statistiken (avgRating, reviewCount); Subset Pattern, um nur die fünf besten Bewertungen einzubetten; Extended Reference, um den Namen und das Logo des Anbieters neben vendorId einzubetten. Dadurch entfallen bei 95 % der Darstellungen von Produktseiten Joins.
// Product document schema (simplified)
{
_id: ObjectId(),
slug: 'wireless-headphones-pro',
name: 'Wireless Headphones Pro',
categoryId: ObjectId(),
vendor: {
_id: ObjectId(), // reference for updates
name: 'AudioTech Ltd', // Extended Reference
logoUrl: '...' // Extended Reference
},
price: 149.99,
stock: 234,
avgRating: 4.3, // Computed Pattern
reviewCount: 892, // Computed Pattern
topReviews: [ /* 5 most recent */ ], // Subset Pattern
tags: ['audio', 'wireless', 'headphones'],
schema_version: 1
}Die Orders-Collection entwerfen
Bestellungen sind ein klassischer Fall für ein Snapshot-Dokument: Sie halten den Stand von Preisen und Adressen zum Zeitpunkt des Kaufs fest, nicht den aktuellen Stand. Betten Sie die vollständige Lieferadresse ein (keine Referenz auf die aktuelle Adresse des Benutzers), ebenso den Produktschnappschuss (Name, Preis und Bild zum Kaufzeitpunkt) sowie den Namen des Anbieters. So bleiben Bestellungen korrekt, auch wenn sich Preise ändern oder Anbieter ihre Profile aktualisieren.
// Order document schema
{
_id: ObjectId(),
userId: ObjectId(),
status: 'processing', // 'pending', 'processing', 'shipped', 'delivered', 'refunded'
createdAt: new Date(),
shippingAddress: {
name: 'Alice Smith',
street: '42 Elm St',
city: 'Istanbul',
country: 'TR'
},
items: [
{
productId: ObjectId(), // reference for linking
slug: 'wireless-...',
name: 'Wireless Headphones Pro', // snapshot
price: 149.99, // price at purchase time
quantity: 1,
imageUrl: '...'
}
],
subtotal: 149.99,
tax: 27.00,
total: 176.99
}Das Entscheidungsframework für den Schemaentwurf anwenden
Wenden Sie für jede Beziehung die Entscheidungs-Checkliste an: Wie oft wird sie gemeinsam abgerufen? (Immer: einbetten, selten: referenzieren); Wie oft ändern sich die referenzierten Daten? (Selten: einbetten, häufig: referenzieren); Wird das eingebettete Array unbeschränkt wachsen? (Ja: referenzieren, begrenzt: einbetten); Wird nach den Daten unabhängig abgefragt? (Ja: separate Collection, immer über das übergeordnete Dokument abgerufen: einbetten).
// Decision table for our e-commerce schema
const decisions = [
{ entity: 'Order items', decision: 'embed', reason: 'always fetched with order; price snapshot required' },
{ entity: 'Shipping address', decision: 'embed', reason: 'snapshot at purchase time; changes do not affect order' },
{ entity: 'Product reviews', decision: 'separate + subset', reason: 'grows unbounded; top-5 subset in product doc' },
{ entity: 'Vendor details', decision: 'extended ref', reason: 'name/logo read on every product page; changes rarely' },
{ entity: 'Category tree', decision: 'separate', reason: 'queried independently; used for breadcrumbs' }
]Schema-Validierung für kritische Collections
Fügen Sie den Collections products und orders JSON-Schema-Validatoren hinzu, um zu verhindern, dass fehlerhaft formatierte Dokumente Ihre Daten beschädigen. Erzwingen Sie Pflichtfelder (price muss eine positive Zahl sein, status muss einem der gültigen Enum-Werte entsprechen) und setzen Sie validationAction: 'error', damit ungültige Schreibvorgänge sofort abgelehnt werden, statt nur eine Warnung auszugeben.
db.runCommand({
collMod: 'orders',
validator: {
$jsonSchema: {
bsonType: 'object',
required: ['userId', 'status', 'items', 'total', 'createdAt'],
properties: {
status: {
bsonType: 'string',
enum: ['pending', 'processing', 'shipped', 'delivered', 'refunded']
},
total: { bsonType: 'double', minimum: 0 },
items: { bsonType: 'array', minItems: 1 }
}
}
},
validationAction: 'error'
})Die Indexmenge planen
Definieren Sie für jedes häufig verwendete Zugriffsmuster Indizes. Verwenden Sie für zusammengesetzte Indizes die ESR-Regel (Equality → Sort → Range). Erstellen Sie Indizes nur für häufig ausgeführte Abfragen – ungenutzte Indizes beeinträchtigen die Schreibperformance und verbrauchen RAM. Dokumentieren Sie den Zweck jedes Index, damit das Team redundante Indizes entfernen kann, wenn sich die Zugriffsmuster weiterentwickeln.
// Products collection indexes
db.products.createIndex({ slug: 1 }, { unique: true }) // product page lookup
db.products.createIndex({ categoryId: 1, price: 1, _id: 1 }) // category listing + keyset pagination
db.products.createIndex({ tags: 1 }) // tag filter
db.products.createIndex({ 'vendor._id': 1 }) // vendor store page
// Orders collection indexes
db.orders.createIndex({ userId: 1, createdAt: -1 }) // user order history
db.orders.createIndex({ status: 1, createdAt: 1 }) // fulfillment queueGleichzeitige Bestandsaktualisierungen verarbeiten
Eine zentrale Herausforderung im E-Commerce ist das Verhindern von Überverkäufen: Zwei Benutzer dürfen nicht beide den letzten verfügbaren Artikel kaufen können. Verwenden Sie MongoDBs atomare Methode findOneAndUpdate mit der Prüfbedingung stock: { $gt: 0 }. Die Aktualisierung ist nur erfolgreich, wenn Bestand verfügbar ist, und die Verringerung erfolgt atomar – eine Race Condition ist somit ausgeschlossen.
// Atomically reserve stock — returns null if out of stock
const product = await db.collection('products').findOneAndUpdate(
{ _id: productId, stock: { $gte: quantity } }, // guard: enough stock
{ $inc: { stock: -quantity } },
{ returnDocument: 'after', projection: { stock: 1, name: 1, price: 1 } }
)
if (!product) {
throw new Error('Insufficient stock')
}
// Proceed to create order with product snapshotAggregationspipeline für Berichte
Entwerfen Sie eine Aggregationspipeline für eine Verkaufsübersicht, die den Umsatz pro Anbieter für die letzten 30 Tage ausgibt. Dies ist ein klassischer Fall, in dem die Aggregationspipeline eine komplexe Berechnung auf Anwendungsseite ersetzt. Die Pipeline filtert aktuelle Bestellungen, entpackt die Artikel, gruppiert nach Anbieter und sortiert nach dem Gesamtumsatz.
// Revenue by vendor, last 30 days
const since = new Date(Date.now() - 30 * 86400000)
db.orders.aggregate([
{ $match: { status: 'delivered', createdAt: { $gte: since } } },
{ $unwind: '$items' },
{
$group: {
_id: '$items.vendorId',
totalRevenue: { $sum: { $multiply: ['$items.price', '$items.quantity'] } },
orderCount: { $addToSet: '$_id' }
}
},
{ $addFields: { orderCount: { $size: '$orderCount' } } },
{ $sort: { totalRevenue: -1 } },
{ $limit: 20 }
])Das Schema mit explain() testen
Validieren Sie vor dem Übergang in die Produktion jede kritische Abfrage mit explain('executionStats'). Stellen Sie sicher, dass alle häufig verwendeten Abfragen im gewinnenden Plan IXSCAN (nicht COLLSCAN) anzeigen, dass docsExamined nahe an nReturned liegt und dass totalKeysExamined angemessen ist. Jede Abfrage mit COLLSCAN oder einem hohen Verhältnis von docsExamined zu nReturned benötigt einen Index.
// Validate the category listing query
const stats = db.products.find(
{ categoryId: ObjectId('...'), price: { $lte: 200 } }
).sort({ price: 1 }).explain('executionStats')
const plan = stats.executionStats
console.log('Stage:', plan.executionStages.inputStage.stage) // should be IXSCAN
console.log('Keys examined:', plan.totalKeysExamined) // should be small
console.log('Docs examined:', plan.totalDocsExamined) // should equal nReturned
console.log('Docs returned:', plan.nReturned)Schnelltest
Testen Sie Ihr Verständnis der Konzepte aus dieser Lektion zu MongoDB & NoSQL Databases.
Lektionsrückblick
In dieser Lektion haben Sie gelernt: Anforderungsanalyse und die Dokumentation von Zugriffsmustern kommen vor dem Schemaentwurf – das Schema dient den Abfragen, nicht umgekehrt; ein gutes Produktdokument kombiniert Extended Reference, Computed Pattern und Subset Pattern, um Joins im häufig genutzten Lesepfad zu vermeiden; und atomare Aufrufe von findOneAndUpdate mit Prüfbedingungen verhindern Überverkäufe, ohne Transaktionen zu benötigen. Als Nächstes definieren wir die Indexstrategie und validieren jeden Index mit explain().
Lerne JavaScript mit einem KI-Tutor — kostenlos
Schreibe und führe echten Code in deinem Browser aus, bekomme sofortige Hilfe von einem 24/7 KI-Tutor und setze dein Lernen im Web oder in der App fort.
- Kurse
- 30
- Lektionen
- 120
Häufig gestellte Fragen
Ist die Lektion „Anforderungsanalyse und Schemaentwurf“ kostenlos?
Ja — der vollständige Text von „Anforderungsanalyse und Schemaentwurf“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des MongoDB Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der MongoDB Academy-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „Anforderungsanalyse und Schemaentwurf“?
Lernende übertragen Anwendungsanforderungen in ein MongoDB-Schema, entscheiden zwischen Einbettung und Referenzierung und wenden geeignete Design-Patterns an. Du übst MongoDB Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um MongoDB Academy zu starten?
Keine Vorkenntnisse erforderlich. MongoDB Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 1 von 4.
Wie lange dauert die Lektion „Anforderungsanalyse und Schemaentwurf“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser MongoDB Academy-Lektion Code schreiben und ausführen?
Ja. Jede MongoDB Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- Anforderungsanalyse und Schemaentwurf
- Indexstrategie und Validierung des Abfrageplaners
- Skalierungsplan: Vom Replikatsatz zum Sharded Cluster
- Sicherheits-Härtung und Checkliste für den Produktivbetrieb