Во-первых, я предполагаю, что столбец in_or_out определяет, является ли транзакция входящей / исходящей транзакцией. Если это так, я не думаю, что этот столбец необходим, так как та же информация может быть передана с использованием типа данных decimal, поскольку decimal обрабатывает как положительные, так и отрицательные значения. В дальнейшем я продолжу предполагать, что столбца in_or_out больше нет на рисунке.
Я думаю, что для этого нам нужно по-настоящему понять процессы, которые ваши пользователи будут выполнять в вашем приложении. В дальнейшем я собираюсь предположить, что вам необходимо представить общую сумму средств, доступных вашим пользователям. Кроме того, вам нужно будет проверить, достаточно ли у ваших пользователей средств для обработки определенных транзакций.
Чтобы представить вашему пользователю общую сумму доступных средств, я думаю, что иметь в наличии общую сумму в таблице пользователей - это хорошо. , Вопрос в том, как вы будете держать его в курсе c, когда приходят новые транзакции, следя за масштабируемостью? Хотя я не являюсь экспертом в области инфраструктуры, я считаю, что решение, перечисленное ниже, будет довольно эффективным (хотя я уверен, что есть место для дополнительных улучшений)
Для проверки транзакций вам потребуется только проверить отрицательный результат транзакции, которые в основном являются покупками / переводами.
Учитывая все вышесказанное, я думаю, что PL SQL, указанный ниже, удовлетворит ваши потребности с точки зрения обработки данных:
-- Function to calculate the total funds available for a single user
CREATE OR REPLACE FUNCTION total_funds (l_cod VARCHAR(100)) -- Guessing about the data type here. You'll need to update as needed.
RETURNS INT
BEGIN
DECLARE l_total DECIMAL(50, 2); -- Also guessing about the data type here. You'll need to update as needed.
SELECT
SUM(value) INTO l_total
FROM
transactions t
WHERE
t.cod = l_cod;
RETURN l_total;
END;
-- Procedure to calculate total user funds
CREATE OR REPLACE PROCEDURE calc_user_funds (l_cod VARCHAR(100))
BEGIN
UPDATE
users u
SET
u.wallet = total_funds(l_cod)
WHERE
u.cod = l_cod;
END;
-- Procedure to validate funds available
CREATE OR REPLACE FUNCTION val_trans (l_cod VARCHAR(100), l_trans_value DECIMAL (100, 2))
RETURNS INT
BEGIN
DECLARE l_total_avail DECIMAL(10, 2);
DECLARE result INT;
SET l_total_avail = total_funds(l_cod);
IF l_total_avail >= l_trans_value THEN
SET result = 1;
ELSE
SET result = 0;
END IF;
RETURN result;
END;
-- Trigger
CREATE TRIGGER trans_insert AFTER INSERT ON transactions
FOR EACH ROW
BEGIN
-- Evaluate whether or not the transaction is a positive/negative transaction
IF NEW.in_or_out < 0 THEN -- If transaction is a purchase/negative transaction
IF val_trans(NEW.cod) = 1 THEN
-- Do something to indicate that the transaction is approved
ELSE
-- Do something to indicate that the transaction is not approved
END IF;
END IF
CALL calc_user_funds(NEW.cod);
END;
Этим вы гарантируете, что с каждая транзакция в таблице транзакций, ваша таблица пользователей обновляется правильно. Это, в свою очередь, позволяет вам использовать итоговую сумму в таблице пользователей для представления в вашем приложении, что устраняет необходимость подсчитывать общую сумму каждый раз, когда ваши пользователи хотят просто увидеть их общую сумму. Это должно сэкономить вам некоторую обработку ...
Чтобы обработать проверки транзакций, вы увидите, что добавленный мной триггер сначала оценит необходимость выполнения проверок или нет, поэтому устраняет ненужную обработку. В зависимости от результатов будут предприняты следующие соответствующие действия, которые вам необходимо будет определить.
Для дополнительных улучшений производительности я видел несколько решений этой проблемы, включая репликацию БД / распределение нагрузки и логическое разделение данных по нескольким таблицам. / баз данных. Я уверен, что есть множество других вариантов, в зависимости от вашей инфраструктуры. Это, к сожалению, где мой опыт ограничен, хотя ...
Надеюсь, этого ответа достаточно, чтобы вы указали в правильном направлении.
Удачи!