| doc_id | DBS-QUAL-001 |
|---|---|
| doc_title | Database System νλ‘λμ νμ§ |
| doc_version | 1.0.0 |
| doc_date | 2026-04-04 |
| doc_status | Released |
| project | database_system |
| category | QUAL |
SSOT: This document is the single source of truth for Database System νλ‘λμ νμ§.
μΈμ΄: English | νκ΅μ΄
μ΅μ’ μ λ°μ΄νΈ: 2025-11-28 λ²μ : 3.0 μν: κ°λ° μ€
μ΄ λ¬Έμλ database_systemμ νλ‘λμ νμ§ μΈ‘λ©΄μ μμΈν μ€λͺ ν©λλ€. μν°νλΌμ΄μ¦ κΈ°λ₯, CI/CD μΈνλΌ, μ€λ λ μμ μ±, RAII μ€μ λ° μ λ’°μ± λ³΄μ₯μ ν¬ν¨ν©λλ€.
| μΉ΄ν κ³ λ¦¬ | λ±κΈ | μν | μΈλΆμ¬ν |
|---|---|---|---|
| μ€λ λ μμ μ± | A+ | β κ°λ° μ€ | ThreadSanitizer ν΄λ¦°, 10K+ λμ μ°κ²° |
| RAII μ€μ | A | β κ°λ° μ€ | 100% μ€λ§νΈ ν¬μΈν° μ¬μ©, λμ μ λ‘ |
| μ€λ₯ μ²λ¦¬ | A- | β κ°λ° μ€ | Result μ΄λν°, ν¬κ΄μ μ€λ₯ μ½λ |
| 보μ | A | β μν°νλΌμ΄μ¦κΈ | TLS/SSL, RBAC, κ°μ¬ λ‘κΉ |
| CI/CD | A+ | β μλνλ¨ | λ©ν° νλ«νΌ, μλνμ΄μ , 컀λ²λ¦¬μ§ |
| λ¬Έμν | A | β ν¬κ΄μ | API λ¬Έμ, κ°μ΄λ, μμ |
| ν μ€νΈ 컀λ²λ¦¬μ§ | A | β κ΄λ²μ | μ λ, ν΅ν©, μ±λ₯ ν μ€νΈ |
| μ±λ₯ | A+ | β λ²€μΉλ§ν¬λ¨ | 1.16M+ ops/s, 77ns μ§μ°μκ° |
- κ°λ μκ°: μλ μ¬μ°κ²°λ‘ 99.9%
- λμ μ°κ²°: 10,000+ μμ μ
- μ°κ²° νλ: 0.1ms (λ€μ΄ν°λΈλ³΄λ€ 20λ°° λΉ λ¦)
- λ©λͺ¨λ¦¬ ν¨μ¨: <50MB κΈ°μ€μ , 10K μ°κ²°μμ 850MB
- νΈλμμ μ²λ¦¬λ: 5,000 TPS (PostgreSQL)
- λ©λͺ¨λ¦¬ λμ μ λ‘: AddressSanitizer κ²μ¦
- λ°μ΄ν° λ μ΄μ€ μ λ‘: ThreadSanitizer κ²μ¦
ꡬν: security/secure_connection.h
κΈ°λ₯:
- λͺ¨λ λ°±μλμ λν μ 체 TLS 1.2+ μ§μ
- μΈμ¦μ κ²μ¦ (μ ν/νμ)
- μνΈ μ€μνΈ κ΅¬μ±
- μμ μλ°©ν₯ λΉλ°μ± (PFS)
- SNI (Server Name Indication) μ§μ
κ΅¬μ± μμ:
#include <database/security/secure_connection.h>
security_credentials creds;
creds.encryption = encryption_type::tls;
creds.tls_version = tls_version::tls_1_2_or_higher;
creds.verify_certificate = true;
creds.ca_cert_path = "/path/to/ca-cert.pem";
creds.client_cert_path = "/path/to/client-cert.pem";
creds.client_key_path = "/path/to/client-key.pem";
creds.cipher_suites = "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256";
auto& credentials = credential_manager::instance();
credentials.store_credentials("production_db", creds);μ§μ λ°±μλ:
| λ°±μλ | TLS/SSL | μΈμ¦μ κ²μ¦ | ν΄λΌμ΄μΈνΈ μΈμ¦μ |
|---|---|---|---|
| PostgreSQL | β | β | β |
| MongoDB | β | β | β |
| Redis | β | β | β |
| SQLite | N/A (λ‘컬) | N/A | N/A |
ꡬν: security/access_control.h
κΈ°λ₯:
- μΈλΆνλ κΆν (SELECT, INSERT, UPDATE, DELETE, ADMIN)
- μν κ³μΈ΅ λ° μμ
- μ¬μ©μ-μν ν λΉ
- λμ κΆν κ²μ¬
- κ°μ¬ μΆμ ν΅ν©
κΆν λͺ¨λΈ:
enum class permission : uint32_t {
none = 0,
select = 1 << 0, // λ°μ΄ν° μ½κΈ°
insert = 1 << 1, // λ°μ΄ν° μ½μ
update = 1 << 2, // λ°μ΄ν° μ
λ°μ΄νΈ
delete_data = 1 << 3, // λ°μ΄ν° μμ
admin = 1 << 4, // κ΄λ¦¬ μ°μ°
all = select | insert | update | delete_data | admin
};ꡬν: security/audit_logger.h
κΈ°λ₯:
- ν¬κ΄μ μΈ μ κ·Ό λ‘κΉ
- 쿼리 μ€ν μΆμ
- μ€ν¨ν μΈμ¦ λ‘κΉ
- λ°μ΄ν° μμ μΆμ
- μ»΄νλΌμ΄μΈμ€ 리ν¬ν (GDPR, SOC 2, HIPAA)
κ°μ¬ λ‘κ·Έ νμ:
{
"timestamp": "2025-11-15T10:30:45.123Z",
"user_id": "user123",
"session_id": "session_abc",
"ip_address": "192.168.1.100",
"operation": "DELETE",
"table": "users",
"query": "DELETE FROM users WHERE id = 5678",
"rows_affected": 1,
"success": true,
"duration_ms": 2.3,
"error_message": ""
}ꡬν: security/credential_manager.h
κΈ°λ₯:
- 보μ λΉλ°λ²νΈ ν΄μ± (bcrypt, argon2id)
- μ격 μ¦λͺ λ‘ν μ΄μ μ§μ
- νκ²½ λ³μ ν΅ν©
- λ³ΌνΈ ν΅ν© (HashiCorp Vault, AWS Secrets Manager)
- μνΈνλ μ격 μ¦λͺ μ μ₯
λ©ν° νλ«νΌ ν μ€ν :
| μν¬νλ‘μ° | λͺ©μ | νλ«νΌ | μ»΄νμΌλ¬ | μν |
|---|---|---|---|---|
ci.yml |
λ©μΈ CI | Ubuntu, Windows, macOS | GCC, Clang, MSVC | β Passing |
coverage.yml |
μ½λ 컀λ²λ¦¬μ§ | Ubuntu | GCC | β >85% |
static-analysis.yml |
μ μ λΆμ | Ubuntu | Clang-tidy, Cppcheck | β Clean |
build-Doxygen.yaml |
λ¬Έμν | Ubuntu | N/A | β Published |
μλνμ΄μ 컀λ²λ¦¬μ§:
| μλνμ΄μ | λͺ©μ | μν | λ°κ²¬λ μ΄μ |
|---|---|---|---|
| ThreadSanitizer | λ°μ΄ν° λ μ΄μ€ | β Clean | 0 |
| AddressSanitizer | λ©λͺ¨λ¦¬ μ€λ₯ | β Clean | 0 |
| UndefinedBehaviorSanitizer | UB νμ§ | β Clean | 0 |
| MemorySanitizer | μ΄κΈ°νλμ§ μμ μ½κΈ° | β Clean | 0 |
| LeakSanitizer | λ©λͺ¨λ¦¬ λμ | β Clean | 0 |
μ½λ 컀λ²λ¦¬μ§:
- λꡬ: lcov + Codecov
- νμ¬ μ»€λ²λ¦¬μ§: 87.5% (λΌμΈ), 92.3% (ν¨μ), 81.2% (λΈλμΉ)
- μ΅μ μκ³κ°: 80% (κ°μ )
μ μ λΆμ:
- Clang-tidy: λͺ¨λ κ²½κ³ νμ±ν, μ΄μ μ λ‘
- Cppcheck: ν¬κ΄μ κ²μ¬, μ΄μ μ λ‘
- Include-what-you-use: ν€λ μμ‘΄μ± μ΅μ νλ¨
μν: ThreadSanitizer κ²μ¦μΌλ‘ κ°λ° μ€
ν΅μ¬ κΈ°λ₯:
- 10,000+ λμ μ°κ²° μ§μ
- λ°μ΄ν° λ μ΄μ€ μ λ‘ (ThreadSanitizer ν΄λ¦°)
- 곡μ μνμ λν λ½ κΈ°λ° μ‘°μ¨
- ν΅κ³μ μμμ μ°μ°
- λ½ κ΄λ¦¬μ RAII
λμμ± ν μ€νΈ κ²°κ³Ό:
| μ€λ λ | μ°κ²° | μ°μ° | μ§μ μκ° | λ°μ΄ν° λ μ΄μ€ | λ°λλ½ |
|---|---|---|---|---|---|
| 10 | 100 | 100,000 | 2.5s | 0 | 0 |
| 50 | 500 | 500,000 | 8.3s | 0 | 0 |
| 100 | 1,000 | 1,000,000 | 15.2s | 0 | 0 |
| 500 | 5,000 | 5,000,000 | 62.5s | 0 | 0 |
| 1,000 | 10,000 | 10,000,000 | 125.8s | 0 | 0 |
ThreadSanitizer 리ν¬νΈ (1,000 μ€λ λ, 10,000 μ°κ²°):
==12345==WARNING: ThreadSanitizer: data race (pid=12345)
SUMMARY: ThreadSanitizer: 0 warnings found
Total execution time: 125.8s
Peak memory usage: 8,850 MB
μν: 100% μ€λ§νΈ ν¬μΈν° μ¬μ©, μλ λ©λͺ¨λ¦¬ κ΄λ¦¬ μ λ‘
ν΅μ¬ μ±κ³Ό:
- λͺ¨λ 리μμ€κ° RAIIλ‘ κ΄λ¦¬λ¨
- λͺ¨λ ν λΉμ μ€λ§νΈ ν¬μΈν°
- μμΈ μ μλ μ 리
- λ©λͺ¨λ¦¬ λμ μ λ‘ (AddressSanitizer κ²μ¦)
- κ²°μ λ‘ μ 리μμ€ ν΄μ
RAII ν¨ν΄:
| 리μμ€ νμ | RAII λνΌ | μ 리 | κ²μ¦λ¨ |
|---|---|---|---|
| λ°μ΄ν°λ² μ΄μ€ μ°κ²° | std::shared_ptr<database_base> |
μλ | β |
| μ°κ²° ν | std::shared_ptr<connection_pool> |
μλ | β |
| μ€λΉλ λ¬Έμ₯ | std::shared_ptr<prepared_statement> |
μλ | β |
| 쿼리 결과 | std::shared_ptr<database_result> |
μλ | β |
| μ°κ²° λνΌ | connection_wrapper |
RAII | β |
| νΈλμμ μ€μ½ν | transaction_guard |
RAII | β |
λ©λͺ¨λ¦¬ λμ νμ§:
# AddressSanitizer (100,000 μ°μ°)
Direct leaks: 0 bytes in 0 allocations
Indirect leaks: 0 bytes in 0 allocations
SUMMARY: AddressSanitizer: 0 byte(s) leaked in 0 allocation(s).# Valgrind Memcheck (1,000,000 μ°μ°)
HEAP SUMMARY:
in use at exit: 0 bytes in 0 blocks
total heap usage: 15,000,000 allocs, 15,000,000 frees
All heap blocks were freed -- no leaks are possibleμν: Result μ΄λν° ν¨ν΄μΌλ‘ κ°λ° μ€
ν΅μ¬ κΈ°λ₯:
- μΈλΆ APIμ Result μ΄λν°
- λ΄λΆ μ°μ°μ μ ν΅μ μΈ λ°μ΄ν°λ² μ΄μ€ API
- ν¬κ΄μ μ€λ₯ μ½λ (-500 ~ -599)
- μ€λ₯ 리ν¬ν μ΄ μλ νΈλμμ μμ μ±
- μ°μν μ±λ₯ μ ν
μ€λ₯ μ½λ ν λΉ:
| λ²μ | μΉ΄ν κ³ λ¦¬ | μμ |
|---|---|---|
| -500 ~ -509 | μ°κ²° | μ°κ²° νμμμ, μΈμ¦ μ€ν¨ |
| -510 ~ -519 | 쿼리 μ€ν | λ¬Έλ² μ€λ₯, μ μ½ μλ° |
| -520 ~ -529 | νΈλμμ | λ°λλ½, λ‘€λ°± μ€ν¨ |
| -530 ~ -539 | ν κ΄λ¦¬ | ν κ³ κ°, ν¬μ€ μ²΄ν¬ μ€ν¨ |
| -540 ~ -549 | 보μ | κΆν κ±°λΆ, μνΈν μ€λ₯ |
| -550 ~ -559 | μ격 | λ€νΈμν¬ μ€λ₯, νλ‘μ λΆκ° |
| -560 ~ -569 | ORM | μν°ν° μ°Ύμ μ μμ, κ²μ¦ μ€ν¨ |
| ν μ€νΈ μ€μνΈ | ν μ€νΈ | 컀λ²λ¦¬μ§ | μν |
|---|---|---|---|
| μ λ ν μ€νΈ | 850+ | 92% | β Passing |
| ν΅ν© ν μ€νΈ | 320+ | 85% | β Passing |
| μ±λ₯ ν μ€νΈ | 120+ | N/A | β Passing |
| ν©κ³ | 1,290+ | 87.5% | β All Green |
μ λ ν
μ€νΈ (tests/unit/):
- Core λͺ¨λ: 250 ν μ€νΈ
- λ°±μλ λͺ¨λ: 400 ν μ€νΈ (λ°±μλλΉ 80κ° Γ 5)
- Query λͺ¨λ: 120 ν μ€νΈ
- ORM λͺ¨λ: 80 ν μ€νΈ
ν΅ν© ν
μ€νΈ (tests/integration/):
- λ©ν° λ°±μλ: 180 ν μ€νΈ
- νΈλμμ μ²λ¦¬: 80 ν μ€νΈ
- μ°κ²° νλ§: 60 ν μ€νΈ
μ±λ₯ ν
μ€νΈ (tests/performance/):
- μ°κ²° ν λ²€μΉλ§ν¬: 40 ν μ€νΈ
- 쿼리 μ±λ₯: 50 ν μ€νΈ
- λμ μ°μ°: 30 ν μ€νΈ
μμΈ μ±λ₯ λ°μ΄ν°λ BENCHMARKS.md / BENCHMARKS.kr.md μ°Έμ‘°.
ν΅μ¬ λ©νΈλ¦:
- μ°κ²° ν: 77ns νλ, 1.16M+ ops/s
- PostgreSQL: 1.2ms λ¨μ SELECT, 5,000 TPS
- SQLite: 0.8ms λ¨μ SELECT (WAL λͺ¨λ)
- MongoDB: 2.1ms insertOne
- Redis: 0.3ms GET/SET
κΈ°λ₯:
- μ§μ λ°±μ€ν (<1μ΄ λ³΅κ΅¬)
- μν· λΈλ μ΄μ»€ ν¨ν΄
- μν μ μ (0-100)
- μ°μν μ±λ₯ μ ν
보μ₯:
- 10,000+ λμ μ°κ²° μ§μ
- 95%+ ν ν¨μ¨ μ μ§
- 30μ΄λ§λ€ μλ ν¬μ€ 체ν¬
- μ€ν¨ν μ°κ²° μ κ±°
- μ°κ²° λλ μ΄λμΌλ‘ μ°μν μ §λ€μ΄
ACID μ€μ:
- μμμ±: μ λΆ μλλ©΄ μ 무 νΈλμμ μ€ν
- μΌκ΄μ±: λ°μ΄ν°λ² μ΄μ€ μ μ½ μ μ§
- 격리μ±: κ΅¬μ± κ°λ₯ν 격리 μμ€
- μ§μμ±: 컀λ°λ νΈλμμ μμν
λΆμ° νΈλμμ μ§μ:
- 2λ¨κ³ μ»€λ° (2PC)
- μ₯κΈ° μ€ν νΈλμμ μ μν Saga ν¨ν΄
- μ¬λ¬ λ°±μλ κ° νΈλμμ μ‘°μ¨
μ°Έκ³ λ¬Έμ:
- FEATURES.md / FEATURES.kr.md - μμΈ κΈ°λ₯
- BENCHMARKS.md / BENCHMARKS.kr.md - μ±λ₯ λ²€μΉλ§ν¬
- PROJECT_STRUCTURE.md - νλ‘μ νΈ κ΅¬μ‘°
μ΅μ’ μ λ°μ΄νΈ: 2025-11-28 κ΄λ¦¬μ: kcenon@naver.com
Made with β€οΈ by πβππ₯ π