Вставка данных из одной таблицы (хранилище троек) в другую (таблица свойств)

У меня есть для переноса данных RDF из хранилища троек в таблицы свойств. Пример тройного хранилища и таблица свойств приведены ниже.

Triplestore

Subject Property Object
  Sub1 prop1 hello
  Sub2 prop1 hello1
  Sub3 prop1 hello2
  Sub1 prop2 world
  Sub2 prop2 world1
  Sub3 prop2 world2
  Sub4 prop3 random

Таблица свойств 1

Subject prop1 prop2
Sub1    hello world
Sub2    hello1 world1
Sub3    hello2 world2

Таблица свойств 2

Subject prop3
Sub4  random 

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

Проблема, с которой я столкнулся, - это вставка данных из хранилища троек в таблицы свойств. Есть ли способ, которым данные для определенной темы могут быть вставлены в строку таблицы свойств в одном операторе вставки. Если это невозможно сделать в одном запросе, какой способ сделать это наиболее эффективно?

Я использую python для создания дампа SQL-запросов, которые я позже запускаю на сервере postgres.


person user2303591    schedule 21.04.2013    source источник
comment
SQLFiddle образцов данных: sqlfiddle.com/#!12/391b7   -  person Craig Ringer    schedule 21.04.2013


Ответы (2)


Это легко сделать, если у вас есть известный фиксированный набор свойств. Если у вас нет известного набора фиксированных свойств, вам необходимо сгенерировать динамический SQL либо из вашего приложения, из PL / PgSQL, либо с помощью функции crosstab из расширения tablefunc.

Для фиксированных наборов свойств вы можете самостоятельно присоединиться:

http://sqlfiddle.com/#!12/391b7/6

SELECT p1."Subject", p1."Object" AS "prop1", p2."Object" AS "prop2"
FROM triplestore p1
INNER JOIN triplestore p2 ON (p1."Subject" = p2."Subject")
WHERE p1."Property" = 'prop1'
  AND p2."Property" = 'prop2'
ORDER BY p1."Subject";

SELECT p1."Subject", p1."Object" AS "prop1"
FROM triplestore p1
WHERE p1."Property" = 'prop3'
ORDER BY p1."Subject";

Чтобы превратить их в INSERTs, просто используйте INSERT ... SELECT, например:

INSERT INTO "Property Table 1"
SELECT p1."Subject", p1."Object" AS "prop1"
FROM triplestore p1
WHERE p1."Property" = 'prop3'
ORDER BY p1."Subject";
person Craig Ringer    schedule 21.04.2013

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

Если ваша проблема заключается в хранении данных ранее неизвестного формата под определенным ключом - в вашем примере это кажется предметом - я бы предложил использовать postgres contrib hstore extension. Использование этого позволит вам создать таблицу вроде

create table foo (
  id serial not null primary key,
  subject character varying not null,
  properties hstore
);

в котором поле свойств по сути является тем, что Ruby, например, называет «хешем». Вы можете вставить пары ключ / значение в это хранилище (например, из приведенного выше примера 'prop1 => hello' и выбрать его с эквивалентным синтаксисом.

Вставка довольно проста:

insert into foo (subject, properties) values ('Sub1', 'prop1=>Hello'::hstore);

Преимущество перед использованием других методов заключается в том, что hstore поддерживает индексы btree, gin и gist (все из которых при определенных предварительных условиях). В вашем случае - выполнение в основном прямых совпадений, поиск определенного значения в свойстве, даже btree работает, поскольку он поддерживает оператор равенства для hstore.

person Skazarok    schedule 21.04.2013