비정규화 전략
쿼리 복잡성을 줄이고 속도를 높이는 평면 데이터 구조를 만들기 위해 비정규화 기법을 적용합니다.
비정규화 전략은(는) CoddyKit의 무료 Spring Boot 4 Microservices & REST APIs 강의입니다. 이것은 9개 중 6번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Spring Boot 4 Microservices & REST APIs 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Spring Boot 4 Microservices & REST APIs 강의에는 총 9개의 강의가 포함되어 있습니다.
이 강의의 일부는 아직 번역되지 않았으며 영어로 표시됩니다.
What is Denormalization?
In traditional relational databases, we "normalize" data to avoid redundancy. But NoSQL databases like Firebase Realtime Database often benefit from the opposite: denormalization.
Denormalization involves intentionally adding redundant data or grouping data to optimize read performance. It's a key strategy for speed in NoSQL.
Why Firebase Needs Denormalization
Firebase Realtime Database excels at real-time updates and quick reads. However, complex queries across multiple data paths can be slow and costly.
- Flat Structures: Firebase works best with flat data structures.
- Reduced Reads: Denormalization can reduce the number of reads needed for common queries.
- Query Limitations: NoSQL databases have limited querying capabilities compared to SQL.
Popular Denormalization Patterns
There are several ways to denormalize your data. Two common patterns are:
- Duplication: Storing the same piece of data in multiple locations.
- Aggregation: Storing pre-calculated summaries or counts.
- Fan-out: Writing data to multiple paths simultaneously (often used with duplication).
We'll focus on the first two in detail.
Example: Duplicating User Data
Imagine a social app where users post messages. Each post needs to display the author's name.
Instead of fetching the user's profile every time you display a post, you can duplicate the user's name directly into the post object when it's created. This makes displaying posts much faster.
// Original structure (normalized)
posts: {
postId1: {
text: "My first post!",
authorId: "userId123"
}
},
users: {
userId123: {
name: "Alice"
}
}
// Denormalized structure
posts: {
postId1: {
text: "My first post!",
authorId: "userId123",
authorName: "Alice" // Duplicated!
}
}Implementing Data Duplication
Here's how you might write data to include duplicated user information. When a user posts, we add their name directly to the post object.
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.DatabaseReference;
import java.util.HashMap;
import java.util.Map;
public class Main {
public static void main(String[] args) {
// This is a placeholder for Firebase initialization.
// In a real app, you'd initialize Firebase first.
// FirebaseApp.initializeApp(options);
// Get a reference to the database
// DatabaseReference dbRef = FirebaseDatabase.getInstance().getReference();
// Mocking database operations for demonstration
System.out.println("Simulating Firebase data write...");
String userId = "user123";
String userName = "Bob Smith";
String postId = "post456";
String postText = "Enjoying CoddyKit lessons!";
// Data for the post
Map<String, Object> postData = new HashMap<>();
postData.put("text", postText);
postData.put("authorId", userId);
postData.put("authorName", userName); // Duplicated user name
// Simulate writing to posts node
// dbRef.child("posts").child(postId).setValue(postData);
System.out.println("Writing post " + postId + " with authorName: " + userName);
System.out.println("Post Data: " + postData);
// In a real app, you'd also update the user's name if it changes
// which requires more advanced logic (e.g., Cloud Functions).
}
}Example: Aggregating Data
Another common denormalization technique is to store aggregated data, like counts or sums, directly on a parent object.
For instance, if you have a blog post and want to quickly show the number of comments, you can store a commentCount property on the post itself. This avoids fetching all comments just to count them.
// Without aggregation
posts: {
postId1: {
title: "My Blog Post"
}
},
comments: {
commentId1: { postId: "postId1", text: "..." },
commentId2: { postId: "postId1", text: "..." }
}
// With aggregation
posts: {
postId1: {
title: "My Blog Post",
commentCount: 2 // Aggregated!
}
}Implementing Count Aggregation
When a new comment is added, we can increment a counter on the parent post. This ensures the count is always up-to-date and easily accessible.
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.ServerValue;
import java.util.HashMap;
import java.util.Map;
public class Main {
public static void main(String[] args) {
// Placeholder for Firebase initialization
System.out.println("Simulating Firebase data write with aggregation...");
String postId = "blogPost1";
String commentId = "commentABC";
String commentText = "Great article!";
String authorId = "user789";
// Simulate writing a new comment
Map<String, Object> commentData = new HashMap<>();
commentData.put("postId", postId);
commentData.put("text", commentText);
commentData.put("authorId", authorId);
// dbRef.child("comments").child(commentId).setValue(commentData);
System.out.println("Writing comment " + commentId);
// Simulate incrementing the comment count on the post
// This uses ServerValue.increment() for atomic operations in a real app
// dbRef.child("posts").child(postId).child("commentCount").setValue(ServerValue.increment(1));
System.out.println("Incrementing commentCount for post " + postId);
System.out.println("New comment added and count updated.");
}
}When Denormalization Helps
Denormalization is a powerful tool, but it's not always the answer. Consider it when:
- Read Performance is Critical: You need to display data quickly and frequently.
- Queries are Complex: Your app often needs to fetch related data that lives in different paths.
- Data Changes Infrequently: The duplicated or aggregated data doesn't change often.
Always weigh the benefits against the complexity.
Managing Denormalized Data
The main challenge with denormalization is maintaining data consistency. If you duplicate a user's name, and they change it, you need to update it in all duplicated locations.
- Increased Write Complexity: More writes are needed to keep data in sync.
- Potential for Inconsistency: If an update fails, data can become out of sync.
- Cloud Functions: Firebase Cloud Functions are often used to automate consistency for denormalized data.
Denormalization Benefits
You're building a social feed where each post needs to display the author's username and their profile picture thumbnail. The username and thumbnail are stored in the users collection. Posts are in the posts collection.
Which denormalization strategy would be most beneficial for quickly loading the feed?
Denormalization Summary
We've learned that denormalization is a key technique for optimizing read performance in Firebase Realtime Database by intentionally adding redundant or aggregated data.
- It helps create flatter data structures.
- Common patterns include duplication and aggregation.
- It speeds up reads but adds complexity to writes and requires careful consistency management, often with Cloud Functions.
Consider your most frequent read patterns when deciding where and how to denormalize.
AI 튜터와 함께 Java을(를) 배우세요 — 무료
브라우저에서 실제 코드를 작성하고 실행하며, 24/7 AI 튜터로부터 즉각적인 도움을 받고, 웹이나 앱에서 중단한 부분부터 계속 학습하세요.
- 코스
- 24
- 레슨
- 93
자주 묻는 질문
“비정규화 전략” 강의는 무료인가요?
네 — “비정규화 전략” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Spring Boot 4 Microservices & REST APIs 강의 전체를 잠금 해제할 수 있습니다. Spring Boot 4 Microservices & REST APIs 강의에는 총 9개의 강의가 포함되어 있습니다.
“비정규화 전략”에서 뭘 배우나요?
쿼리 복잡성을 줄이고 속도를 높이는 평면 데이터 구조를 만들기 위해 비정규화 기법을 적용합니다. 브라우저에서 직접 실행하는 실습 코드로 Spring Boot 4 Microservices & REST APIs을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
Spring Boot 4 Microservices & REST APIs을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 Spring Boot 4 Microservices & REST APIs은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 9개 중 6번째 강의입니다.
“비정규화 전략” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 Spring Boot 4 Microservices & REST APIs 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 Spring Boot 4 Microservices & REST APIs 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- 메시지 처리량 최적화
- WebFlux를 사용한 비동기 처리
- 데이터 구조 최적화
- 소비자 및 생산자 확장
- 마이크로서비스 캐싱 전략
- 비정규화 전략
- 데이터베이스 샤딩 및 복제
- 데이터베이스 모니터링 및 디버깅
- RabbitMQ 성능 벤치마킹