2009-03-28 3 views
4

Описание проблемы: В моем приложении я должен представить содержимое пакетов данных в определенном формате. Пример:Хранение пакетов данных в базе данных

Пример Любой упакованы двоичные данные, например: заголовок 4 байта, 4 байта (тип коды типа, имеющие заранее определенные значения), то адрес источника, адрес получателя, и так далее.

Раньше я делал домашние готовые реализации, которые сохраняли данные в двоичном файле (фиксированная длина записи допускала быстрый поиск), но со временем я понял, что я изобретаю какую-то базу данных. Например, я реализую свой собственный эффективный формат двоичного хранения для очень больших файлов данных. Я также внедряю свою собственную индексацию для быстрого поиска запросов в некоторых полях. Я думаю, что реальная БД (даже простой SQLite) может сделать этот материал прозрачным.

Вопрос №1: БД полезны для хранения таких данных и как это сделать? Обратите внимание, что здесь нет сопоставлений от одного до многих, много-ко-многим и других продвинутых вещей, это просто простая последовательность пакетов с определенной внутренней структурой, которую я хочу отобразить пользователю, и позволить ему взаимодействовать (т.е. искать по определенному полю).

Вопрос № 2: Теперь предположим, что пользователь сам может указать формат его пакетов, то есть в файле конфигурации: длина каждого поля, его тип, что означают его значения (в случае перечисления) и скоро. Как мне расширить реализацию DB-backed для этого? Должен ли пользователь определять схемы БД? Должен ли файл конфигурации автоматически транслироваться в эти схемы? ORM?

Вопрос № 3: Еще более продвинутый ... Теперь предположим, что пакеты данных могут варьироваться по длине и содержимому. I.e., для пакетов типа 2 есть некоторое поле для типа # 3, некоторые другие поля и т. Д. Но мне все равно понравилось, чтобы мое приложение обрабатывало его, отображая все красиво, а также позволяя пользователям указывать форматы в файлах конфигурации. Как это делается?

Заранее спасибо.

+0

Какие проблемы вы видите при выполнении чего-то простого, например http://code.activestate.com/recipes/252531/? Вы спрашиваете, есть ли такая реализация генерации схемы из файлов конфигурации? –

ответ

1

Вопрос № 1: есть DB полезны для хранения таких данных и как это должно быть сделано ?

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

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

"product table, many kind of product, each product have many parameters."

Для вашего приложения, я бы выбрал Concrete Table Inheritance дизайн

Вопрос № 2:. Теперь предположим, что пользователь сам может указать формат его пакетов, то есть в конфигурационном файле: длина каждое поле, его типа, , что его значения означают (в случае перечисления ) и так далее. Как расширить DB поддерживаемой реализации для этого?

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

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

Вы также можете определить ограничения, чтобы некоторые поля были обязательными (NOT NULL) или их значения, ограниченные поисковыми таблицами. Опять же, использование возможностей базы данных для использования метаданных для обеспечения согласованной структуры, где это желательно.

SQL уже поддерживает стандартный декларативный язык для указания полей с типами данных, ограничениями и т. Д. Зачем разрабатывать другой язык, который затем нужно перевести на SQL?

Вопрос № 3: Даже более продвинутые ... Теперь предположим, что пакеты данных могут быть разной длины и содержания.

Поля, которые являются необязательными в заданном типе пакета, должны содержать NULL в соответствующем столбце.

+0

Возможно, это лучше решить с помощью ORM, например SQLAlchemy, или это не имеет отношения к моим потребностям? –

+0

также, не могли бы вы прояснить, что вы подразумеваете под «умением управлять метаданными»? какие комплекты метаданных мне лучше всего здесь? –

+0

По метаданным я имею в виду таблицу, состоящую из столбцов и ограничений. СУРБД использует метаданные для обеспечения соблюдения типов данных, NOT NULL, ссылочной целостности и т. Д. –

0

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

  1. Таблица с определениями столбцов - назовите ее tblColumnDefs. В этой таблице содержатся такие столбцы, как «Имя», «Тип», «Длина» и «Описание»
  2. Мастер-таблица экземпляра (tblPacketNames). По существу, просто «PacketTypeID», «PacketName» и «Описание» для каждого типа пакета, который вы определяете.
  3. Таблица определения экземпляра (для вас это будет tblPacketColumns). Эта таблица собирает предварительно определенные столбцы вместе, чтобы сформировать структуру данных, которую вы храните. Например, он может содержать «PacketTypeID», «ColumnNumber», «ColumnID». В нормализации базы данных - это таблица много-ко-многим, поскольку она сопоставляет столбцы с используемыми ими пакетами.
  4. Во второй базе данных (из-за динамических последствий SQL/инъекций этого шага) таблицы динамически создаются для хранения фактических данных. Например, если вы определили (в шагах 2/3) тип пакета, называемый «PING», у вас может быть таблица с названием «PING» в вашей базе данных для хранения этих данных. Вы должны использовать tblPacketColumns, связанные с tblColumnDefs, чтобы выяснить, какие типы полей создавать и насколько они велики. В итоге вы получите набор таблиц, соответствующих определениям типа пакета, начиная с шага 3, используя столбцы с шага 1.

