Предложения по проектированию для агрегации данных в реальном времени? - PullRequest
4 голосов
/ 14 июля 2010

Я хочу построить некоторые агрегирующие данные в C #, и я хотел бы, чтобы что-то было похоже на сводную таблицу в реальном времени или какой-то вид постоянно обновляемого SQL-запроса с поддержкой select, sum , average, first, where и group-by (где first в смысле LINQ «дай мне первое значение»).

Например, у меня может быть какой-то табличный объект с именем Trans со столбцами Name, Date и Total, а другая таблица с именем Price со столбцами Name и Price , Я хочу создать некоторый экземпляр Query, который выполняет (в псевдо-SQL)

select Name, sum(Total), first(Price) from Trans, Price join on Name group by Name

и передайте его Aggregator экземпляру, который имеет ссылки на источники данных. Наряду с этим я хочу зарегистрировать обратный вызов, который срабатывает всякий раз, когда строка, в которой запрос производит изменения. Таким образом, если цена для объекта с именем «XYZ» изменится, обратный вызов сработает с объектом, содержащим новые значения для этой агрегированной строки. Я также хотел бы, чтобы Aggregator был настолько эффективным, насколько это возможно, чтобы в нем была какая-то схема индексации, чтобы не требовалось сканирование таблицы при изменении значений.

Я не совсем уверен, как назвать такие вещи, и я надеюсь, что смогу реализовать что-то полностью в C #, предполагая, что это не на порядок сложнее, чем я думаю, что это могло бы быть. Я читал о Continuous LINQ и Bindable LINQ, но я не мог по-настоящему ощутить, подходит ли либо эта проблема, или возникнут проблемы с производительностью (например, агрегаты LINQ, перечисляющие всю таблицу при каждом изменении значения).

Кто-нибудь знает о проекте, который делает что-то подобное, на которое я мог бы взглянуть, или есть предложения о том, как спроектировать / собрать его самостоятельно?

edit: я должен отметить, что данные на самом деле не были бы в базе данных, они были бы в памяти.

Ответы [ 3 ]

3 голосов
/ 14 июля 2010

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

Я делаю это с моим приложением для балансирования банка, всякий раз, когда я вставляю / изменяю / удаляю транзакцию, логика также обновляет баланс счетапотому что баланс просматривается много раз и вскоре может стать дорогостоящим для расчета при большом количестве транзакций.

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

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

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

1 голос
/ 14 июля 2010

Вы смотрели на Push Linq или Reactive Extensions (Rx) ?

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

Дополнительную информацию о Rx можно найти на сайте DevLabs:

http://msdn.microsoft.com/en-us/devlabs/ee794896.aspx

0 голосов
/ 17 апреля 2013

Существует более активно разработанный проект под названием OLinq, который вы также можете попробовать

http://nuget.org/packages/OLinq

...