наиболее эффективно (производительность запросов и
потребление памяти)
Под этим вы, вероятно, подразумеваете что-то, что хорошо сбалансировано между ними. Кроме того, я думаю, что вставка данных должна быть быстрой.
Самым простым и, возможно, достаточным решением будет использование IMO в виде простого массива, поскольку это наиболее сжатая несжатая форма, в которой можно хранить данные. Таким образом, каждый элемент массива содержит timestamp, id and value
.
Когда вы запрашиваете данные с двумя отметками времени begin
и end
, вы определяете расположение отметок времени в массиве, используя binary search
. Затем вы пересекаете все элементы и выбираете только те, которые имеют идентификаторы источников данных, которые вас интересуют. Элементы массива, конечно, должны быть упорядочены по временным меткам.
- Данные занимают O (n) памяти, где количество записей журнала равно n.
- Данные вставляются в O (1)
- Извлечение данных должно быть примерно таким: O (2 * log (n) + n * m), где n - количество элементов. Если у вас есть больше источников данных, которые вы хотите включить в запрос, вы можете сохранить идентификаторы источника данных в наборе, поэтому сложность будет O (2 * log (n) + n * log (m)).
Конечно, есть и другие возможности, которые могут включать хранение транзакций в деревьях, хеш-таблицах или в чем-то, что смешивает их со списками для получения более детального баланса между производительностью / потреблением памяти.
Также проблемы возникают, когда количество логов велико. В этом случае вы должны разбить массив на файлы и сохранить начальную / конечную метки времени, когда файлы содержат журналы. Тогда реализация становится немного более сложной.
Надеюсь, это поможет вам выбрать наилучшую структуру данных / реализацию для вашего решения.