Примечание: Я не особенно, как последствия SQL-инъекции на шаг 4. Создание таблиц динамически может привести к некоторым последствиям, если безопасность не должным образом продумана и вход от любого введенного пользователя полей в приложение не очищается должным образом, особенно если это приложение имеет интерфейс, доступный для ненадежных абонентов (т. е. Интернета).

Используя это, вы можете создавать индексы, однако, если вы создаете таблицы (возможно, на шаге 1 есть столбец, где вы указываете определенные столбцы как «индексируемые», а индексы создаются поверх них, когда таблицы

1

Простым правилом является следующее: если вы собираетесь запрашивать данные, то это должно быть дискретное поле внутри таблицы в БД. Если нет, вы можете сохранить BLOB и сделать с ним.

Тем не менее, если вы хотите получить «метаданные» из BLOB, и индекс тО, то вы можете сделать это легко, как хорошо.

Если ваши типы данных согласуются с тем, что база данных может поддерживать (или может быть точно преобразована), может быть какое-то значение - это взрыв BLOB в его составные части, которые хорошо вписываются в столбцы DB.

Проблема с определением «таблиц на лету» (что может быть легко сделано) не столько определение таблицы, сколько потенциальное изменение таблицы. Таблицы, которые меняются (то есть столбцы, добавленные или отброшенные и т. Д.), Как правило, непригодны для использования во время изменения. Не проблема для 100 строк. Реальная проблема для миллионов строк.

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

Что касается «разных строк разных типов», вы можете поместить эти данные в одну таблицу. Некоторые строки имеют «неиспользуемые» столбцы по сравнению с другими, каждая строка идентифицируется по типу. Если у вас много определений строк и много вариаций, вы получаете много потраченного впустую пространства, делая это. Затем вы можете захотеть получить таблицу для каждого типа строки и главную таблицу, которая содержит типы строк и ссылки на реальные строки в фактических таблицах. Вам понадобится только эта мастер-таблица, если вам понадобятся отношения исходных пакетов данных друг с другом (тогда вы можете сохранить их в порядке получения, например, и т. Д.).

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

1

Другой вариант, который вы, возможно, пожелаете рассмотреть, - Berkeley DB или один из его клонов. BDB довольно низкий уровень, SQL не существует. Это довольно маленькая, очень быстрая хэш-таблица с файловой поддержкой. Это было навсегда, и используется во многих местах, где скорость и простота имеют первостепенное значение. Однако вам нужно добавить некоторые функции сверху, чтобы делать то, что вы пытаетесь выполнить.

1

Несмотря на то, что вы заявили, что не существует 1-много отношений, есть :)

я рекомендовал бы создать две таблицы для хранения пакетов. Один для хранения «заголовка» или «скалярной» информации, который является общим для пакета, и - хотя он может определять данные WHAT, - это не фактические данные, хранящиеся в пакете.

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

create table packet 
(
    packet_id int identity(1, 1) primary key, 
    destination varchar(50), 
    sender varchar(50), 
    packet_type_id int not null 
) 

create table packet_field 
(
    packet_field_id int identity(1, 1) primary key, 
    packet_id int not null references packet (packet_id), 
    field_id int not null, 
    data varbinary(500) 
) 

Очевидно, что эти две таблицы предположений о типе и размере данных, хранящихся и не являются исчерпывающими в том, что они должны будут хранить. Однако эта фундаментальная структура позволит использовать динамически определенные форматы пакетов и представляет собой схему, которая легко индексируется (например, добавление индекса на packet_id+field_id в packet_field было бы без проблем).

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

Конечно, с этого момента вам понадобятся таблицы, которые хранят фактический формат пакета. Что-то вроде ...

create table packet_type 
(
    packet_type_id int identity(1, 1) primary key, 
    name varchar(200) not null 
) 

create table packet_type_field 
(
    field_id int identity(1, 1) primary key, 
    packet_type_id int not null references packet_type (packet_type_id) 
    field_offset int not null, 
    name varchar(200) not null 
) 

Опять же, очевидно, упрощенный, но он показывает основную идею. У вас будет одна запись в вашей таблице packet_type для каждого формата пакета и одна строка в packet_type_field для каждого поля в данном пакете. Это должно дать вам большую часть информации, которая вам понадобится, чтобы обрабатывать произвольный фрагмент двоичных данных в вышеупомянутой схеме хранения пакетов.

1

Три метода приходят на ум.

sFlow и IPFlow могут передавать ограниченный набор содержимого пакета. Это может быть зарегистрировано непосредственно в нескольких разных базах данных.

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

ngrep также может захватывать выборочные данные прямо с провода.

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