Динамическое проектирование базы данных для пространственно-временных данных переменной длины в Oracle (требуется проектирование схемы) - PullRequest
2 голосов
/ 17 декабря 2011

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

Исследование ведется на метеорологических данных, поэтому атрибуты данных - это температура, влажность, давление, скорость ветра, направление ветра и т. Д. Число атрибутов нам ранее неизвестно, в зависимости от того, что нам может потребоваться добавить больше. Атрибуты (Таблица, имеющая динамический атрибут и различную природу типа данных). Снова данные собираются из разных мест, с разной высоты и в течение определенного времени, а также временного интервала.

Итак, что должно быть лучшим способом для разработки схемы для требования? Мы должны эффективно выяснить отношения.

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

Пример данных в табличном формате -

location | time                | height | pressure | temparature | wind-direction | ...
L1       | 2011-12-18 08:04:02 | 7      | 1009.6   | 28.3        | east           | ...
L1       | 2011-12-18 08:04:02 | 15     | 1008.6   | 27.9        | east           | ...
L1       | 2011-12-18 08:04:02 | 27     | 1007.4   | 27.4        | east           | ...
L1       | 2011-12-18 08:04:04 | 7      | 1010.2   | 28.4        | north-east     | ...
L1       | 2011-12-18 08:04:04 | 15     | 1009.4   | 28.2        | north-east     | ...
L1       | 2011-12-18 08:04:04 | 27     | 1008.9   | 27.6        | north-east     | ...
L2       | 2011-12-18 08:04:02 | ..... so on

Здесь мне нужно спроектировать схему для приведенных выше примеров данных, где Location - это пространственное местоположение, которое может быть реализовано с использованием типа oracle MDSYS.SDO_GEOMETRY.



Ограничения:
1) Нет атрибутов (столбец таблицы) неизвестно во время разработки. Во время выполнения может быть добавлен любой новый атрибут (скажем, влажность, показатель преломления и т. Д.). Таким образом, мы не можем спроектировать атрибут таблицы конкретной таблицы.
1.1) для этого ограничения я подумал использовать схему вроде -
tbl_attributes (attr_id_pk, attr_name, attr_type);
tbl_data (loc, время, attr_id_fk, значение);

В моем дизайне значение атрибута должно быть типа varchar, и, как я думал, я хотел бы разыграть (не очень хорошая идея).
Но найти реляционные данные с помощью этой схемы очень сложно, используя только SQL-запрос. Например я хочу найти -
1.1.1) среднее давление для местоположения L1, когда направление ветра восточное, а температура между 27-28
1.1.2) места, где давление максимально на высоте 15
1.2) Я также подумываю отредактировать схему таблицы во время выполнения, что, опять же, не очень хорошая идея.
2) Мы будем использовать приложение-загрузчик, которое позаботится об этой динамической вставке в зависимости от схемы (что бы это ни было).
3) Необходимость эффективного извлечения статистических данных, как приведено выше в примере [1.1. *].

Ответы [ 4 ]

3 голосов
/ 18 декабря 2011

Я не совсем уверен, что понимаю, что вы имеете в виду, когда говорите, что

Число атрибутов (столбец таблицы) неизвестно во время разработки.Во время выполнения может быть добавлен любой новый атрибут (скажем, влажность, показатель преломления и т. Д.).

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

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

Поэтому я бы пошел наклассическое отображение объекта в СУБД, где у вас есть:

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

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

Пример:

Заголовок

location | time                | height | source  |Key          | 
L1       | 2011-12-18 08:04:02 | 7      | team-1  | 002020013   | 
L1       | 2011-12-18 08:04:02 | 15     | team-1  | 002020017   | 
L1       | 2011-12-18 08:04:02 | 27     | Lab-X   | 002020018   | 
L1       | 2011-12-18 08:04:04 | 7      | Lab-Y   | 002020021   | 
L1       | 2011-12-18 08:04:04 | 15     | Lab-X   | 002020112   | 

