Решение базы данных для статических данных временных рядов

У нас есть большой и растущий набор данных экспериментальных данных, взятых из примерно 30 000 предметов. Для каждого объекта есть несколько записей данных. В каждой записи имеется коллекция нескольких временных рядов физиологических данных, каждая около 90 секунд и выборка на частоте 250 Гц. Я должен отметить, что любой данный экземпляр временного ряда никогда не расширяется, только дополнительные записи добавляются в набор данных. Эти записи имеют не все одинаковые длины. В настоящее время данные для каждой записи содержатся в собственном плоском файле. Эти файлы организованы в структуре каталогов, которая разбивается иерархически по версии общего эксперимента, местоположения эксперимента, даты и терминала эксперимента (в этом иерархическом порядке).

Большая часть нашего анализа выполняется в MATLAB, и мы планируем продолжать использовать MATLAB для дальнейшего анализа. Ситуация в ее нынешнем виде была работоспособной (если это было нежелательно), когда все исследователи были совместно расположены. Мы теперь распространились по всему миру, и я изучаю лучшее решение, чтобы сделать все эти данные доступными из удаленных мест. Я хорошо разбираюсь в MySQL и SQL Server и могу легко создать способ структурировать эти данные в рамках такой парадигмы. Однако я скептически отношусь к эффективности этого подхода. Я бы оценил любые предложения, которые могли бы указать мне в правильном направлении. Должен ли я рассматривать что-то другое? База данных временных рядов (хотя мне кажется, что меня настраивают на расширение существующих временных рядов)? Что-то еще?

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

Обновление:

В моих исследованиях я нашел эту статью, где они хранят и анализируют очень похожие сигналы. Они выбрали MongoDB по следующим причинам:

  • Скорость разработки
  • Легкость добавления полей в существующие документы (функции, извлеченные из сигналов и т.д.)
  • Простота использования MapReduce через сам интерфейс MongoDB

