Отзыв о предлагаемой структуре базы данных для веб-приложения типа денежный перевод / обмен валюты - PullRequest
0 голосов
/ 13 июня 2019

Я на самом деле не эксперт по базам данных, поэтому я был бы признателен за некоторые отзывы о следующей предложенной структуре базы данных.Ситуация следующая;Я создаю веб-приложение, в котором посетитель может разместить денежный перевод в определенной валюте и получить эквивалент в другой валюте.Кошельки, которые управляют средствами, не являются частью структуры базы данных, они обмениваются данными через API, работающий в локальной сети.Единственное, что мне нужно для управления в моей базе данных, это заказы и связанные с ними суммы.Здесь есть пара вещей:

  1. Запрошенная сумма заказа может потребоваться распределить по нескольким кошелькам, если заказанная сумма больше текущего баланса одного кошелька.
  2. AnСрок действия заказа истекает автоматически через 15 минут бездействия (т.е. заказчику необходимо подтвердить заказ в течение 15 минут с момента размещения заказа).Процесс подтверждения на самом деле не имеет отношения к моему вопросу, поэтому опущу детали.
  3. Мне как-то нужно сохранить промежуточную сумму всех сумм заказов, принадлежащих заказам, которые в настоящее время помечены как невыполненные (т.е. имеют статус«новый», «ожидающий» и т. д., но не «истек», «не выполнен», «завершен»).
  4. Разница между балансом кошелька и текущей суммой от пункт 3 сообщит мне, достаточно ли средств на кошельке для покрытия входящего заказа.
  5. При прохождении процесса определения, можно ли разместить заказ (на предыдущем шаге), и на самом делепри размещении заказа (все выполняется в рамках одной транзакции базы данных), соответствующие строки таблицы amount должны быть заблокированы во избежание потенциальных проблем параллелизма.

Структура базы данных, которую я придумал:

Таблица заказов
+-------------------+------------+-----------+---------------------+---------------------+
| id                | rate       | status    | created_at          | updated_at          |
+-------------------+------------+-----------+---------------------+---------------------+
| 8ec17086-0d34-... | 0.00024041 | "expired" | 2019-12-06 20:11:30 | 2019-12-06 20:26:30 |
| 4fcaf220-c3af-... | 0.00026243 | "new"     | 2019-13-06 15:01:50 | 2019-13-06 15:01:50 | 
| ...               | ...        | ...       | ...                 | ...                 |
Таблица сумм
+-----+--------+------------+-------------------+
| id  | value  | wallet     | order_id          |
+-----+--------+------------+-------------------+
| 1   | 150000 | "wallet_2" | 8ec17086-0d34-... |
| 2   | 100000 | "wallet_1" | 4fcaf220-c3af-... |
| 3   | 200000 | "wallet_3" | 4fcaf220-c3af-... |
| ... | ...    | ...        | ...               |

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

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

    SELECT SUM("amount"."value") AS "sum" FROM "amount" "amount" INNER JOIN "order" "order" ON "order"."id"="amount"."orderId" AND ("order"."status" IN ("new", "pending", "accepted")) WHERE "amount"."wallet" = "wallet_1"
    

    Pro's:

    • Самый простой в реализации, так как мне больше не нужно вести бухгалтерский учет.

    Con's

    • Не самый эффективный, так как вы должны вычислять всю сумму каждый раз.Может не быть проблемой, если количество неоплаченных ордеров не слишком велико.
    • Я не могу заблокировать строки (см. point 5 ), как PostgreSQL не разрешать блокировку, когда задействованы агрегатные функции.
  2. Добавить дополнительный столбец balance в таблицу amount , которая содержитнакопленная сумма.Каждый раз, когда я хочу узнать баланс заказа, я просто просматриваю самую последнюю сумму заказа, связанную с невыполненным заказом.Таким образом, таблица amount будет выглядеть примерно так:

    +-----+--------+---------+------------+-------------------+
    | id  | value  | balance | wallet     | order_id          |
    +-----+--------+---------+------------+-------------------+
    | 1   | 150000 | 150000  | "wallet_2" | 8ec17086-0d34-... |
    | 2   | 100000 | 250000  | "wallet_1" | 4fcaf220-c3af-... |
    | 3   | 200000 | 450000  | "wallet_3" | 4fcaf220-c3af-... |
    | ... | ...    | ...     | ...        | ...               |
    

    Pro's:

    • Теоретически это кажется самым элегантным решением, но оно поставляется сосложнения.

    Con's:

    • Это усложняется, когда статус заказа больше не обозначается как ожидающий (например, "новый", "принят").В какой-то момент заказ перейдет из невыполненного состояния («новый», «принятый» и т. Д.) В невыполненное состояние («выполнено», «отклонено», «истек срок действия» и т. Д.).Вся история баланса должна быть пересмотрена в этих случаях.Так что это не совсем реально.
  3. Добавить новую таблицу с одной строкой и таким количеством столбцов, сколько есть кошельков, в которых записана сумма суммы заказа на кошелек. Каждый раз, когда создается заказ, соответствующий столбец необходимо увеличивать на сумму заказа, каждый раз, когда заказ завершен, срок его действия или любым другим способом изменяется в статусе с невыполненного на невыполненный, соответствующий столбец уменьшается на соответствующую сумму заказа. вместо. Я думаю, это также может быть несколько строк (каждый кошелек отдельная строка) и таблица с одним столбцом. Подумайте об этом, придумайте больше смысла, так как он будет более гибким при добавлении / удалении кошельков.

    Pro-х:

    • Это позволяет обойти минусы из первых двух вариантов.

    Con-х:

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

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

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