Атмосферные данные(базовый)

Key       | pressure  | temp | wind-dir  | 
002020013 | 1009.6    | 28.3 | east      |
002020017 | 1019.3    | 29.2 | east      |
002020018 | 1011.6    | 26.9 | east      |

Данные датчика освещенности

Key       | refractive-ind  | albedo  | Ultraviolet  |
002020017 |         79.6    | .37865  | 7.0E-34      |
002020018 |         67.4    | .85955  | 6.5E-34      |
002020021 |         91.6    | .98494  | 8.1E-34      |

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

Я считаю, что это более эффективно, чем использование текстовых полей с CSV внутри, или двоичных объектов данных или использование ассоциаций ключ-значение.

1 голос
/ 21 февраля 2013

Это звучит как домашнее задание, предметом которого являются: варианты использования для отказа от строгих принципов проектирования нормальных форм.

Решение этой головоломки состоит в разработке трехэтапного решения. Этап 1 - адаптивность во время выполнения с использованием гибкого подхода AttributeType, AttributeValue, так что быстро поступающие данные могут быть захвачены и временно помещены куда-то квазиструктурированным образом. Этап 2 включает в себя анализ этих данных времени выполнения, чтобы увидеть, где модель должна быть расширена с помощью дополнительных столбцов и таблиц проверки для размещения любых новых атрибутов. Этап 3 - импорт еще не импортированных данных в пересмотренную модель, что никогда не ослабляет строгие ограничения на тип данных и декларативные ограничения ссылочной целостности.

Как говорится: жизнь, друзья, это компромисс.

1 голос
/ 20 декабря 2011

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

Концептуальная модель

  1. Для динамичности - (номер столбца не определен ранее) Я создал 4 таблицы следующим образом -
    • геолокация (locid int, имя varchar, geometry пространственный_тип) - для хранения информации о конкретном местоположении, может быть определена с пространственным элементом.
    • met_loc_event (loceventid int, locid * int, метка времени record_time, высота с плавающей точкой) - это для определения перикулярного события в месте с внезапной высотой.
    • metfeatures (featureid int, имя varchar, тип varchar) - для хранения деталей объекта (т. е. столбца) с типом данных, это поле типа поможет преобразовать данные по мере необходимости.
    • metstore (loceventid * int, featureid * int, value varchar) - для хранения значения атома для объекта в определенное время.До этого я проектирую ориентацию столбцов для хранения динамического характера таблицы.Но, как вы предполагаете, это не очень хороший дизайн для запроса (некоторые не будут работать как арифметические функции) базы данных.Это также не хорошо, если мы рассматриваем производительность.
  2. Для эффективного запроса требуется (чтобы избежать большого количества объединений и избежать приведения значения во время запроса) - я расширяю модель с помощью некоторого вспомогательного представления.написать процедуру хранения для генерации представлений из хранимой базы данных.
    • Сначала я создал представления для каждого объекта (взяв значение из таблицы пространственных объектов, поэтому изначально ни одно из представлений не будет представлением объектов) с помощью таблиц met_loc_event, metfeatures и metstore.Эти представления хранят locid, record_time, height и caste value в соответствии с типом объекта
    • Далее из этих представлений я создал ориентированное на строки представление named metrelview - которые состоят из всех строк данных отношения, как и обычная таблица.Я планировал запустить запрос к представлению, поэтому производительность запроса будет улучшена.
    • Эта процедура генерации представления должна выполняться всякий раз, когда в таблице объектов будет какая-либо операция вставки, обновления или удаления.

Ниже приведена процедура MySQL, которую я разработал для генерации представления