Это все привлекательные преимущества для меня. Развитие выглядит мертвым простым, и способность легко дополнять существующие документы с результатами анализа явно полезна (хотя я знаю, что это не совсем сложно сделать в тех системах, с которыми я уже знаком.

Чтобы быть ясным, я знаю, что я могу оставить данные, хранящиеся в плоских файлах, и я знаю, что могу просто организовать безопасный доступ к этим плоским файлам через MATLAB по сети. Есть множество причин, по которым я хочу хранить эти данные в базе данных. Например:

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

Долгое и короткое, что я хочу хранить эти данные в базе данных по множеству причин (пространство, эффективность и простота доступа, среди многих других).

Обновление 2

Кажется, я недостаточно описываю характер этих данных, поэтому я попытаюсь прояснить. Эти записи, безусловно, являются данными временного ряда, но не так, как многие люди думают о временных рядах. Я не постоянно собираю данные для добавления в существующие временные ряды. Я действительно делаю несколько записей, все с разными метаданными, но из тех же трех сигналов. Эти сигналы можно рассматривать как вектор чисел, и длина этих векторов варьируется от записи до записи. В традиционной СУБД я мог бы создать одну таблицу для записи типа A, одну для B и т.д. И рассматривать каждую строку как точку данных в временном ряду. Однако это не работает, поскольку записи различаются по длине. Скорее, я предпочел бы иметь сущность, которая представляет человека, и связать этот объект с несколькими записями, взятыми у этого человека. Вот почему я рассмотрел MongoDB, так как я могу вложить несколько массивов (различной длины) в один объект в коллекции.

Потенциальная структура MongoDB

В качестве примера, вот что я набросал как потенциальную структуру BSON MongoDB для субъекта:

{
    "songs": 
    {
        "order": 
        [
            "R008",
            "R017",
            "T015"
        ],
        "times": [
            { 
                "start": "2012-07-02T17:38:56.000Z",
                "finish": "2012-07-02T17:40:56.000Z",
                "duration": 119188.445
            },
            { 
                "start": "2012-07-02T17:42:22.000Z",
                "finish": "2012-07-02T17:43:41.000Z",
                "duration": 79593.648
            },
            { 
                "start": "2012-07-02T17:44:37.000Z",
                "finish": "2012-07-02T17:46:19.000Z",
                "duration": 102450.695
            }
        ] 
    },
    "self_report":
    {
        "music_styles":
        {
                "none": false,
                "world": true
        },
        "songs":
        [
            {
                "engagement": 4,
                "positivity": 4,
                "activity": 3,
                "power": 4,
                "chills": 4,
                "like": 4,
                "familiarity": 4
            },
            {
                "engagement": 4,
                "positivity": 4,
                "activity": 3,
                "power": 4,
                "chills": 4,
                "like": 4,
                "familiarity": 3
            },
            {
                "engagement": 2,
                "positivity": 1,
                "activity": 2,
                "power": 2,
                "chills": 4,
                "like": 1,
                "familiarity": 1
            }
        ],
        "most_engaged": 1,
        "most_enjoyed": 1,
        "emotion_indices":
        [
            0.729994,
            0.471576,
            28.9082
        ]
    },
    "signals":
    {
        "test":
        {
            "timestamps":
            [
                0.010, 0.010, 0.021, ...
            ],
            "eda":
            [
                149.200, 149.200, 149.200, ...
            ],
            "pox":
            [
                86.957, 86.957, 86.957, ...
            ]
        },
        "songs":
        [
            {
                "timestamps":
                [
                    0.010, 0.010, 0.021, ...
                ],
                "eda":
                [
                    149.200, 149.200, 149.200, ...
                ],
                "pox":
                [
                    86.957, 86.957, 86.957, ...
                ]
            },
            {
                "timestamps":
                [
                    0.010, 0.010, 0.021, ...
                ],
                "eda":
                [
                    149.200, 149.200, 149.200, ...
                ],
                "pox":
                [
                    86.957, 86.957, 86.957, ...
                ]
            },
            {
                "timestamps":
                [
                    0.010, 0.010, 0.021, ...
                ],
                "eda":
                [
                    149.200, 149.200, 149.200, ...
                ],
                "pox":
                [
                    86.957, 86.957, 86.957, ...
                ]
            }
        ]
    },
    "demographics":
    {
        "gender": "female",
        "dob": 1980,
        "nationality": "rest of the world",
        "musical_background": false,
        "musical_expertise": 1,
        "impairments":
        {
            "hearing": false,
            "visual": false
        }
    },
    "timestamps":
    {
        "start": "2012-07-02T17:37:47.000Z",
        "test": "2012-07-02T17:38:16.000Z",
        "end": "2012-07-02T17:46:56.000Z"
    }
}

Те signal - это временные ряды.

Ответ 1

Довольно часто, когда люди приходят в базы данных NoSQL, они приходят к нему, слушая, что нет никакой схемы и жизни. Однако ИМХО это действительно неправильное понятие.

При работе с NoSQL вы должны думать в терминах "агрегатов". Как правило, совокупность будет организацией, которая может работать как единое целое. В вашем случае один возможный (но не такой эффективный) способ заключается в моделировании пользователя и его/ее данных как единого агрегата. Это гарантирует, что ваш агрегат пользователя может быть агностиком центра обработки данных/осколка. Но если данные будут расти - загрузка пользователя также загрузит все связанные данные и станет свистком памяти. (Монго как таковой немного жадный в памяти)

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

Место, где проявляется MongoDb, - это та часть, где вы можете делать adhoc-запросы с помощью свойства в документе (вы создадите индекс для этого свойства, если вы не хотите терять волосы позже по дороге). Вы не ошибетесь в своем выборе для хранения данных временных рядов в Монго. Вы можете извлекать данные, которые соответствуют идентификатору, в пределах диапазона дат, например, без каких-либо крупных трюков.

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

Ответ 2

Я чувствую, что это может не отвечать на правильный вопрос, но вот что я, вероятно, захочу (используя SQL-сервер):

Пользователь (таблица)

  • UserId
  • Пол
  • Экспертиза
  • и т.д...

Пример (таблица)

  • SampleId
  • UserId
  • СтарТайм
  • Продолжительность
  • Заказ
  • и т.д...

Серия (таблица)

  • SampleId
  • SecondNumber (около 1-90)
  • Значения (строка со значениями)

Я думаю, что это должно дать вам довольно гибкий доступ, а также разумную эффективность памяти. Поскольку значения хранятся в строковом формате, вы не можете выполнять анализ на тайм-серверах в sql (сначала их нужно разобрать), но я не думаю, что это должно быть проблемой. Конечно, вы также можете использовать MeasurementNumber и Value, тогда у вас есть полная свобода.

Конечно, это не так полно, как ваша установка MongoDB, но пробелы должны быть довольно легко заполнены.

Ответ 3

Вы должны действительно исследовать LDAP и его модель данных. Для ваших данных явно характерен иерархический характер, и LDAP уже обычно используется для хранения атрибутов о людях. Это зрелый, стандартизованный сетевой протокол, поэтому вы можете выбирать из множества реализаций, а не быть привязанным к определенному варианту выбора NoSQL в месяц. LDAP предназначен для распределенного доступа, обеспечивает модель безопасности для аутентификации (а также авторизацию/контроль доступа) и чрезвычайно эффективен. Более того, чем любой из этих HTTP-протоколов.