Вы смутили народ соей странной постановкой задачи.
В реальном мире смысл монеты ка краз в ее неуникальности и взаимной заменяемости с другими такими же. А у вас это не монеты, а, своего рода, токены. И если формулировать так, то станет гораздо понятнее.
У вас определённо должна быть таблица токенов и, если каждй токен кому-то принадлежит, то токен должен ссылаться на текущего владельца.
Вообще тут можно всё сделать очень по-разному в зависимости от того, какие операции и какие отчеты вам нужны чаще, а какие реже, какие агрегации надо делать.
К примеру, можно хранить у каждого токена ссылку на его текущего владельца, а в отдельном журнале историю движения токена в том виде в каком вы предложили.
Фактически это журнал транзакций передачи токенов между пользователями.
Однако по постановке вопроса ясно, что вы хотите также понимать в какой-то момент сколько токенов у кажого пользователя. То есть существует какая-то функция нормирования, которая приводит токен к какой-то веичине объективно определяющей его ценность.
Тогда определить текущий баланс пользователя можно агрегацией - суммированием норм всех токенов, принадлежащих конкретному юзеру.
Если баланс вам надо получать часто, то каждый раз аггрегировать плачевно для производительности. Тогда вам стоит хранить своеобразный кеш текущего баланса в таблице пользователей.
Тогда в рамках кажлой транзакции в бэкенде вы должны:
- занести запись о передаче токена от пользователя к пользователю,
- вычесть стоимость токена из баланса первого юера,
- добавить ее к балансу второго.
Эти три изменения должны быть в рамках атомарной транзакции. Если что-то пошло не так, то все три действия должны отмениться.
Вам стоит поизучать курс баз данных, чтобы понимать какие неочевидные для новичков проблемы кроются в бизнес логике, когда ваша система постянно осуществляет одновременные переводы между пользователями. Там целый мир и CAP-теорема. Почитайте.
Да, возможны более сложные ситуации, когда вам нужно быстро получать не только баланс пользователя на текущий момент, но и баланс пользователя на любой конкретный момент времени в прошлом.
Очевидно, что вм для этого пришлось бы сделать снимок текущего состояния балансов пользователя, а потом пройтись в обратном порядке по всем его транзакциям в которых он был источником и приемником токенов и обратить все операции над копией его баланса.
Чтобы делать это быстро, то балансы пользователей на момент транзакции можно размещать в жарнале. Это избыточность, но она позволит мгновенно получать баланс любого польщователя на любой момент времени. Для этого нажно лишь найти саму старую транзакцию этого пользователя не позднее заданного времени и там будет нужное число. Этот поиск делается с логарифмической сложность.