Добавление централизованной базы данных для существующего приложения C# Win

У нас есть приложение для Windows с локальной базой данных. Мало кто из наших клиентов запрашивает централизованный отчет со всего своего местоположения. Наше предлагаемое решение - иметь центральную базу данных в головном офисе клиента по статическому IP и синхронизировать все данные с помощью службы WCF.

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

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

Любое альтернативное решение?

3 ответа

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

Если вы добавите столбец VersionNumber, вы будете знать, что каждая строка с VersionNumber ниже фактического VersionNumber нуждается в обновлении.

Более сложным подходом может быть добавление столбца LastUpdated TimeStamp в каждую таблицу, что может сэкономить некоторый трафик, поскольку VersionNumber может увеличиться и может содержать обновление строки, но не может! Принимая во внимание, что LastUpdated от того, что я вижу, является специфичным для строки и создает возможность извлекать (= обновлять) только те данные (= строки), которые являются более новыми, чем самая новая запись в вашей (= центральной) всей базе данных. Который на самом деле может работать как денди.

Несколько вещей для рассмотрения:

  • Почему центральная БД не всегда будет доступна?
  • Будут ли отчеты выполняться в центральной или локальной БД?
  • Требуется ли двухсторонняя синхронизация (локальная <-> центральная)?
  • Насколько надежным будет соединение во время синхронизации?

Решение, которое я недавно унаследовал, обрабатывает это следующим образом:

  • Служба Windows работает в фоновом режиме - она ​​отвечает за синхронизацию. Местного приложения нет.
  • Для центральной -> локальной синхронизации каждая запись имеет столбец last_updated (DateTime). Это обновляется до CURRENT_TIMESTAMP каждый раз, когда происходит обновление записи. Для каждой таблицы в локальной БД служба Windows проверяет наличие самой новой отметки времени записи. Запрос запускается к соответствующей таблице в центральной БД, чтобы получить какие-либо новые / обновленные записи, то есть что-то вроде SELECT * FROM central.table WHERE last_update > @lastLocalUpdate;, Все результаты вставляются / обновляются в локальной БД.
  • Для локальной -> центральной синхронизации каждая запись в локальной БД имеет только столбец is_sent (логический). Это значение false каждый раз, когда происходит локальное обновление записи. Для каждой таблицы в локальной БД служба Windows проверяет записи, которые не были отправлены в центральную БД, т.е. SELECT * FROM local.table WHERE is_sent = 0;, Все результаты вставляются / обновляются в центральной БД, а затем is_sent устанавливается в 1.

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

В моем списке пожеланий стоит полностью пересмотреть этот механизм и реализовать очередь сообщений.

РЕДАКТИРОВАТЬ: если вы настаиваете, что не хотите вносить какие-либо изменения в существующую кодовую базу, вы можете реализовать обновления last_updated / is_sent на уровне SQL и иметь синхронизацию. Сервис как совершенно отдельный проект. "Невидимые обновления" не помогут найти самое чистое решение, но, эй, выбирайте свои сражения.

Похоже, вам нужно реализовать репликацию с несколькими хозяевами или с несколькими источниками. Репликация с несколькими мастерами - очень сложное решение для реализации самостоятельно.

Я сделал это следующим образом: вам понадобятся триггеры для каждой таблицы (вставка, удаление, обновление), чтобы отслеживать все изменения, внесенные в каждую строку, в таблицу "отслеживания изменений" (вы должны убедиться, что триггеры остаются с любой БД / таблица обновлений). Таблица изменений будет нуждаться в глобально уникальном ключе (ключах) (обычно это комбинация уникального "кода сайта" и уникального идентификатора каждой строки), типа изменения, даты и времени изменения UTC, имени таблицы, идентификатора строки и статус репликации (т.е. дата отправки) каждой строки CRUD. Вы используете таблицу отслеживания изменений со службами WCF для синхронизации клиента с таблицами сервера. Вы также должны убедиться, что они содержат одни и те же данные, прежде чем запускать систему репликации (возможно, загрузив сайты db в центральную базу данных в начале).

Если вы можете переключиться на другую БД, последняя версия MariaDB включает эту функциональность "из коробки" ( https://mariadb.com/kb/en/multi-source-replication/) бесплатно. Такая функциональность на уровне базы данных значительно облегчит эту задачу.

В качестве альтернативы, в зависимости от вашего бюджета и СУБД, может быть какой-нибудь готовый продукт для репликации, чтобы помочь вам?

Другие вопросы по тегам