Хранимая процедура — это набор SQL-операторов (и процедурной логики), сохранённых в базе данных и выполняемых по названию. Она выполняет логику внутри базы данных, а не в коде приложения. Они имеют реальные преимущества, но также значительные компромиссы, поэтому решение об их использовании является подлинным архитектурным выбором.
Хранимая процедура
-- define a procedure that encapsulates logic in the database
CREATE PROCEDURE transfer_funds(from_id INT, to_id INT, amount DECIMAL)
LANGUAGE plpgsql AS $$
BEGIN
UPDATE accounts SET balance = balance - amount WHERE id = from_id;
UPDATE accounts SET balance = balance + amount WHERE id = to_id;
-- can include logic: conditionals, loops, error handling, transactions
END;
$$;
CALL transfer_funds(1, 2, 100); -- execute by name
Хранимая процедура объединяет SQL и процедурную логику (переменные, условные операторы, циклы, обработку ошибок) в именованный, переиспользуемый подпрограмму базы данных. Функции похожи, но возвращают значение.
Потенциальные преимущества
✓ Performance — runs IN the database (no round-trips for multi-step logic); precompiled
✓ Reduced network traffic — one call vs many queries from the app
✓ Reusability — shared logic callable from multiple applications/clients
✓ Security — grant EXECUTE on a procedure without granting table access; reduces
injection surface (parameterized)
✓ Consistency — centralize critical logic so all clients use the same implementation
Значительные компромиссы (почему многие избегают их сегодня)
✗ Business logic in the DATABASE → harder to version-control, test, and maintain
(logic split between app code and the database)
✗ Database-specific (PL/pgSQL vs T-SQL vs PL/SQL) → less portable, vendor lock-in
✗ Harder to debug than application code; weaker tooling
✗ Scaling — the database is often the hardest tier to scale; pushing logic there
can increase its load
✗ Modern apps often prefer logic in the application layer (testable, portable, versioned)
Когда их использовать
✓ Performance-critical data-intensive operations (heavy multi-step DB logic, batch jobs)
✓ Logic that MUST be enforced at the DB level across multiple clients
✓ Reducing round-trips for operations involving many queries
✗ AVOID putting general business logic in procedures by default — modern practice
usually favors the application layer (better testing, versioning, portability)
Почему это важно
Понимание хранимых процедур — включая их компромиссы — это ценные знания, потому что они представляют подлинный архитектурный выбор с реальными преимуществами и недостатками, а знание когда их использовать (и когда нет) отражает зрелое суждение.
Хранимые процедуры могут предоставить преимущества производительности (выполнение многошаговой логики внутри базы данных избегает сетевых обращений), снижение сетевого трафика, переиспользование на разных клиентах, безопасность (предоставление прав на выполнение без доступа к таблицам) и централизованную согласованность — что делает их подходящими для критичных по производительности операций с большим объёмом данных, пакетной обработки и логики, которая должна быть обеспечена на уровне базы данных в нескольких приложениях.
Однако понимание значительных компромиссов одинаково важно и отражает современную практику: размещение бизнес-логики в базе данных усложняет её контроль версий, тестирование и поддержку (разделение логики между приложением и базой данных), привязывает вас к процедурному языку конкретной базы данных (PL/pgSQL, T-SQL, PL/SQL — снижая портативность), усложняет отладку и добавляет нагрузку на уровень базы данных (часто самый сложный для масштабирования).
По этим причинам современная разработка приложений часто предпочитает держать бизнес-логику на уровне приложения (тестируемая, портативная, контролируемая версионно) вместо хранимых процедур.
Ключевой момент — это суждение о том, когда их использовать — подходят для специфических критичных по производительности потребностей или для обеспечения на уровне БД, но в целом избегаются как по умолчанию для бизнес-логики.
Поскольку хранимые процедуры встречаются во многих системах (особенно в корпоративных/устаревших), и поскольку понимание как их преимуществ, так и компромиссов (и современного предпочтения логики на уровне приложения) позволяет принимать обоснованные архитектурные решения, понимание хранимых процедур является ценными знаниями уровня senior, демонстрирующими способность взвешивать логику на стороне базы данных в сравнении с логикой на стороне приложения — значимое архитектурное соображение и тема, отражающая архитектурную зрелость.
