2015-04-13 4 views
1

У нас есть приложение Qt C++ Gui, которое в основном является терминалом для сервера (TCP), контролирующего его и отображающего его данные.Параллельные обновления данных реляционных приложений

Проблема в том, что данные, поступающие с сервера, являются реляционными данными. В Условиях SQL это будет ~ 10-15 таблиц, все связанные друг с другом некоторыми внешними ключами

Эти данные обновляются на сервере и должны быть (в то же время) отображены графическим интерфейсом.

Исходное решение состоит в том, что мы храним все данные в (в основном) картах и ​​структурах с соответствующей блокировкой (чтение/запись), чтобы избежать проблем с одновременным доступом.

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

Будет ли использоваться система реляционных баз данных в приложении (например, sqlite с базой данных в памяти)? Использует базу данных (где реляционные зависимости решаются при запросе) лучше масштабируется, чем с использованием карт структур (где реляционные зависимости решаются во время вставки)?

Надеюсь, я поставил свою проблему как можно яснее.

С уважением, Андре


Чтобы сделать его более ясным: Это о GUI не реагирует больше, как много обновлений с сервера блокировки datastructures.

+0

Вопрос: пользователь вводит команды в графическом интерфейсе, которые затем отправляются на сервер, который отвечает на большее количество данных (по запросу)? – Sga

+0

Я боюсь, что с «блокировкой» вы хотите отправить запрос блокировки от клиента к серверу, ответить с успехом/неудачей блокировки и продолжить работу с обновлением? Потому что это объясняет медленность. – MSalters

+0

Ах, все еще неясно ... Игнорируйте, что клиент делает с сервером. Все дело в данных, поступающих с сервера. Обработка данных (помещая их в правильные карты) по существу блокирует поток графического интерфейса пользователя от рисования. В связи с этим возникает вопрос: поможет ли RDB в этом случае – Bigbohne

ответ

3

(на основе обновленного комментария с указанием фактической проблемы, UI нить блок)

Есть два простых решений, которые могут помочь здесь. Первой проблемой является предварительная обработка всех входящих данных перед блокировкой общих структур данных. Например, если у вас есть std::string на карте, не конвертируйте const char* в std::string, удерживая замок на карте. Это вызовет strlen, удерживая поток пользовательского интерфейса. Вместо этого сначала конвертируйте, а затем заблокируйте карту.

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

Более сложная стратегия (если разбиение невозможно) является постановкой. Создайте все новые записи на новой карте, а затем объедините две карты. Это в основном предварительная обработка стероидов, так как теперь вы также сортируете новые записи. (Я надеюсь, что вы обмениваетесь разностями с сервером и не делаете полного обновления данных каждый раз!)

+0

Хорошие идеи. Мы делаем delta-updates, но имеем значительное количество (что мы называем) начальные обновления ... Все дельта-обновления до этого момента. Это происходит во время повторного подключения в середине дня. – Bigbohne

+0

Подготовка обновлений до добавления в контейнер - это то, что мы уже делаем (в виде общих указателей). Но чтобы убедиться, что реляционные ограничения удерживаются, нам все равно придется блокировать несколько контейнеров. (Так что читатель не увидит разбитое состояние) – Bigbohne

+1

@Bigbohne: Обеспечение ссылочной целостности - это ответственность базы данных, а не ответственность пользовательского интерфейса. Надеюсь, вы не тратите время на блокирование потока пользовательского интерфейса, чтобы гарантировать такую ​​целостность? Возможно, даже стоит иметь две копии данных, одну для пользовательского интерфейса и одну для дельта-обновлений. После каждого обновления сделайте копию свежих данных (в это время, третью копию), заблокируйте, замените копию копией пользовательского интерфейса (это мгновенно - замените указатель на корневой узел), разблокируйте и отбросьте старые данные пользовательского интерфейса. – MSalters

Смежные вопросы