에이전틱 AI가 전통적인 데이터베이스 아키텍처의 전제를 어떻게 깨뜨리는지, 어떤 방어적 패턴(타임아웃, 소프트 삭제, 이벤트 로그, 멱등성 키, 전용 커넥션 풀, 관측 가능성, 스키마 가독성, 최소 권한)이 필요한지 구체적인 코드와 함께 정리한다.
BlogsPapershelfBookshelfCoursesTalks

엔지니어링, 데이터베이스, 그리고 시스템. 늘 만들고 있다.
당신이 지금까지 내린 모든 데이터베이스 아키텍처 결정의 바닥에는 암묵적인 계약이 하나 깔려 있다. 아마 한 번도 문서로 적어 둔 적은 없을 것이다. 아무도 그렇게 하지 않는다. 그건 그냥… 존재해 왔다.
그 계약은 대략 이런 식이다. 호출자는 사람이 작성한 애플리케이션이고, 결정적인 코드를 실행하며, 예측 가능한 쿼리를 발행하고, 배포 전에 개발자가 리뷰한다. 쓰기는 의도적이다. 연결은 짧다. 뭔가 잘못되면 사람이 알아챈다. 애플리케이션 계층이 똑똑하고 조심스럽기 때문에 데이터베이스는 단순하고 빠를 수 있다.
40년 동안 이 계약은 유지됐다. 이 계약은 우리가 스키마를 설계하고, 커넥션 풀을 사이징하고, 권한을 부여하고, 장애 모드를 생각하는 방식을 형성했다. 가정이 맞았기 때문에 작동했다.
이제는 더 이상 맞지 않다. 에이전틱 AI 시스템은 이 계약을 모든 계층에서 동시에 위반한다.
이 글에서는 어떤 가정들이 정확히 어떻게 무너지고 있는지, 왜 중요한지, 그리고 무엇을 해야 하는지를 구체적인 패턴과 코드와 함께 분해해서 설명한다. 바로 들어가 보자…
에이전트 이전에 당신이 배포했던 모든 애플리케이션에서, 데이터베이스에 들어오는 쿼리는 사람이 작성했다.
이 가정은 너무 깊이 박혀 있어서 도구들이 자동으로 이를 반영한다. Postgres 쿼리 플래너는 관측된 쿼리 패턴을 중심으로 통계를 만들고, 캐싱 레이어는 반복되는 쿼리로 워밍업되며, 커넥션 풀은 알려진 복잡도의 동시 쿼리 수를 기준으로 튜닝된다.
에이전트는 다르게 동작한다. 에이전트는 추론을 통해 쿼리를 만들어 낸다. 서로 다른 추론 경로는 같은 테이블을 대상으로도 서로 다른 쿼리를 만든다.
고객 분석 작업을 수행하는 에이전트는 이전에 한 번도 실행된 적 없는 5개 테이블 조인을 날릴 수 있고, 결과를 곱씹는 동안 커넥션을 붙잡아 둔 채로 있다가, 완전히 다른 후속 쿼리를 날릴 수도 있다. 당신의 인덱스는 ‘해피 패스’를 커버한다. 당신의 커넥션 풀은 관측된 피크에 맞춰져 있다. 에이전트가 필요 데이터에 따라 어떤 쿼리든 조립할 수 있게 되면, 둘 다 성립하지 않는다.
statement timeout은 첫 번째 방어선이다. 30초 걸리는 사람이 작성한 쿼리는 누군가가 알아챌 버그다. 30초 걸리는 에이전트 쿼리는 아무도 보고 있지 않은 추론 루프일 수 있다.
그래서 애플리케이션 레벨뿐 아니라 롤 레벨에서 타임아웃을 설정하라.
CREATE ROLE agent_worker;
ALTER ROLE agent_worker SET statement_timeout = '5s';
ALTER ROLE agent_worker SET idle_in_transaction_session_timeout = '10s';
idle_in_transaction_session_timeout은 특히 중요하다. 에이전트가 추론 도중 멈춘 채로 열린 트랜잭션을 쥐고 있는 상황은 충분히 현실적인 케이스다.
데이터베이스 아키텍처에서 가장 위험한 가정은, 모든 쓰기가 발생하기 전에 사람의 리뷰를 거쳤다는 것이다. 이는 사실상 당신의 커리어 대부분 동안 대체로 참이었지만, 이제는 아니다.
에이전트는 자율적으로 쓴다. 에이전트는 현재 과업에 대한 자신의 이해를 바탕으로 쓰는데, 그 이해가 틀릴 수 있다. 에이전트는 도구가 예상치 못한 결과를 돌려주면 루프를 돌면서 쓴다. 일시적인 네트워크 오류로 첫 시도가 실패했다고 ‘생각’하면 재시도하면서 또 쓴다. 심지어 Slack 알림 하나 받는 동안 수천 행을 쓸 수도 있다.
여기 실제로 문서화된 실패 패턴이 있다. 레거시 API를 호출한 에이전트가 빈 결과 집합과 함께 HTTP 200을 받는다. 다운스트림에서 데이터베이스 커넥션 풀이 고갈되며 API가 조용히 실패한 것이다. 에이전트는 “데이터 없음”을 “문제 없음”으로 해석하고 불완전한 데이터로 500건의 트랜잭션을 처리한다. 예외는 발생하지 않았다. 알림도 울리지 않았다. 로그에는 모든 레코드에 “decision: approved”가 찍혔다.
핵심 해결책은, 호출자가 틀릴 수 있고, 재시도할 수 있고, 결과를 보고 있지 않을 수 있다는 전제에서 쓰기 경로를 설계하는 것이다.
에이전트가 무엇이든 하드 삭제하게 두지 마라. 에이전트가 쓸 수 있는 모든 테이블에 대해 소프트 삭제를 기본선으로 삼아라.
ALTER TABLE orders ADD COLUMN deleted_at TIMESTAMPTZ;
ALTER TABLE orders ADD COLUMN deleted_by TEXT; -- 'agent:customer-support-v2', 'user:abc123'
ALTER TABLE orders ADD COLUMN delete_reason TEXT;
-- Agents query this view; they never see deleted rows and can't accidentally undelete
CREATE VIEW active_orders AS
SELECT * FROM orders WHERE deleted_at IS NULL;
deleted_by 컬럼은 보기보다 훨씬 중요하다. 두 시간 전에 무슨 일이 있었는지 디버깅할 때, “에이전트 X가 삭제한 모든 것 보여줘”는 반드시 실행하고 싶은 쿼리다.
재무 기록, 재고 변경, 사용자 상태 변이처럼 더 중요한 작업에서는 한 걸음 더 나아가 테이블을 append-only로 만들 것을 고려하라. 에이전트는 UPDATE나 DELETE를 발행하지 않는다. 새로운 상태와 이유를 담은 INSERT를 발행한다.
CREATE TABLE order_state_log (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
order_id UUID NOT NULL REFERENCES orders(id),
previous_status TEXT,
new_status TEXT NOT NULL,
changed_by TEXT NOT NULL,
changed_at TIMESTAMPTZ DEFAULT now(),
reason TEXT,
idempotency_key TEXT UNIQUE
);
이는 테이블 레벨에 적용한 이벤트 소싱 패턴이다. 가장 민감한 엔티티에 대해 append-only 로그 테이블 하나만 있어도 완전한 감사 추적(audit trail)을 얻을 수 있고, “되돌리기(undo)”는 프로젝션 쿼리가 된다.
에이전트는 재시도하며, 이는 설계상 그렇다. 모든 오케스트레이션 프레임워크는 최소 한 번(at-least-once) 전달 시맨틱으로 동작한다. 어떤 스텝이 실패하면 다시 실행된다. 따라서 쓰기 경로는 이를 전제로 설계되어야 한다.
멱등성 키(idempotency key)는 에이전트가 모든 쓰기와 함께 포함하는 안정적인 식별자다. 데이터베이스는 유니크 제약으로 중복을 조용히 거부한다. 에이전트는 어느 쪽이든 성공 응답을 받는다. 같은 작업을 두 번 실행해도 한 번 실행한 것과 결과가 동일해진다.
-- The agent generates this key from
-- task_id + operation_type + target_id
-- It is deterministic for the same logical
-- operation, so retries produce the same key
ALTER TABLE order_state_log
ADD CONSTRAINT uq_idempotency_key UNIQUE (idempotency_key);
실제로 에이전트는 키를 이렇게 구성한다.
import hashlib
def make_idempotency_key(task_id: str,
operation: str, target_id: str) -> str:
raw = f"{task_id}:{operation}:{target_id}"
return hashlib.sha256(raw.encode()).hexdigest()[:32]
task ID는 오케스트레이션 레이어에서 오며, 같은 논리적 작업의 재시도 전반에 걸쳐 안정적이다. 즉 에이전트는 필요한 만큼 재시도해도, 데이터베이스는 논리적 작업당 정확히 한 번의 쓰기만 보게 된다.
전통적인 커넥션 풀 사이징은 단순한 멘탈 모델을 따른다. 애플리케이션은 동시 요청 N개를 처리한다. 각 요청은 짧은 시간 동안 하나의 DB 커넥션이 필요하다. 기대하는 동시성 피크보다 약간 크게 풀을 잡고, 약간의 헤드룸을 더하면 끝이다.
에이전트는 이 모델을 세 가지 방식으로 깨뜨린다.
다단계 추론 작업은 쿼리를 날리고, 결과를 LLM으로 처리하기 위해 잠시 멈추고, 또 다른 쿼리를 날리고, 다시 멈추는 일을 반복할 수 있다. 각 멈춤 동안 커넥션은 열린 채로 유지된다. 작업당 커넥션 시간이 더 이상 “쿼리 실행 시간”이 아니라 “쿼리 실행 시간 + LLM 추론 시간 x 추론 스텝 수”가 된다.
하나의 상위 에이전트 작업은 종종 병렬로 일할 서브 에이전트를 생성한다. 하나의 작업이 다섯 개의 동시 DB 세션이 된다. 동시에 진행되는 에이전트 워크플로가 긴 IO 대기 동안 db.session을 열린 채로 붙잡으면 Postgres의 커넥션 슬롯이 바닥나면서 커넥션이 고갈될 수 있다.
개발에서는 에이전트가 세 개였다. 운영에서는 서른 개다. 누구도 커넥션 풀 설정을 업데이트하지 않았다.
해결책은, 에이전트 워크로드를 위한 전용 커넥션 풀을 두고, 사람 대상 트랜잭션 애플리케이션 트래픽과 분리한 채로 독립적으로 사이징하는 것이다.
# Rule of thumb: (num_agent_workers * avg_concurrent_steps * 0.5)
# The 0.5 accounts for the fact that most agent steps
# involve LLM time, not DB time
agent_engine = create_engine(
DATABASE_URL,
pool_size=10, # base pool for agents
max_overflow=5, # burst capacity
pool_timeout=3, # fail fast rather than queue
pool_recycle=300, # recycle connections every 5 minutes
pool_pre_ping=True, # validate connections before checkout
connect_args={
"options": "-c statement_timeout=5000 -c idle_in_transaction_session_timeout=10000"
}
)
pool_timeout=3는 의도적이다. 에이전트가 3초 안에 커넥션을 얻지 못하면, 무한정 큐에 쌓이기보다 빠르게 실패하고 백오프로 재시도해야 한다. 포화된 풀 아래에서 요청을 큐잉하는 것이 연쇄 장애(cascading failures)가 발생하는 전형적인 경로다.
많은 에이전트를 동시에 돌리는 시스템이라면 에이전트와 Postgres 사이에 PgBouncer를 추가하라. PgBouncer는 트랜잭션 풀링 모드로 동작할 수 있는데, 이는 세션 전체 동안 커넥션을 붙잡는 대신 각 트랜잭션이 끝나면 즉시 커넥션을 풀로 돌려보낸다. 에이전틱 워크로드에서 유효 커넥션 수용량을 크게 늘리는 중요한 배수 효과를 준다.
# pgbouncer.ini
[databases]
mydb = host=postgres_host dbname=mydb
[pgbouncer]
pool_mode = transaction # critical: release connection after each transaction
max_client_conn = 500 # clients (agents) can connect up to this number
default_pool_size = 20 # actual postgres connections (much smaller)
reserve_pool_size = 5 # emergency capacity
reserve_pool_timeout = 1.0 # fail fast if reserve is also exhausted
트랜잭션 풀링 모드에서는 실제 Postgres 커넥션 20개가 에이전트 커넥션 500개를 서비스할 수 있다. 각 에이전트는 멀티스텝 작업 전체가 아니라, 단일 트랜잭션 지속 시간 동안만 Postgres 커넥션을 점유하기 때문이다.
사람이 운영하는 시스템에서는 느리거나 잘못된 쿼리가 빠르게 드러난다. 대시보드가 느리게 뜨거나 API가 타임아웃되고, 엔지니어가 EXPLAIN ANALYZE를 돌려 문제를 찾는다. 피드백 루프가 촘촘하다.
에이전트는 그 피드백 루프를 닫아 버린다. 느린 쿼리 결과를 받은 에이전트는 그냥 그 결과를 사용한다. 빈 결과 집합을 받은 에이전트는 데이터가 정말 없는 것인지, 쿼리가 틀린 것인지 알지 못한다. 그리고 작업을 계속 진행하며, 잘못된 읽기에 기반한 결정을 쓸 수도 있다.
이는 애플리케이션 에러와는 다른 종류의 실패다. 예외는 관측 가능하다. 하지만 의미적으로 틀린 쿼리가 행을 반환하면 관측되지 않는다.
완화책은 에이전트 전용 관측 가능성을 데이터베이스 접근 레이어에 구축하는 것이다. 표준 슬로우 쿼리 로그만으로는 부족하다. 어떤 에이전트가, 어떤 태스크에서, 어떤 추론 스텝으로 쿼리를 만들었는지 알아야 한다. Postgres에서 이를 하는 가장 실용적인 방법은 쿼리 코멘트다.
from sqlalchemy import text, event
from sqlalchemy.engine import Engine
@event.listens_for(Engine, "before_cursor_execute")
def add_agent_context_comment(conn, cursor, statement, parameters, context, executemany):
agent_ctx = getattr(conn.info, "agent_context", None)
if agent_ctx:
statement = f"/* agent_id={agent_ctx['agent_id']}, task_id={agent_ctx['task_id']}, step={agent_ctx['step']} */ {statement}"
return statement, parameters
# Usage: set context on the connection before executing
with engine.connect() as conn:
conn.info["agent_context"] = {
"agent_id": "fulfillment-v3",
"task_id": "task-abc-123",
"step": "check-inventory"
}
conn.execute(text("SELECT ..."))
이 코멘트는 pg_stat_activity, pg_stat_statements, 그리고 슬로우 쿼리 로그에 나타난다. 슬로우 쿼리 로그에 agent_id=fulfillment-v3, task_id=task-abc-123, step=check-inventory로 태그된 쿼리가 찍히면 즉시 조치 가능하다. 이것이 없으면 고고학을 하는 셈이다.
에이전트별로 쿼리를 그룹핑해 보여주는 모니터링 뷰를 만들어라.
-- pg_stat_statements with agent context extracted from query text
SELECT
(regexp_match(query, 'agent_id=([^,]+)'))[1] AS agent_id,
(regexp_match(query, 'task_id=([^,]+)'))[1] AS task_id,
count(*) AS call_count,
round(mean_exec_time::numeric, 2) AS avg_ms,
round(total_exec_time::numeric, 2) AS total_ms
FROM pg_stat_statements
WHERE query LIKE '%agent_id=%'
GROUP BY 1, 2
ORDER BY total_ms DESC;
총 데이터베이스 시간의 60%를 특정 에이전트 타입이 차지하고 있다는 것을 보면, 어디를 봐야 할지 알게 된다.
대부분의 팀은 이 가정이 깨질 때까지 이를 생각하지 않는다. 당신의 스키마는 개발자 인체공학을 위해 설계됐다. 엔지니어에게 의미가 통하는 이름, 쿼리 편의를 위한 구조, 원래 마이그레이션 코멘트를 읽어야만 의미가 드러나는 nullable 컬럼들.
에이전트가 Text-to-SQL을 통해서든, 도구 정의를 통해서든, 데이터베이스를 감싼 MCP 서버를 통해서든 스키마를 볼 수 있게 되면, 스키마는 언어 모델과의 계약이 된다. 컬럼 이름, 테이블 구조, nullability는 이제 LLM이 올바른 쿼리를 생성할지, 그럴듯하게 들리는 헛소리를 생성할지를 좌우한다.
다음 두 컬럼 정의의 차이를 생각해 보자.
-- What most schemas look like
CREATE TABLE orders (
id UUID PRIMARY KEY,
usr_id UUID, -- which user?
stat_cd INT, -- what does 2 mean? what does 7 mean?
flg_1 BOOLEAN, -- ???
upd_ts TIMESTAMPTZ -- updated at? but by whom?
);
-- What a schema legible to an agent looks like
CREATE TABLE orders (
id UUID PRIMARY KEY,
customer_id UUID NOT NULL REFERENCES customers(id),
fulfillment_status TEXT NOT NULL CHECK (
fulfillment_status IN ('pending', 'processing', 'shipped', 'delivered', 'cancelled')
),
requires_signature BOOLEAN NOT NULL DEFAULT false,
last_modified_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
두 번째 스키마는 거의 자동으로 올바른 LLM 쿼리를 만들어 낸다. 첫 번째 스키마는 스키마 레벨에서 했어야 할 일을 보완하기 위해 광범위한 프롬프트 엔지니어링이 필요하다.
이름을 바꿀 수 없는 스키마(레거시 시스템, 마이그레이션 비용이 큰 테이블)라면 에이전트용 뷰 레이어를 만들어라.
-- The raw table retains its legacy names
-- Agents query this view; they never touch the underlying table directly
CREATE VIEW agent_orders AS
SELECT
id,
usr_id AS customer_id,
CASE stat_cd
WHEN 1 THEN 'pending'
WHEN 2 THEN 'processing'
WHEN 5 THEN 'shipped'
WHEN 7 THEN 'delivered'
WHEN 9 THEN 'cancelled'
END AS fulfillment_status,
flg_1 AS requires_signature,
upd_ts AS last_modified_at
FROM orders
WHERE deleted_at IS NULL; -- agents only ever see active rows
컬럼 코멘트는 docstring을 쓰듯 작성하라. Text-to-SQL 에이전트에게는 그것이 곧 docstring이기 때문이다.
COMMENT ON COLUMN agent_orders.fulfillment_status IS
'Current state of the order in the fulfillment pipeline. '
'Use this to filter orders that need action: pending and processing orders are active. '
'Cancelled orders should never be modified.';
COMMENT ON COLUMN agent_orders.requires_signature IS
'True if the delivery requires an adult signature. '
'When true, the shipping agent must schedule a delivery window.';
위의 모든 가정을 가로지르는 또 하나의 실패 모드는 따로 다룰 가치가 있다. 바로, 오작동하는 에이전트의 블라스트 반경은 그 에이전트가 부여받은 접근 권한에 의해 결정된다는 점이다.
전통적인 애플리케이션은 하나의 DB 롤을 공유하거나, 많아야 서비스별로 몇 개의 롤을 가진다. 가정은 애플리케이션 코드가 가드레일이라는 것이었다. 코드가 사용자에게 자기 레코드만 업데이트하게 했다면, DB 롤이 그걸 강제할 필요는 없었다. 애플리케이션 레이어가 처리했다.
에이전트는 이 가정을 위험하게 만든다. 추론이 잘못된 상태로 들어간 에이전트는 개발자가 예상하지 못했던 쿼리를 발행할 수 있다. 에이전트는 제한된 코드 경로 집합이 아니다. DB 커넥션에 접근할 수 있는 범용 추론기다. 애플리케이션 레벨 가드레일은 결정적 코드에 묶이는 방식으로 에이전트를 묶지 못한다.
해결책은 에이전트 타입별 롤(role-per-agent-type) 접근과, 데이터베이스 레벨에서 정의하는 최소 권한이다.
-- Each agent type gets its own role
CREATE ROLE agent_fulfillment;
CREATE ROLE agent_customer_support;
CREATE ROLE agent_analytics;
-- agent_analytics: read-only, only the tables it needs
GRANT SELECT ON agent_orders TO agent_analytics;
GRANT SELECT ON customers TO agent_analytics;
-- Explicitly: no access to payments, credentials, PII tables
-- agent_customer_support: can update order status, cannot touch financials
GRANT SELECT ON agent_orders TO agent_customer_support;
GRANT INSERT ON order_state_log TO agent_customer_support;
-- Does not have UPDATE on orders -- changes go through the event log
-- agent_fulfillment: can read and update shipping-related fields only
GRANT SELECT, UPDATE (fulfillment_status, shipped_at, tracking_number)
ON orders TO agent_fulfillment;
접근 설계 리뷰에서 물어야 할 질문은 “이 에이전트에게 무엇이 필요한가?”가 아니라 “이 에이전트의 추론이 틀어지거나 자격 증명이 탈취되면 최악의 경우가 무엇인가?”다. 데이터베이스 레벨에서 그 블라스트 반경을 줄여라. 그러면 추론으로 우회할 수 없다.
이를 종합하면, 이러한 실패 모드를 내재화한 팀의 데이터 레이어는 다음과 같은 모습이 된다. 어떤 것도 특별하거나 생소하지 않다. 모두 검증된 데이터베이스 도구들에 이미 존재한다.
각 에이전트 타입은 최소 필요 권한만 가진 전용 DB 롤을 가지며, 롤 레벨 타임아웃으로 데이터베이스에서 강제된다. 에이전트는 전용 커넥션 풀을 통해 접속하며, 에이전틱 워크로드 패턴에 맞춰 사이징되고 사람 대상 트래픽과 분리된다. 에이전트와 Postgres 사이에는 트랜잭션 풀링 모드의 PgBouncer가 동작한다.
에이전트가 쓸 수 있는 테이블은 deleted_by 컬럼으로 에이전트 정체성을 남기는 소프트 삭제를 사용한다. 고위험 쓰기 경로는 멱등성 키 제약이 있는 append-only 이벤트 로그 테이블을 사용한다. 모든 쓰기는 에이전트 ID와 task ID를 담아 감사 추적이 항상 탐색 가능하도록 한다.
에이전트가 볼 수 있는 스키마 오브젝트는 레거시 편의가 아니라 가독성을 위해 이름이 지어진다. 유지 관리되는 뷰 레이어가 레거시 컬럼 이름을 의미 있는 이름으로 변환한다. 컬럼 코멘트는 docstring처럼 작성된다. 에이전트는 기본 테이블이 아니라 뷰에 대한 접근 권한만 받는다.
에이전트가 발행하는 모든 쿼리는 에이전트 ID, task ID, 추론 스텝을 담은 코멘트를 포함한다. 모니터링 대시보드는 이 데이터를 집계하여 온콜 엔지니어가 실시간으로 “지난 1시간 동안 에이전트 X가 DB 시간의 40%를 소비했다”를 볼 수 있게 한다.
서킷 브레이커도 정의된다. 오케스트레이션 레이어에서 태스크당 최대 쓰기 횟수를 강제하고, statement 복잡도 체크로 statement당 영향 행 수를 제한하며, 워치독 프로세스로 최대 태스크 지속 시간을 강제해 정체된 에이전트 세션을 종료한다.
새로운 기술은 필요 없다. 소프트 삭제, append-only 로그, 최소 권한 롤, 행 수준 보안(row-level security), 멱등성 키, 쿼리 태깅—이런 패턴들은 수년간 존재해 왔다. 에이전트가 강제하는 변화는, 이런 패턴들이 “언젠가 구현해야지 하는 베스트 프랙티스”에서 “하중을 버티는 핵심 인프라(load-bearing infrastructure)”로 바뀐다는 점이다. 에이전트는 이를 미루는 사치를 허락하지 않는다.
데이터베이스는 이런 호출자를 위해 설계되지 않았다. 하지만 이를 안전하게 만들 도구들은 이미 다 있다.
전통적인 데이터베이스 아키텍처는 에이전틱 AI 워크로드가 체계적으로 위반하는 가정들 위에 서 있다. 결정적인 호출자, 의도적인 쓰기, 짧은 연결, 크게 드러나는 실패, 그리고 스키마를 개발자 계약으로 보는 관점.
이 가정들이 유지될 수 있었던 이유는 항상 어딘가에 사람이 루프 안에 있었기 때문이다. 에이전트는 그 보장을 제거한다. 그 결과, 오랫동안 선택적 베스트 프랙티스로 취급되던 패턴들—소프트 삭제, append-only 로그, 멱등성 키, 최소 권한 롤, 쿼리 태깅—이 하중을 버티는 핵심 인프라가 된다.
새로운 기술이 필요한 것이 아니다. 호출자가 틀릴 수 있고, 재시도할 수 있고, 결과를 보고 있지 않을 수 있다는 것을 전제로 데이터베이스를 방어 계층으로 대우해야 한다.
이 글이 도움이 되고 흥미로웠다면,

GCP Memorystore & Dataproc에서 전 스태프 엔지니어, DiceDB 제작자, 전 Amazon Fast Data, 전 엔지니어링 디렉터. Unacademy에서 SRE 및 데이터 엔지니어링 전 리드. 나는 YouTube의 군더더기 없는 엔지니어링 영상과 내 코스를 통해 엔지니어링 호기심을 불러일으킨다.
글과 배움
코스
법적 고지 및 연락처
기타
Arpit의 뉴스레터는 145,000명의 엔지니어가 읽는다
현실 세계의 시스템 설계, 분산 시스템, 또는 매우 영리한 알고리즘에 대한 딥다이브를 다루는 주간 에세이.
Subscribe on LinkedInSubscribe on Substack
이 웹사이트에 기재된 코스는 다음 회사가 제공한다.
Relog Deeptech Pvt. Ltd.
203, Sagar Apartment, Camp Road, Mangilal Plot, Amravati, Maharashtra, 444602
GSTIN: 27AALCR5165R1ZF
YouTube (200k)Twitter (100k)LinkedIn (250k)Instagram (7k)GitHub (6k)