Структура таблицы для финансовых транзакций в Mysql - PullRequest
0 голосов
/ 19 апреля 2020

Я занимаюсь разработкой системы, в которой будут проводиться финансовые транзакции. В этой системе пользователь может вставлять или снимать деньги, покупать и продавать товары, отправлять деньги другим пользователям и т. Д. c.

В настоящее время у меня есть таблица пользователей, которая, помимо регистрационных данных, также содержит общий остаток денег, который есть у пользователя в его кошельке .

и другая таблица транзакций, в которой указываются все совершенные транзакции, деньги, которые поступили на счет или покинули его ( in_or_out ), который ссылается на транзакцию ( trans_ref ) и значение , которое было передано.

Ниже приведена текущая структура:

|        Table USERS       |
----------------------------
|cod        varchar (index)|
|full_name  varchar        |
|username   varchar        |
|password   varchar        |
|wallet     decimal        |
|created_at timestamp      |
|activate   int            |


|    Table TRANSACTIONS    |
----------------------------
|cod        varchar (index)|
|user_cod   varchar        |
|trans_ref  varchar        |
|in_or_out  int            |
|value      decimal        |
|created_at timestamp      |
|status     int            |

Боюсь, что из-за ошибки в транзакции сумма не будет добавлена ​​в таблицу пользователей. Или что пользователь совершает платеж и сумма не вычитается из таблицы. Потому что я всегда буду учитывать стоимость кошелька пользователя как общую сумму денег на его счете.

Так что, если он совершает покупку, например, за 1 тысячу долларов, эта сумма не вычитается из его счет, у него все равно будет та же сумма, которую он может потратить, что впоследствии может привести к убыткам для компании, поскольку с 1 миллионом пользователей будет трудно узнать, какой пользователь вызвал проблему.

Я думал, вместо того, чтобы вносить весь кошелек в пользовательскую таблицу, я делаю запрос, чтобы получить сумму транзакций. Тогда в этом случае, если у меня 1 миллион пользователей и 1 миллиард транзакций, будет слишком тяжело постоянно получать данные о сумме, что может привести к большой медлительности в системных запросах.

Может ли кто-нибудь, имеющий некоторый опыт в вычислениях или подобных системах, подсказать мне с лучшей логикой c для структурирования этих таблиц?

Помня, что текущую структуру все еще можно изменить любым необходимым способом.

1 Ответ

0 голосов
/ 19 апреля 2020

Во-первых, я предполагаю, что столбец 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;

Этим вы гарантируете, что с каждая транзакция в таблице транзакций, ваша таблица пользователей обновляется правильно. Это, в свою очередь, позволяет вам использовать итоговую сумму в таблице пользователей для представления в вашем приложении, что устраняет необходимость подсчитывать общую сумму каждый раз, когда ваши пользователи хотят просто увидеть их общую сумму. Это должно сэкономить вам некоторую обработку ...

Чтобы обработать проверки транзакций, вы увидите, что добавленный мной триггер сначала оценит необходимость выполнения проверок или нет, поэтому устраняет ненужную обработку. В зависимости от результатов будут предприняты следующие соответствующие действия, которые вам необходимо будет определить.

Для дополнительных улучшений производительности я видел несколько решений этой проблемы, включая репликацию БД / распределение нагрузки и логическое разделение данных по нескольким таблицам. / баз данных. Я уверен, что есть множество других вариантов, в зависимости от вашей инфраструктуры. Это, к сожалению, где мой опыт ограничен, хотя ...

Надеюсь, этого ответа достаточно, чтобы вы указали в правильном направлении.

Удачи!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...