CREATE PROCEDURE `buildModel`()
BEGIN
    DECLARE done INT DEFAULT FALSE;
    DECLARE fid INTEGER;
    DECLARE fname VARCHAR(45);
    DECLARE ftype VARCHAR(45);
    DECLARE cur_fatures CURSOR FOR SELECT `featureid`, `name`, `type` FROM `metfeatures`;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
    SET @viewAlias = 'v_';
    SET @metRelView = "metrelview";
    SET @stmtCols = "";
    SET @stmtJoin = "";

    START TRANSACTION;

    OPEN cur_fatures;
    read_loop: LOOP
        FETCH cur_fatures INTO fid, fname, ftype;
        IF done THEN
            LEAVE read_loop;
        END IF;
        IF fname IS NOT NULL THEN
            SET @featureView = CONCAT(@viewAlias, LOWER(fname));
            IF ftype = 'float' THEN
                SET @featureCastStr = "`value`+0.0";
            ELSEIF ftype = 'int' THEN
                SET @featureCastStr = "CAST(`value` AS SIGNED)";
            ELSE
                SET @featureCastStr = "`value`";
            END IF;

            SET @stmtDeleteView = CONCAT("DROP VIEW IF EXISTS `", @featureView, "`");
            SET @stmtCreateView = CONCAT("CREATE VIEW `", @featureView, "` AS SELECT le.`loceventid` AS loceventid, le.`locid`, le.`rectime`, le.`height`, ", @featureCastStr, " AS value FROM `metlocevent` le JOIN `metstore` ms ON (le.`loceventid`=ms.`loceventid`) WHERE ms.`featureid`=", fid);
            PREPARE stmt FROM @stmtDeleteView;
            EXECUTE stmt;
            PREPARE stmt FROM @stmtCreateView;
            EXECUTE stmt;

            SET @stmtCols = CONCAT(@stmtCols, ", ", @featureView, ".`value` AS ", @featureView);
            SET @stmtJoin = CONCAT(@stmtJoin, " ", "LEFT JOIN ", @featureView, " ON (le.`loceventid`=", @featureView,".`loceventid`)");
        END IF;
    END LOOP;

    SET @stmtDeleteView = CONCAT("DROP VIEW IF EXISTS `", @metRelView, "`");
    SET @stmtCreateView = CONCAT("CREATE VIEW `", @metRelView, "` AS SELECT le.`loceventid`, le.`locid`, le.`rectime`, le.`height`", @stmtCols, " FROM `metlocevent` le", @stmtJoin);

    PREPARE stmt FROM @stmtDeleteView;
    EXECUTE stmt;
    PREPARE stmt FROM @stmtCreateView;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;
    CLOSE cur_fatures;

    COMMIT;
END;

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

1 голос
/ 18 декабря 2011

Я бы определенно пошел с 1.2 (редактировать схему таблицы во время выполнения), по крайней мере, для начала. Любая достаточно продвинутая конфигурация неотличима от программирования; не думайте, что вы можете волшебным образом избежать внесения изменений в вашу программу.

Не бойся alter table. Да, первоначальные затраты выше - вам может понадобиться процесс (а не просто программа), чтобы ваша схема оставалась чистой. И есть некоторые потенциальные проблемы блокировки (которые имеют решения). Но если вы все сделаете правильно, вам придется заплатить цену только один раз за каждое изменение.

С совершенно общим решением вы будете платить небольшую цену за каждый запрос. Ваши запросы будут сложными, медленными, уродливыми и с большей вероятностью потерпят неудачу. Вы никогда не можете написать запрос типа select avg(value) ..., он может работать или не работать, в зависимости от того, как осуществляется доступ к данным. Вы можете использовать функцию PL / SQL для перехвата исключений или использовать встроенные представления и подсказки для принудительного определения определенного шаблона доступа. В любом случае, ваши запросы сложнее и медленнее, и вы должны убедиться, что все понимают эти проблемы, прежде чем использовать данные.

А с универсальным решением оптимизатор будет отстой, потому что он ничего не знает о ваших данных. Oracle не может предсказать, сколько строк будет возвращено where attr_name = 'temperature' and is_number(value) = 28.4. Но это может сделать очень хорошее предположение для where temperature = 28.4. У вас может быть значительно больше плохих планов (например, медленные запросы) с общими столбцами.

...