Разработка базы данных SQL для веб-платформы внутреннего обмена - PullRequest
0 голосов
/ 08 сентября 2011

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

В частности, типичная транзакция происходит следующим образом:

Пользователь А может предложить работу в обмен на Х кредитов. Пользователи B и C могут принять предложение. Всего X кредитов будет вычтено из счетов B и C. Когда работа будет завершена, X кредитов будут добавлены на счет А. А может использовать заработанные кредиты для торговли с другими пользователями.

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

Каждый раз, когда задание выполняется для пользователя B и C пользователем A:

  • В таблице транзакций записаны две транзакции: перевод из B в A и перевод из C в A

  • Таблица счетов будет обновлена: доступные кредиты будут обновлены на счетах A, B и C

  • Таблица заданий также обновляется.

(Все эти действия будут заключены в «транзакцию» SQL, т. Е. Все записи обновлены или отсутствуют)

Когда транзакция отменяется (скажем, между A и B, но не между A и C), учетная запись A и B и Account_History будут обновлены, транзакция между A и B будет установлена ​​на «возврат».

Эскиз в Rails выглядит следующим образом:

  • класс Работа

    атрибуты:: job_id,: total_credit,: созданный_ат,: updated_at

    принадлежит_ продавцу,: имя_класса => "Пользователь" принадлежит_покупателю: : class_name => "Пользователь" # одна работа может быть выполнена для нескольких пользователей

  • Класс транзакции

    атрибуты: транзакция_ид,: покупатель_ид,: продавец_ид,: статус,
    : credit,: creation_at,: updated_at

    принадлежит_то: продавец,: class_name => «Пользователь» принадлежит_то: покупатель,
    : class_name => "Пользователь # одна запись транзакции на кредитный своп
    принадлежат: учетная запись

  • Класс учетной записи

    атрибуты:: account_id,: user_id,: available_credit

    принадлежит_: пользователь

Я не уверен, должен ли я:

  1. Создать таблицу Account_History для представления извлеченной сводной статистики из таблицы счетов (например, транзакции за последний месяц, общая сумма кредита) заработанные / потраченные и т. д.) для клиентов, или хранить эту информацию в серии кэшированных запросов.

    Представляет ожидающую транзакцию (то есть, когда B принимает предложение A, но работа еще не завершена) и завершенная транзакция (т.е. когда B принимает работу А) в отдельных записях в таблице транзакций. Другой вариант будет просто изменить статус транзакции с в ожидании завершения.

Спасибо за ваши комментарии.

1 Ответ

1 голос
/ 09 сентября 2011

Более традиционным подходом было бы использование большей части схемы учета с двойной записью.

Вы можете прочитать об этом проекте где угодно, но вот ссылка на довольно хорошее обсуждение того, что это такое и как оно работает.

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

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

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

Если вы хотите провести различие между транзакциями, находящимися на рассмотрении, и транзакциями, которые были завершены, то вы можете установить флаг статуса для транзакции (в ссылочной ссылке, таблица JOURNAL). Тем не менее, существует также более разностороннее соглашение о бухгалтерском учете, которое дает каждому пользователю две учетные записи, одну из заработанных кредитов и одну незаработанную. В этой схеме, используя ваш пример, B и C положили бы некоторые кредиты на ожидающий кредитный счет A. Это сразу же приведет к привлечению средств на счетах B и C, чтобы они не тратили эти кредиты в другом месте. Когда А завершает работу, эти кредиты переводятся с ожидающего аккаунта А на текущий аккаунт А. Если задание будет отменено, вы должны внести транзакцию, чтобы перевести обратно с ожидающего аккаунта А на текущие счета Б и С.

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

...