Помощь в построении архитектурной логики с БД

Я сейчас разрабатываю симуляцию торговой биржи. И хотел бы чтобы все было более реалистично.

Мне нужно хранить данные о пользователи(апи ключ, баланс, активные ордера и выполненные ордера)

Примерно в таком формате баланс:

[
  {
    "currency": "ETH",
    "available": "10.000000000",
    "reserved": "0.560000000"
  },
  {
    "currency": "BTC",
    "available": "0.010205869",
    "reserved": "0"
  }
]

И данные об ордере

[
  {
    "id": 840450210,
    "clientOrderId": "c1837634ef81472a9cd13c81e7b91401",
    "symbol": "ETHBTC",
    "side": "buy",
    "status": "partiallyFilled",
    "type": "limit",
    "timeInForce": "GTC",
    "quantity": "0.020",
    "price": "0.046001",
    "cumQuantity": "0.005",
    "postOnly": false,
    "createdAt": "2017-05-12T17:17:57.437Z",
    "updatedAt": "2017-05-12T17:18:08.610Z"
  }
]

Я решил хранить данные о ключе в Mysql и данные об активных ордерах, выполненных и балансе в коллекциях mongodb.

Проблема как связать таблицу mysql с данными о ключах пользователя и его активными ордерами в mongo? Или я должен изменить архитектуру?

Хочу узнать как правильно сделать архитектуру в данном случае.


Ответы (1 шт):

Автор решения: Roman Konoval

Самый простой способ это добавить поле в монго документ user_id, в котором сохранять идентификатор пользователя, с которым связан ордер. Придется хранить таблицу пользователей (если ее еще нет в mysql) и там нужно поле id, значение из которого и использовать для связи сущностей.

Одно замечание немного за рамками вопроса о том как хранить связь, но относится к нему, является довольно важным, возможно, неочевидным и его нужно иметь ввиду.

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

Поясню, на примере.

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

При этом возникает такая проблема, что простая и наивная реализация может привести к тому, что пользователь будет удален, но для него все равно добавится ордер. В случае если все данные хранятся в одной БД, то эта ситуация не случится, т.к. будет существовать внешний ключ с поля user_id в ордере, который ссылается на user.id, и БД гарантирует что не возникнет ситуации, при которой запись в таблице order ссылается на (уже) несуществующую запись в таблице user.

→ Ссылка