NoSQL 데이터베이스는 전통적인 관계형 데이터베이스(RDMBS)의 한계를 극복하고, 대규모 데이터 처리 및 다양한 데이터 구조를 효과적으로 관리하기 위해 개발된 비관계형 데이터베이스입니다. NoSQL은 "Not Only SQL"의 약자로 SQL을 완전히 배제하는 것이 아니라 보완하는 형태로 이해할 수 있습니다.
Redis / Amazon DynamoDB / Riak
ex)
캐싱 : 데이터베이스 조회 속도를 높이기 위해 자주 접근하는 데이터를 메모리에 저장
세션 관리 : 웹 애플리케이션의 사용자 세션 정보를 저장하고 관리
실시간 분석 : 빠른 데이터 입출력이 요구되는 실시간 데이터 처리
MongoDB / CouchDB/ RethinkDB
ex)
콘텐츠 관리 시스템 : 다양한 형태의 콘텐츠를 유연하게 저장하고 관리
전자상거래 플랫폼 : 제품 정보, 사용자 리뷰 등 다양한 데이터를 효율적으로 처리
로그 및 이벤트 데이터 저장 : 구조가 자주 변경되거나 다양한 형태의 로그 데이터를 저장
Apache Cassandra / HBase / ScyllaDB
ex)
시간 시리즈 데이터 저장 : IoT 센서 데이터, 주식 거래 데이터 등 시간에 따라 축적되는 데이터 저장.
추천 시스템 : 사용자 행동 데이터와 제품 정보를 대규모를 저장하고 분석
실시간 분석 및 보고 : 대규모 데이터를 실시간으로 처리하고 분석하여 비즈니스 인사이트 도출
Neo4j / Amazon Neptune / ArangoDB
ex)
소셜 네트워크 : 사용자 간의 친구 관계, 팔로우 관계 등을 효과적으로 저장하고 분석
추천 엔진 : 사용자 행동 데이터와 제품 간의 관계를 분석하여 개인화된 추천 제공.
사기 탐지 : 금융 거래 데이터에서 복잡한 패턴과 관계를 분석하여 사기 행위를 식별
지식 그래프 : 다양한 정보와 개념 간의 관계를 체계쩍으로 저장하고 검색
신입 및 취업 준비 중인 Java와 Spring 기반 백엔드 개발자로서 NoSQL 데이터베이스를 실습해보는 것은 현대 웹 애플리케이션 개발에 매우 유용한 경험이 될 것입니다. 다음은 각 NoSQL 데이터베이스 유형별로 실습할 만한 프로젝트와 학습 과정을 제안합니다. 이를 통해 이론을 실제로 적용하고, 다양한 데이터베이스의 특징을 이해하며, Java와 Spring과의 통합 방법을 익힐 수 있습니다.
추천 데이터베이스: Redis
실습 프로젝트: 사용자 세션 관리 시스템
프로젝트 개요:
웹 애플리케이션에서 사용자 세션을 관리하는 시스템을 구축합니다. Redis를 사용하여 세션 데이터를 저장하고, Spring과 연동하여 사용자 로그인, 로그아웃 기능을 구현합니다.
실습 단계:
Redis 설치 및 설정:
Spring 프로젝트 설정:
Spring Boot 프로젝트를 생성하고, spring-boot-starter-data-redis
의존성을 추가합니다.
application.properties
파일에 Redis 연결 설정을 추가합니다.
spring.redis.host=localhost
spring.redis.port=6379
세션 관리 구현:
사용자 로그인 시, Redis에 세션 데이터를 저장합니다.
로그인 API와 로그아웃 API를 구현하고, 각 API에서 Redis를 이용하여 세션 데이터를 관리합니다.
@RestController
public class AuthController {
@Autowired
private StringRedisTemplate redisTemplate;
@PostMapping("/login")
public ResponseEntity<String> login(@RequestBody UserCredentials credentials) {
// 인증 로직 (예: username과 password 확인)
String sessionId = UUID.randomUUID().toString();
redisTemplate.opsForValue().set(sessionId, credentials.getUsername(), 30, TimeUnit.MINUTES);
return ResponseEntity.ok(sessionId);
}
@PostMapping("/logout")
public ResponseEntity<String> logout(@RequestHeader("Session-Id") String sessionId) {
redisTemplate.delete(sessionId);
return ResponseEntity.ok("Logged out successfully");
}
}
테스트 및 검증:
확장 가능성:
추천 데이터베이스: MongoDB
실습 프로젝트: 블로그 관리 시스템
프로젝트 개요:
블로그 포스트와 사용자 데이터를 MongoDB에 저장하는 간단한 블로그 관리 시스템을 구축합니다. Spring Data MongoDB를 사용하여 데이터베이스와의 상호작용을 구현합니다.
실습 단계:
MongoDB 설치 및 설정:
Spring 프로젝트 설정:
Spring Boot 프로젝트를 생성하고, spring-boot-starter-data-mongodb
의존성을 추가합니다.
application.properties
파일에 MongoDB 연결 설정을 추가합니다.
spring.data.mongodb.uri=mongodb://localhost:27017/blogdb
도메인 모델 정의:
User
와 Post
엔티티를 정의합니다.
@Document(collection = "users")
public class User {
@Id
private String id;
private String username;
private String email;
// getters and setters
}
@Document(collection = "posts")
public class Post {
@Id
private String id;
private String title;
private String content;
private String authorId;
private Date createdAt;
// getters and setters
}
레포지토리 인터페이스 생성:
UserRepository
와 PostRepository
를 생성합니다.
public interface UserRepository extends MongoRepository<User, String> {
Optional<User> findByUsername(String username);
}
public interface PostRepository extends MongoRepository<Post, String> {
List<Post> findByAuthorId(String authorId);
}
CRUD API 구현:
사용자 등록, 포스트 작성, 포스트 조회 등의 API를 구현합니다.
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private UserRepository userRepository;
@PostMapping("/register")
public ResponseEntity<User> register(@RequestBody User user) {
User savedUser = userRepository.save(user);
return ResponseEntity.ok(savedUser);
}
// 추가적인 사용자 관련 API
}
@RestController
@RequestMapping("/posts")
public class PostController {
@Autowired
private PostRepository postRepository;
@PostMapping("/create")
public ResponseEntity<Post> createPost(@RequestBody Post post) {
post.setCreatedAt(new Date());
Post savedPost = postRepository.save(post);
return ResponseEntity.ok(savedPost);
}
@GetMapping("/author/{authorId}")
public ResponseEntity<List<Post>> getPostsByAuthor(@PathVariable String authorId) {
List<Post> posts = postRepository.findByAuthorId(authorId);
return ResponseEntity.ok(posts);
}
// 추가적인 포스트 관련 API
}
테스트 및 검증:
확장 가능성:
추천 데이터베이스: Apache Cassandra
실습 프로젝트: 실시간 주식 거래 데이터 분석 시스템
프로젝트 개요:
실시간 주식 거래 데이터를 Cassandra에 저장하고, Java와 Spring을 사용하여 데이터의 삽입 및 조회를 구현합니다. 주식 거래 기록을 효율적으로 저장하고, 특정 주식의 거래 내역을 빠르게 조회할 수 있도록 합니다.
실습 단계:
Cassandra 설치 및 설정:
cqlsh
를 사용하여 Cassandra 클러스터에 접속합니다.키스페이스 및 테이블 생성:
주식 거래 데이터를 저장할 키스페이스와 테이블을 생성합니다.
CREATE KEYSPACE stockdb WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1};
USE stockdb;
CREATE TABLE trades (
stock_symbol text,
trade_time timestamp,
trade_id uuid,
quantity int,
price double,
PRIMARY KEY (stock_symbol, trade_time)
) WITH CLUSTERING ORDER BY (trade_time DESC);
Spring 프로젝트 설정:
Spring Boot 프로젝트를 생성하고, spring-boot-starter-data-cassandra
의존성을 추가합니다.
application.properties
파일에 Cassandra 연결 설정을 추가합니다.
spring.data.cassandra.contact-points=127.0.0.1
spring.data.cassandra.port=9042
spring.data.cassandra.keyspace-name=stockdb
spring.data.cassandra.schema-action=create_if_not_exists
도메인 모델 정의:
Trade
엔티티를 정의합니다.
@Table("trades")
public class Trade {
@PrimaryKey
private TradeKey key;
private int quantity;
private double price;
// getters and setters
}
public class TradeKey {
@PrimaryKeyColumn(name = "stock_symbol", ordinal = 0, type = PrimaryKeyType.PARTITIONED)
private String stockSymbol;
@PrimaryKeyColumn(name = "trade_time", ordinal = 1, type = PrimaryKeyType.CLUSTERED)
private Date tradeTime;
// getters and setters
}
레포지토리 인터페이스 생성:
TradeRepository
를 생성합니다.
public interface TradeRepository extends CassandraRepository<Trade, TradeKey> {
List<Trade> findByKeyStockSymbol(String stockSymbol);
}
데이터 삽입 및 조회 API 구현:
실시간 주식 거래 데이터를 삽입하고, 특정 주식의 거래 내역을 조회하는 API를 구현합니다.
@RestController
@RequestMapping("/trades")
public class TradeController {
@Autowired
private TradeRepository tradeRepository;
@PostMapping("/add")
public ResponseEntity<Trade> addTrade(@RequestBody Trade trade) {
trade.setKey(new TradeKey(trade.getKey().getStockSymbol(), new Date()));
Trade savedTrade = tradeRepository.save(trade);
return ResponseEntity.ok(savedTrade);
}
@GetMapping("/symbol/{symbol}")
public ResponseEntity<List<Trade>> getTradesBySymbol(@PathVariable String symbol) {
List<Trade> trades = tradeRepository.findByKeyStockSymbol(symbol);
return ResponseEntity.ok(trades);
}
}
테스트 및 검증:
cqlsh
또는 Cassandra 클라이언트 툴을 통해 데이터가 올바르게 저장되었는지 확인합니다.확장 가능성:
추천 데이터베이스: Neo4j
실습 프로젝트: 소셜 네트워크 분석 시스템
프로젝트 개요:
사용자 간의 친구 관계를 관리하고, 친구 추천 기능을 구현하는 소셜 네트워크 분석 시스템을 구축합니다. Neo4j를 사용하여 사용자 간의 관계를 그래프로 저장하고, Spring과 연동하여 데이터를 관리합니다.
실습 단계:
Neo4j 설치 및 설정:
Spring 프로젝트 설정:
Spring Boot 프로젝트를 생성하고, spring-boot-starter-data-neo4j
의존성을 추가합니다.
application.properties
파일에 Neo4j 연결 설정을 추가합니다.
spring.neo4j.uri=bolt://localhost:7687
spring.neo4j.authentication.username=neo4j
spring.neo4j.authentication.password=your_password
도메인 모델 정의:
User
엔티티와 FRIEND
관계를 정의합니다.
@Node
public class User {
@Id @GeneratedValue
private Long id;
private String name;
private String email;
@Relationship(type = "FRIEND", direction = Relationship.Direction.UNDIRECTED)
private Set<User> friends = new HashSet<>();
// getters and setters
}
레포지토리 인터페이스 생성:
UserRepository
를 생성합니다.
public interface UserRepository extends Neo4jRepository<User, Long> {
Optional<User> findByEmail(String email);
}
CRUD 및 관계 관리 API 구현:
사용자 등록, 친구 추가, 친구 추천 기능을 구현합니다.
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private UserRepository userRepository;
@PostMapping("/register")
public ResponseEntity<User> registerUser(@RequestBody User user) {
User savedUser = userRepository.save(user);
return ResponseEntity.ok(savedUser);
}
@PostMapping("/{id}/add-friend/{friendId}")
public ResponseEntity<String> addFriend(@PathVariable Long id, @PathVariable Long friendId) {
Optional<User> userOpt = userRepository.findById(id);
Optional<User> friendOpt = userRepository.findById(friendId);
if(userOpt.isPresent() && friendOpt.isPresent()) {
User user = userOpt.get();
User friend = friendOpt.get();
user.getFriends().add(friend);
userRepository.save(user);
return ResponseEntity.ok("Friend added successfully");
}
return ResponseEntity.status(HttpStatus.NOT_FOUND).body("User not found");
}
@GetMapping("/recommend/{id}")
public ResponseEntity<List<User>> recommendFriends(@PathVariable Long id) {
// 간단한 친구 추천 로직: 친구의 친구 중 아직 친구가 아닌 사용자 추천
String cypherQuery = "MATCH (u:User)-[:FRIEND]->(f:User)-[:FRIEND]->(fof:User) " +
"WHERE u.id = $id AND NOT (u)-[:FRIEND]->(fof) " +
"RETURN fof LIMIT 10";
Map<String, Object> params = new HashMap<>();
params.put("id", id);
List<User> recommendations = userRepository.getSession()
.run(cypherQuery, params)
.list(record -> new User(
record.get("fof").get("name").asString(),
record.get("fof").get("email").asString()
));
return ResponseEntity.ok(recommendations);
}
}
테스트 및 검증:
확장 가능성:
공식 문서 및 튜토리얼:
온라인 강의 및 코스:
실습 환경 구축 도구:
Docker: 다양한 NoSQL 데이터베이스를 컨테이너로 쉽게 실행할 수 있습니다.
Docker Compose: 여러 데이터베이스를 동시에 실행하고 네트워크를 설정할 수 있습니다.
version: '3.8'
services:
redis:
image: redis:latest
ports:
- "6379:6379"
mongodb:
image: mongo:latest
ports:
- "27017:27017"
cassandra:
image: cassandra:latest
ports:
- "9042:9042"
neo4j:
image: neo4j:latest
ports:
- "7474:7474"
- "7687:7687"
environment:
- NEO4J_AUTH=neo4j/password
버전 관리 및 협업:
이러한 실습 프로젝트를 통해 NoSQL 데이터베이스의 다양한 유형을 직접 다뤄보며, Java와 Spring을 활용한 백엔드 개발 역량을 크게 향상시킬 수 있을 것입니다. 성공적인 실습과 학습을 기원합니다!