SlideShare a Scribd company logo
1 of 72
Download to read offline
Слабо-структурированные данные в СУБД
PostgreSQL (мастер-класс)
Александр Коротков, Иван Панченко
Postgres Professional
2015
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 1 / 72
1. Немного о массивах
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 2 / 72
Исходные данные: products
# d product
Table ”public.product”
Column | Type | Modifiers
---------------------+-----------------+-----------
product_id | character(10) | not null
product_title | text | not null
product_sales_rank | bigint | not null
product_group | text | not null
product_category | text |
product_subcategory | text |
similar_product_ids | character(10)[] | not null
Indexes:
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 3 / 72
Subscrip on – вытащить элемент по
заданному индексу
# SELECT product_id, similar_product_ids
FROM product LIMIT 5;
product_id | similar_product_ids
------------+----------------------------------------------------------
0001047655 | {0061007129,0061007358,0061007137,0061099341,0061007161}
0001053736 | {0440905605,0345336062,0140380531,0393320979,0395898714}
0001053744 | {}
0001054600 | {}
0001474103 | {0895403889,0001473123,0766177610,0001472933,0766187403}
(5 rows)
# SELECT product_id, similar_product_ids[2]
FROM product LIMIT 5;
product_id | similar_product_ids
------------+---------------------
0001047655 | 0061007358
0001053736 | 0345336062
0001053744 | NULL
0001054600 | NULL
0001474103 | 0001473123
(5 rows)
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 4 / 72
Subscrip on – вытащить slice
# SELECT product_id, similar_product_ids[1:2]
FROM product LIMIT 5;
product_id | similar_product_ids
------------+-------------------------
0001047655 | {0061007129,0061007358}
0001053736 | {0440905605,0345336062}
0001053744 | {}
0001054600 | {}
0001474103 | {0895403889,0001473123}
(5 rows)
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 5 / 72
Subscrip on – обновление
# UPDATE product
SET similar_product_ids[1] = ’0061007129’
WHERE product_id = ’0001047655’;
# UPDATE product
SET similar_product_ids[1:2] = ’{0440905605,0345336062}’
WHERE product_id = ’0001047655’;
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 6 / 72
Осторожно – произвольные границы!
# SELECT (’[-3:-2]={1,2}’::int[])[1];
int4
------
NULL
(1 row)
# SELECT (’[-3:-2]={1,2}’::int[])[-2];
int4
------
2
(1 row)
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 7 / 72
Осторожно – многомерные массивы!
# SELECT (’{{1,2},{3,4}}’::int[])[1];
int4
------
NULL
(1 row)
# SELECT (’{{1,2},{3,4}}’::int[])[1][2];
int4
------
2
(1 row)
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 8 / 72
array_lower и array_upper – верхняя и
нижняя границы массива
Откусываем у массива первый элемент.
# SELECT product_id,
similar_product_ids[
array_lower(similar_product_ids,1) + 1 :
array_upper(similar_product_ids,1)]
FROM product LIMIT 5;
product_id | similar_product_ids
------------+-----------------------------------------------
0001047655 | {0061007358,0061007137,0061099341,0061007161}
0001053736 | {0345336062,0140380531,0393320979,0395898714}
0001053744 | NULL
0001054600 | NULL
0001474103 | {0001473123,0766177610,0001472933,0766187403}
(5 rows)
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 9 / 72
Поиск по массиву: ANY
# SELECT product_id, product_title
FROM product WHERE ’0061007137’ = ANY(similar_product_ids);
product_id | product_title
------------+------------------------------------
0001047655 | Prodigal Daughter
0061007129 | Kane & Abel
0061007145 | The Prodigal Daughter
0061007161 | First Among Equals
0061007358 | Not a Penny More, Not a Penny Less
0061013315 | The Eleventh Commandment
0061013706 | Shall We Tell the President?
0061092045 | Honor Among Thieves
0061093653 | Twelve Red Herrings
0061099341 | As the Crow Flies
(10 rows)
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 10 / 72
Разворачивание массива в rowset: unnest
# SELECT unnest(similar_product_ids)
FROM product WHERE product_id = ’0061007137’;
unnest
------------
0061007358
0061099341
0061007145
0061007161
0061007129
(5 rows)
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 11 / 72
Сворачивание rowset в массив: array_agg
# SELECT array_agg(product_id)
FROM product
WHERE ’0061093653’ = ANY(similar_product_ids);
array_agg
-----------------------------------------------
{006018552X,0060185805,006100717X,0061032077}
(1 row)
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 12 / 72
Задача #1
Для каждого продукта собрать массив тех,
которые ссылаются на него через
similar_product_ids.
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 13 / 72
Задача #1: решение
SELECT
similar_id,
array_agg(product_id)
FROM (
SELECT
product_id,
unnest(similar_product_ids) AS similar_id
FROM
product) s
GROUP BY
similar_id;
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 14 / 72
Задача #2
Сделать выборку продуктов, для которых
все продукты, указанные в массиве
similar_product_ids имеют рейтинг не
меньше 100000.
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 15 / 72
Задача #2: решение
SELECT
*
FROM
product p1
WHERE NOT EXISTS (
SELECT
1
FROM
unnest(p1.similar_product_ids) sid
JOIN
product p2
ON
p2.product_id = sid
WHERE
NOT (p2.product_sales_rank >= 100000));
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 16 / 72
Операторы &&, @>, <@ (1/2)
▶ a && b – у массивов a и b есть хотя бы один
общий элемент.
▶ a @> b – в массиве a есть все элементы массива b
и, быть может, другие.
▶ a <@ b – то же, что и b @> a.
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 17 / 72
Операторы &&, @>, <@ (2/2)
# SELECT count(*) FROM product
WHERE similar_product_ids && ’{0061007137,0007149689}’;
count
-------
11
(1 row)
# SELECT count(*) FROM product
WHERE similar_product_ids @> ’{0061007137,0061007161}’;
count
-------
6
(1 row)
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 18 / 72
Индексы по массивам (1/3)
▶ Встроенный GIN-индекс для массивов всех типов
(операторы &&, @>, <@, =).
▶ GiST-индекс для int[] в contrib/intarray.
▶ Индексы по конкретным элементам массива
(например, a[3]). Не очень интересно.
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 19 / 72
Индексы по массивам (2/3)
# EXPLAIN ANALYZE SELECT * FROM product
WHERE similar_product_ids @> ’{0061007137,0061007161}’;
QUERY PLAN
---------------------------------------------------------------
Seq Scan on product (cost=0.00..9348.25 rows=1 width=161) (ac
Filter: (similar_product_ids @> ’{0061007137,0061007161}’::b
Rows Removed by Filter: 253614
Planning time: 0.120 ms
Execution time: 97.547 ms
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 20 / 72
Индексы по массивам (3/3)
# CREATE INDEX product_similar_product_ids_idx
ON product USING gin (similar_product_ids);
CREATE INDEX
Time: 18795,075 ms
# EXPLAIN ANALYZE SELECT * FROM product
WHERE similar_product_ids @> ’{0061007137,0061007161}’;
---------------------------------------------------------------
Bitmap Heap Scan on product (cost=28.00..32.01 rows=1 width=1
Recheck Cond: (similar_product_ids @> ’{0061007137,006100716
Heap Blocks: exact=5
-> Bitmap Index Scan on product_similar_product_ids_idx (c
Index Cond: (similar_product_ids @> ’{0061007137,00610
Planning time: 0.123 ms
Execution time: 0.089 ms
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 21 / 72
2. Hstore
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 22 / 72
Исходные данные: stocks (1/2)
Table ”public.stocks”
Column | Type | Modifiers
----------+---------+------------------------------------------
id | integer | not null default nextval(’stocks_id_seq’:
country | text | not null
industry | text | not null
sector | text | not null
company | text | not null
ticker | text | not null
volume | integer | not null
h | hstore | not null
Indexes:
”stocks_pkey” PRIMARY KEY, btree (id)
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 23 / 72
Исходные данные: stocks (2/2)
# SELECT * FROM stocks LIMIT 1;
-[ RECORD 1 ]--------------------------------------------------
id | 1
country | USA
industry | Semiconductor Equipment & Materials
sector | Technology
company | Brooks Automation Inc.
ticker | BRKS
volume | 516739
h | ”Gap”=>”0.0151”, ”P/B”=>”1.05”, ”P/E”=>”6.07”, ”P/S”
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 24 / 72
Вытаскивание полей (1/2)
# SELECT id, h -> ’Price’, h -> ’Change’
FROM stocks LIMIT 10;
id | ?column? | ?column?
----+-------------------+----------
1 | 10.24 | 0.0291
2 | 26.94 | -0.023
3 | 92.56999999999999 | 0.0016
4 | 14.95 | 0.0047
5 | 26.65 | 0.0013
6 | 25.33 | -0.0261
7 | 62.7 | 0.0061
8 | 11.9 | -0.0017
9 | 24.44 | 0.0188
10 | 36.87 | 0.0104
(10 rows)
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 25 / 72
Вытаскивание полей (2/2)
# SELECT company FROM stocks
WHERE h -> ’Price’ > 1000.0;
ERROR: operator does not exist: text > numeric
# SELECT company FROM stocks
WHERE (h -> ’Price’)::numeric > 1000.0;
company
----------------------------
Seaboard Corp.
Berkshire Hathaway Inc.
Google Inc.
priceline.com Incorporated
(4 rows)
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 26 / 72
Превращаем hstore в набор пар
ключ-значение
# SELECT (each(h)).* FROM stocks WHERE id = 4;
key | value
-------------------------------+----------------------
Gap | 0
Price | 14.95
Change | 0.0047
50-Day Low | 0.0381
50-Day High | -0.0177
52-Week Low | 0.3304
Short Ratio | 0.14
......................................................
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 27 / 72
Задача #3
Собрать статистику по использованию
различных ключей в поле h таблицы stocks:
для каждого встречающегося ключа указать
его частоту.
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 28 / 72
Задача #3: решение
# SELECT key,
count(*)::float8 /
(SELECT count(*) FROM stocks) freq
FROM (SELECT (each(h)).* FROM stocks) kv
GROUP BY key;
key | freq
-----------------------------------+-------------------
Shares Float | 0.725725281231498
Analyst Recom | 0.616489046773239
Insider Transactions | 0.554026050917703
Institutional Transactions | 0.705743043220841
P/B | 0.71166370633511
.......................................................
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 29 / 72
Оператор @>
a @> b тогда и только тогда, когда для каждой пары
ключ => значение из b, такая же пара присутствует и в
a.
Примеры.
key1 | key2 | result
-----------------+--------------+--------
a=>x, b=>y, c=>z | a=>x, b=>y | true
a=>x, b=>y | a=>x, b=>qqq | false
a=>x, b=>y | t=>x, b=>y | false
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 30 / 72
Операторы ?, ?&, ?|
▶ a ? b – проверяет наличие ключа b в массиве a.
▶ a ?& b – проверяет наличие всех ключей из
массива b в массиве a.
▶ a ?| b – проверяет наличие хотя бы одного из
ключей массива b в массиве a.
# SELECT count(*),
count(*) FILTER
(WHERE h ? ’Short Ratio’),
count(*) FILTER
(WHERE h ?| ’{Short Ratio, Change from Open}’),
count(*) FILTER
(WHERE h ?& ’{Short Ratio, Change from Open}’)
FROM stocks;
count | count | count | count
-------+-------+-------+-------
6756 | 5412 | 6743 | 5412
(1 row)
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 31 / 72
Задача #4
Написать аналог оператора @> с помощью
функций each(hstore) и операторов ->, ?.
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 32 / 72
Задача #4: решение
CREATE FUNCTION contains_sql(hstore, hstore) RETURNS bool
AS $$
SELECT NOT EXISTS (
SELECT 1
FROM each($2) kv
WHERE NOT (
$1 ? key AND
$1 -> key IS NOT DISTINCT FROM value)
)
$$ LANGUAGE sql;
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 33 / 72
Конструируем hstore
# SELECT hstore(’{key1, key2}’::text[],
’{value1, value2}’::text[]);
hstore
------------------------------------
”key1”=>”value1”, ”key2”=>”value2”
(1 row)
# SELECT hstore(array_agg(id::text),
array_agg(company))
FROM stocks WHERE id <= 4;
hstore
------------------------------------------------------
”1”=>”Brooks Automation Inc.”, ”2”=>”Broadcom Corp.”
(1 row)
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 34 / 72
Задача #5
Посчитать для каждой отрасли (sector) из
таблицы stocks суммарный объём ценных
бумаг (volume), и выдать это в виде hstore
вида: отрасль => суммарный объём ценный
бумаг.
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 35 / 72
Задача #5: решение
# SELECT hstore(
array_agg(sector),
array_agg(volume::text)) h
FROM (SELECT sector,
SUM(volume) AS volume
FROM stocks
GROUP BY sector) s;
-[ RECORD 1 ]--------------------------------------------------------
h | ”Services”=>”637878158”, ”Financial”=>”1389743864”,
| ”Utilities”=>”94268768”, ”Healthcare”=>”381247435”,
| ”Technology”=>”1225484169”, ”Conglomerates”=>”3547704”,
| ”Consumer Goods”=>”276207382”,
| ”Basic Materials”=>”625043686”,
| ”Industrial Goods”=>”200105263”
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 36 / 72
Индексы для hstore
▶ GIN/GiST индексы: индексируем ключи отдельно,
значения отдельно (операторы @>, ?, ?&, ?|).
▶ GIN индекс: индексируем пары hash(key) +
hash(value) (операторы @>, ?, ?&, ?|)
https://github.com/postgrespro/hstore_ops
▶ Индекс по отдельному ключу (h->’key’).
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 37 / 72
3. Jsonb
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 38 / 72
Исходные данные: company
# d company
Table ”public.company”
Column | Type | Modifiers
--------+-------+-----------
js | jsonb |
# SELECT js FROM company limit 5;
---------------------------------------------------------------
{”_id”: {”$oid”: ”52cdef7c4bab8bd675297d8a”}, ”name”: ”Wetpain
{”_id”: {”$oid”: ”52cdef7c4bab8bd675297d8b”}, ”name”: ”AdventN
{”_id”: {”$oid”: ”52cdef7c4bab8bd675297d8c”}, ”name”: ”Zoho”,
{”_id”: {”$oid”: ”52cdef7c4bab8bd675297d8d”}, ”ipo”: null, ”na
{”_id”: {”$oid”: ”52cdef7c4bab8bd675297d8e”}, ”ipo”: {”pub_day
(5 rows)
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 39 / 72
Jsonb pre y print
# SELECT jsonb_pretty(js) FROM company LIMIT 1;
-[ RECORD 1 ]+-------------------------------------------
jsonb_pretty | {
| ”_id”: {
| ”$oid”: ”52cdef7c4bab8bd675297d8a”
| },
| ”name”: ”Wetpaint”,
| ”image”: {
| ”available_sizes”: [
| [
| [
| 150,
| 75
.........................................................
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 40 / 72
Вытаскивание полей
# SELECT js -> ’name’,
js -> ’acquisition’ -> ’price_amount’,
js #> ’{acquisition,price_amount}’
FROM company
LIMIT 5;
?column? | ?column? | ?column?
-------------------------+-----------+-----------
”Wetpaint” | 30000000 | 30000000
”AdventNet” | NULL | NULL
”Zoho” | NULL | NULL
”Digg” | 500000 | 500000
”Facebook” | NULL | NULL
(5 rows)
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 41 / 72
Вытаскивание полей и типы (1/2)
-> вытаскивает тип jsonb
# SELECT js -> ’name’ FROM company
WHERE js -> ’name’ ILIKE ’%paint%’;
ERROR: operator does not exist: jsonb ~~* unknown
Приведение значения поля к строке
# SELECT (js -> ’name’)::text, js ->> ’name’
FROM company LIMIT 5;
text | ?column?
-------------+-----------
”Wetpaint” | Wetpaint
”AdventNet” | AdventNet
”Zoho” | Zoho
”Digg” | Digg
”Facebook” | Facebook
(5 rows)
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 42 / 72
Вытаскивание полей и типы (2/2)
# SELECT
js ->> ’name’,
js ->> ’number_of_employees’
FROM company
WHERE
js ->> ’name’ ILIKE ’%paint%’ AND
(js ->> ’number_of_employees’)::int >= 10;
?column? | ?column?
----------+----------
Wetpaint | 47
(1 row)
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 43 / 72
Вытаскивание элементов массивов
# SELECT
js -> ’offices’ -> 0 ->> ’city’,
js #>> ’{offices,0,city}’
FROM company LIMIT 5;
?column? | ?column?
---------------+---------------
Seattle | Seattle
Pleasanton | Pleasanton
Pleasanton | Pleasanton
San Francisco | San Francisco
Menlo Park | Menlo Park
(5 rows)
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 44 / 72
Индексы по выражениям
# CREATE UNIQUE INDEX company_id_idx
ON company ((js -> ’_id’ ->> ’$oid’));
CREATE INDEX
# EXPLAIN ANALYZE SELECT js -> ’name’ FROM company
WHERE js -> ’_id’ ->> ’$oid’ = ’52cdef7c4bab8bd675297d8a’;
QUERY P
---------------------------------------------------------------
Index Scan using company_id_idx on company (cost=0.29..8.31 r
Index Cond: (((js -> ’_id’::text) ->> ’$oid’::text) = ’52cde
Planning time: 0.084 ms
Execution time: 0.156 ms
(4 rows)
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 45 / 72
Разворачивание JSON-массивов в rowset
# SELECT jsonb_array_elements(js -> ’competitions’)
FROM company
WHERE js -> ’_id’ ->> ’$oid’ = ’52cdef7c4bab8bd675297d8a’;
jsonb_array_elements
---------------------------------------------------------------------
{”competitor”: {”name”: ”Wikia”, ”permalink”: ”wikia”}}
{”competitor”: {”name”: ”JotSpot”, ”permalink”: ”jotspot”}}
{”competitor”: {”name”: ”Socialtext”, ”permalink”: ”socialtext”}}
{”competitor”: {”name”: ”Ning by Glam Media”, ”permalink”: ”ning”}}
{”competitor”: {”name”: ”Soceeo”, ”permalink”: ”soceeo”}}
{”competitor”: {”name”: ”Yola”, ”permalink”: ”yola”}}
{”competitor”: {”name”: ”SocialGO”, ”permalink”: ”socialgo”}}
{”competitor”: {”name”: ”IslamNor”, ”permalink”: ”islamnor”}}
(8 rows)
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 46 / 72
Разворачивание JSON-объекта
в key-value rowset
# SELECT (jsonb_each(js #> ’{offices, 0}’)).*
FROM company
WHERE js -> ’_id’ ->> ’$oid’ = ’52cdef7c4bab8bd675297d8a’;
key | value
--------------+--------------------
city | ”Seattle”
address1 | ”710 - 2nd Avenue”
address2 | ”Suite 1100”
latitude | 47.603122
zip_code | ”98104”
longitude | -122.333253
state_code | ”WA”
description | ””
country_code | ”USA”
(9 rows)
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 47 / 72
Оператор @>
▶ Для скалярных a и b, a @> b тогда и только тогда, когда a = b.
▶ Если a и b объекты, то для каждого ключа в b должен
существовать ключ в a, содержащий соответствующее значение.
▶ Если a и b массивы, то для каждого элемента в b должен
существовать содержащий его элемент в a.
Примеры.
arg1 | arg2 | result
---------------------+----------------------+--------
1 | 1 | true
1 | ”1” | false
{”a”: 1, ”b”: 2} | {”a”: 1} | true
{”a”: 1, ”b”: 2} | {”a”: 2} | false
[1, 2] | [1] | true
[{”a”: 1, ”b”: 2}] | [{”a”: 1}, {”b”: 2}] | true
[{”a”: 1}, {”b”: 2}] | [{”a”: 1, ”b”: 2}] | false
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 48 / 72
Установка plv8
$ git clone https://github.com/plv8/plv8.git
$ cd plv8
$ make USE_PGXS=1
$ sudo make USE_PGXS=1 install
$ make USE_PGXS=1 installcheck
$ psql DB -c ”CREATE EXTENSION plv8;”
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 49 / 72
Задача #6
Написать на plv8 функцию, которая для
компании выводит список стран, где у неё
есть офисы.
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 50 / 72
Задача #6: решение
CREATE FUNCTION extract_countries(company jsonb)
RETURNS text[]
AS $$
var tmp = {}, result = [];
for(var i = 0; i < company.offices.length; i++)
tmp[company.offices[i].country_code] = true;
for(var i in tmp)
result.push(i)
return result;
$$ LANGUAGE plv8 IMMUTABLE STRICT;
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 51 / 72
Индекс по странам
CREATE INDEX company_countries_idx ON company
USING gin(extract_countries(js));
# EXPLAIN ANALYZE SELECT * FROM company
WHERE extract_countries(js) @> ’{RUS}’;
QUER
---------------------------------------------------------------
Bitmap Heap Scan on company (cost=8.73..348.48 rows=94 width=
(actual time=0.038..0.089 rows=50 loops=1)
Recheck Cond: (extract_countries(js) @> ’{RUS}’::text[])
Heap Blocks: exact=48
-> Bitmap Index Scan on company_countries_idx (cost=0.00..
Index Cond: (extract_countries(js) @> ’{RUS}’::text[])
Planning time: 0.057 ms
Execution time: 0.113 ms
(7 rows)
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 52 / 72
Задача #7
Написать на plv8 агрегат, который который
посчитает частоты различных размеров
картинок.
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 53 / 72
Задача #7: решение (1/2)
CREATE FUNCTION image_size_agg_sfunc(state jsonb,
company jsonb) RETURNS jsonb
AS $$
if (!company.image) return state;
var sizes = company.image.available_sizes
for (var i = 0; i < sizes.length; i++)
{
var sizeKey = sizes[i][0][0] + ’x’ +
sizes[i][0][1];
if (sizeKey in state) state[sizeKey]++;
else state[sizeKey] = 1;
}
return state;
$$ LANGUAGE plv8 IMMUTABLE STRICT;
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 54 / 72
Задача #7: решение (2/2)
CREATE AGGREGATE image_size_agg (jsonb) (
SFUNC = image_size_agg_sfunc,
STYPE = jsonb,
INITCOND = ’{}’);
# SELECT image_size_agg(js) FROM company;
-[ RECORD 1 ]--+-----------------------------------------------
image_size_agg | {”1x1”: 15, ”32x8”: 3, ”150x7”: 1, ”150x8”: 5,
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 55 / 72
Установка jsquery
$ git clone https://github.com/postgrespro/jsquery.git
$ cd jsquery
$ make USE_PGXS=1
$ sudo make USE_PGXS=1 install
$ make USE_PGXS=1 installcheck
$ psql DB -c ”CREATE EXTENSION jsquery;”
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 56 / 72
Индексы для jsonb
▶ GIN jsonb_ops: индексируем ключи отдельно,
значения отдельно (операторы @>, ?, ?&, ?|).
▶ GIN jsonb_path_ops: индексируем hash(path +
value) (операторы @>).
▶ jsonb_path_value_ops: индексируем hash(path) +
hash(value) (операторы @>, jsonb @@ jsquery).
▶ jsonb_value_path_ops: индексируем hash(value) +
bloom(path) (операторы @>, jsonb @@ jsquery).
▶ Индексы по отдельным ключам (js -> ’key’).
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 57 / 72
Пример: найти комании с офисами в
России
-- Оператор @>
# SELECT js->’name’ FROM company
WHERE js @> ’{”offices”:[{”country_code”: ”RUS”}]}’;
-- Оператор jsquery
# SELECT js->’name’ FROM company
WHERE js @@ ’offices.#.country_code = ”RUS”’;
-- Разворачивание jsonb в rowset
# SELECT js->’name’ FROM company
WHERE EXISTS (
SELECT 1
FROM jsonb_array_elements(js->’offices’) el
WHERE el ->> ’country_code’ = ’RUS’);
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 58 / 72
Задача #8
Найти компании, конкуренты Wikia, у
которых есть офис в США.
Реализовать решение с помощью:
▶ оператора @>,
▶ jsquery,
▶ разворачивания jsonb в rowset.
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 59 / 72
Задача #8: решение (1/3)
-- Оператор @>
# SELECT js->’name’ FROM company
WHERE
js @>
’{”competitions”:[{”competitor”:
{”name”: ”Wikia”}
}]}’ AND
js @>
’{”offices”:[{”country_code”: ”USA”}]}’;
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 60 / 72
Задача #8: решение (2/3)
-- jsquery
# SELECT js->’name’ FROM company
WHERE js @@
’competitions.#.competitor.name = ”Wikia” AND
offices.#.country_code = ”USA”’;
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 61 / 72
Задача #8: решение (3/3)
-- Разворачивание jsonb в rowset
SELECT js->’name’ FROM company
WHERE
EXISTS (
SELECT 1
FROM jsonb_array_elements(js->’competitions’) el
WHERE el -> ’competitor’ ->> ’name’ = ’Wikia’
) AND EXISTS (
SELECT 1
FROM jsonb_array_elements(js->’offices’) el
WHERE el ->> ’country_code’ = ’USA’
);
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 62 / 72
Задача #9
Найти компании, в которые финансовая
организация Trinity Ventures инвестировала
в 2007 или 2008 году.
Реализовать решение с помощью:
▶ оператора @>,
▶ jsquery,
▶ разворачивания jsonb в rowset.
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 63 / 72
Задача #9: решение (1/3)
-- Оператор @>
# SELECT js->’name’ FROM company
WHERE
js @>
’{”funding_rounds”:[{”funded_year”: 2007,
”investments”:[{”financial_org”:
{”name”:”Trinity Ventures”}}
]}
]}’ OR
js @>
’{”funding_rounds”:[{”funded_year”: 2008,
”investments”:[{”financial_org”:
{”name”:”Trinity Ventures”}}
]}
]}’;
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 64 / 72
Задача #9: решение (2/3)
-- jsquery
# SELECT js->’name’ FROM company
WHERE
js @@
’funding_rounds.#(
funded_year IN (2007,2008) AND
investments.#.
financial_org.name = ”Trinity Ventures”)’;
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 65 / 72
Задача #9: решение (3/3)
-- Разворачивание jsonb в rowset
# SELECT js->’name’ FROM company
WHERE EXISTS (
SELECT 1
FROM jsonb_array_elements(js->’funding_rounds’) el
WHERE el -> ’funded_year’ IN (’2007’,’2008’) AND EXISTS
(SELECT 1
FROM jsonb_array_elements(el -> ’investments’) el2
WHERE el2 -> ’financial_org’ ->>
’name’ = ’Trinity Ventures’));
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 66 / 72
Задача #10
Найти компании, которые в 2008 году
привлекли более 100 000 000 USD
инвестиций.
Реализовать решение с помощью:
▶ jsquery,
▶ разворачивания jsonb в rowset.
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 67 / 72
Задача #10: решение (1/2)
-- jsquery
# SELECT js -> ’name’
FROM company
WHERE js @@
’funding_rounds.# (funded_year = 2008 AND
raised_currency_code = ”USD” AND
raised_amount > 100000000)’;
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 68 / 72
Задача #10: решение (2/2)
-- Разворачивание jsonb в rowset
# SELECT js->’name’ FROM company
WHERE EXISTS (
SELECT 1
FROM jsonb_array_elements(js->’funding_rounds’) el
WHERE
el -> ’funded_year’ = ’2008’ AND
el ->> ’raised_currency_code’ = ’USD’ AND
el -> ’raised_amount’ > ’100000000’);
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 69 / 72
Задача #11
Найти компании, у которых суммарный
объём инвестиций был более 1 000 000 000
USD.
Реализовать решение с помощью
разворачивания jsonb в rowset.
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 70 / 72
Задача #11: решение
-- Разворачивание jsonb в rowset
SELECT js->’name’ FROM company
WHERE (
SELECT SUM((el ->> ’raised_amount’)::numeric)
FROM jsonb_array_elements(js->’funding_rounds’) el
WHERE
el ->> ’raised_currency_code’ = ’USD’) > 1000000000;
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 71 / 72
Спасибо за внимание!
Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 72 / 72

More Related Content

Viewers also liked

09 01 HappyDev-lite'14 Андрей Токарев. Разработка iOS-приложений
09 01 HappyDev-lite'14 Андрей Токарев. Разработка iOS-приложений09 01 HappyDev-lite'14 Андрей Токарев. Разработка iOS-приложений
09 01 HappyDev-lite'14 Андрей Токарев. Разработка iOS-приложенийHappyDev
 
13 HappyDev-lite'14 Павел Сумароков. Ответственный подход к профессиональном...
13 HappyDev-lite'14 Павел Сумароков. Ответственный подход к профессиональном...13 HappyDev-lite'14 Павел Сумароков. Ответственный подход к профессиональном...
13 HappyDev-lite'14 Павел Сумароков. Ответственный подход к профессиональном...HappyDev
 
2015-12-06 Александр Чернышев - Технологии открытости мобильных приложений
2015-12-06 Александр Чернышев - Технологии открытости мобильных приложений2015-12-06 Александр Чернышев - Технологии открытости мобильных приложений
2015-12-06 Александр Чернышев - Технологии открытости мобильных приложенийHappyDev
 
Виталий Шибаев - Креативный менеджмент глазами разработчика: как выжить в agi...
Виталий Шибаев - Креативный менеджмент глазами разработчика: как выжить в agi...Виталий Шибаев - Креативный менеджмент глазами разработчика: как выжить в agi...
Виталий Шибаев - Креативный менеджмент глазами разработчика: как выжить в agi...HappyDev
 
Александр Кудымов - Любовь и честность в интерфейсах | HappyDev'12
Александр Кудымов - Любовь и честность в интерфейсах | HappyDev'12Александр Кудымов - Любовь и честность в интерфейсах | HappyDev'12
Александр Кудымов - Любовь и честность в интерфейсах | HappyDev'12HappyDev
 
2014.12.06 03 Геннадий Омышев — Рецепт приготовления фирменного стиля
2014.12.06 03 Геннадий Омышев — Рецепт приготовления фирменного стиля2014.12.06 03 Геннадий Омышев — Рецепт приготовления фирменного стиля
2014.12.06 03 Геннадий Омышев — Рецепт приготовления фирменного стиляHappyDev
 
2015-12-06 Сергей Хрущев - Человеческим языком о суперкомпьютерах
2015-12-06 Сергей Хрущев - Человеческим языком о суперкомпьютерах2015-12-06 Сергей Хрущев - Человеческим языком о суперкомпьютерах
2015-12-06 Сергей Хрущев - Человеческим языком о суперкомпьютерахHappyDev
 
2015-12-06 Евгений Тюменцев - Практики разработки серверных приложений
2015-12-06 Евгений Тюменцев - Практики разработки серверных приложений2015-12-06 Евгений Тюменцев - Практики разработки серверных приложений
2015-12-06 Евгений Тюменцев - Практики разработки серверных приложенийHappyDev
 
11 HappyDev-lite'14 Андрей Казимиров. Особенности разработки по для встраива...
11 HappyDev-lite'14 Андрей Казимиров. Особенности разработки по для встраива...11 HappyDev-lite'14 Андрей Казимиров. Особенности разработки по для встраива...
11 HappyDev-lite'14 Андрей Казимиров. Особенности разработки по для встраива...HappyDev
 
2015-12-06 Aнтон Непомнящих - Принципы канбан и теории ограничений на примере...
2015-12-06 Aнтон Непомнящих - Принципы канбан и теории ограничений на примере...2015-12-06 Aнтон Непомнящих - Принципы канбан и теории ограничений на примере...
2015-12-06 Aнтон Непомнящих - Принципы канбан и теории ограничений на примере...HappyDev
 
Симуляция аттестации. Максим Дорофеев.
Симуляция аттестации. Максим Дорофеев.Симуляция аттестации. Максим Дорофеев.
Симуляция аттестации. Максим Дорофеев.IT-Доминанта
 
Олег Годовых - Как учёба в универе и олимпиады не сделали мою жизнь хуже | Ha...
Олег Годовых - Как учёба в универе и олимпиады не сделали мою жизнь хуже | Ha...Олег Годовых - Как учёба в универе и олимпиады не сделали мою жизнь хуже | Ha...
Олег Годовых - Как учёба в универе и олимпиады не сделали мою жизнь хуже | Ha...HappyDev
 
2015-04-12 06 Елена Гальцина. Осознанный ты
2015-04-12 06 Елена Гальцина. Осознанный ты2015-04-12 06 Елена Гальцина. Осознанный ты
2015-04-12 06 Елена Гальцина. Осознанный тыHappyDev
 
Рамиль Шайхутдинов - Фууу, стартап! | HappyDev'12
Рамиль Шайхутдинов - Фууу, стартап! | HappyDev'12Рамиль Шайхутдинов - Фууу, стартап! | HappyDev'12
Рамиль Шайхутдинов - Фууу, стартап! | HappyDev'12HappyDev
 
2015-12-05 Максим Дорофеев - Студенческий синдром: почему мы все делаем в пос...
2015-12-05 Максим Дорофеев - Студенческий синдром: почему мы все делаем в пос...2015-12-05 Максим Дорофеев - Студенческий синдром: почему мы все делаем в пос...
2015-12-05 Максим Дорофеев - Студенческий синдром: почему мы все делаем в пос...HappyDev
 

Viewers also liked (15)

09 01 HappyDev-lite'14 Андрей Токарев. Разработка iOS-приложений
09 01 HappyDev-lite'14 Андрей Токарев. Разработка iOS-приложений09 01 HappyDev-lite'14 Андрей Токарев. Разработка iOS-приложений
09 01 HappyDev-lite'14 Андрей Токарев. Разработка iOS-приложений
 
13 HappyDev-lite'14 Павел Сумароков. Ответственный подход к профессиональном...
13 HappyDev-lite'14 Павел Сумароков. Ответственный подход к профессиональном...13 HappyDev-lite'14 Павел Сумароков. Ответственный подход к профессиональном...
13 HappyDev-lite'14 Павел Сумароков. Ответственный подход к профессиональном...
 
2015-12-06 Александр Чернышев - Технологии открытости мобильных приложений
2015-12-06 Александр Чернышев - Технологии открытости мобильных приложений2015-12-06 Александр Чернышев - Технологии открытости мобильных приложений
2015-12-06 Александр Чернышев - Технологии открытости мобильных приложений
 
Виталий Шибаев - Креативный менеджмент глазами разработчика: как выжить в agi...
Виталий Шибаев - Креативный менеджмент глазами разработчика: как выжить в agi...Виталий Шибаев - Креативный менеджмент глазами разработчика: как выжить в agi...
Виталий Шибаев - Креативный менеджмент глазами разработчика: как выжить в agi...
 
Александр Кудымов - Любовь и честность в интерфейсах | HappyDev'12
Александр Кудымов - Любовь и честность в интерфейсах | HappyDev'12Александр Кудымов - Любовь и честность в интерфейсах | HappyDev'12
Александр Кудымов - Любовь и честность в интерфейсах | HappyDev'12
 
2014.12.06 03 Геннадий Омышев — Рецепт приготовления фирменного стиля
2014.12.06 03 Геннадий Омышев — Рецепт приготовления фирменного стиля2014.12.06 03 Геннадий Омышев — Рецепт приготовления фирменного стиля
2014.12.06 03 Геннадий Омышев — Рецепт приготовления фирменного стиля
 
2015-12-06 Сергей Хрущев - Человеческим языком о суперкомпьютерах
2015-12-06 Сергей Хрущев - Человеческим языком о суперкомпьютерах2015-12-06 Сергей Хрущев - Человеческим языком о суперкомпьютерах
2015-12-06 Сергей Хрущев - Человеческим языком о суперкомпьютерах
 
2015-12-06 Евгений Тюменцев - Практики разработки серверных приложений
2015-12-06 Евгений Тюменцев - Практики разработки серверных приложений2015-12-06 Евгений Тюменцев - Практики разработки серверных приложений
2015-12-06 Евгений Тюменцев - Практики разработки серверных приложений
 
11 HappyDev-lite'14 Андрей Казимиров. Особенности разработки по для встраива...
11 HappyDev-lite'14 Андрей Казимиров. Особенности разработки по для встраива...11 HappyDev-lite'14 Андрей Казимиров. Особенности разработки по для встраива...
11 HappyDev-lite'14 Андрей Казимиров. Особенности разработки по для встраива...
 
2015-12-06 Aнтон Непомнящих - Принципы канбан и теории ограничений на примере...
2015-12-06 Aнтон Непомнящих - Принципы канбан и теории ограничений на примере...2015-12-06 Aнтон Непомнящих - Принципы канбан и теории ограничений на примере...
2015-12-06 Aнтон Непомнящих - Принципы канбан и теории ограничений на примере...
 
Симуляция аттестации. Максим Дорофеев.
Симуляция аттестации. Максим Дорофеев.Симуляция аттестации. Максим Дорофеев.
Симуляция аттестации. Максим Дорофеев.
 
Олег Годовых - Как учёба в универе и олимпиады не сделали мою жизнь хуже | Ha...
Олег Годовых - Как учёба в универе и олимпиады не сделали мою жизнь хуже | Ha...Олег Годовых - Как учёба в универе и олимпиады не сделали мою жизнь хуже | Ha...
Олег Годовых - Как учёба в универе и олимпиады не сделали мою жизнь хуже | Ha...
 
2015-04-12 06 Елена Гальцина. Осознанный ты
2015-04-12 06 Елена Гальцина. Осознанный ты2015-04-12 06 Елена Гальцина. Осознанный ты
2015-04-12 06 Елена Гальцина. Осознанный ты
 
Рамиль Шайхутдинов - Фууу, стартап! | HappyDev'12
Рамиль Шайхутдинов - Фууу, стартап! | HappyDev'12Рамиль Шайхутдинов - Фууу, стартап! | HappyDev'12
Рамиль Шайхутдинов - Фууу, стартап! | HappyDev'12
 
2015-12-05 Максим Дорофеев - Студенческий синдром: почему мы все делаем в пос...
2015-12-05 Максим Дорофеев - Студенческий синдром: почему мы все делаем в пос...2015-12-05 Максим Дорофеев - Студенческий синдром: почему мы все делаем в пос...
2015-12-05 Максим Дорофеев - Студенческий синдром: почему мы все делаем в пос...
 

Similar to 2015-12-05 Александр Коротков, Иван Панченко - Слабо-структурированные данные в СУБД глазами и руками разработчиков PostgreSQL

Новые возможности языка SQL в Firebird 3.0
Новые возможности языка SQL в Firebird 3.0Новые возможности языка SQL в Firebird 3.0
Новые возможности языка SQL в Firebird 3.0Alexey Kovyazin
 
Advanced Sql Injection
Advanced Sql InjectionAdvanced Sql Injection
Advanced Sql InjectionDmitry Evteev
 
Web осень 2013 лекция 6
Web осень 2013 лекция 6Web осень 2013 лекция 6
Web осень 2013 лекция 6Technopark
 
Дмитрий Долгов
Дмитрий ДолговДмитрий Долгов
Дмитрий ДолговCodeFest
 
Adymo Barcamp Presentation Faster Higher Sql
Adymo Barcamp Presentation Faster Higher SqlAdymo Barcamp Presentation Faster Higher Sql
Adymo Barcamp Presentation Faster Higher SqlOleksandr Petrov
 
Три вызова реляционным СУБД и новый PostgreSQL - #PostgreSQLRussia семинар по...
Три вызова реляционным СУБД и новый PostgreSQL - #PostgreSQLRussia семинар по...Три вызова реляционным СУБД и новый PostgreSQL - #PostgreSQLRussia семинар по...
Три вызова реляционным СУБД и новый PostgreSQL - #PostgreSQLRussia семинар по...Nikolay Samokhvalov
 
Tagconf 13 - SphinxSearch - 2
Tagconf 13 - SphinxSearch - 2Tagconf 13 - SphinxSearch - 2
Tagconf 13 - SphinxSearch - 2Roman Kudlay
 
Тестирование программных фильтров безопасности
Тестирование программных фильтров безопасностиТестирование программных фильтров безопасности
Тестирование программных фильтров безопасностиZestranec
 
Промышленный подход к тюнингу PostgreSQL: эксперименты над базами данных
Промышленный подход к тюнингу PostgreSQL: эксперименты над базами данныхПромышленный подход к тюнингу PostgreSQL: эксперименты над базами данных
Промышленный подход к тюнингу PostgreSQL: эксперименты над базами данныхNikolay Samokhvalov
 
Народные средства оптимизации PostgreSQL
Народные средства оптимизации PostgreSQLНародные средства оптимизации PostgreSQL
Народные средства оптимизации PostgreSQLNikolay Pisarev
 
Time series data in a relational database. TimescaleDB and PipelineDB extensi...
Time series data in a relational database. TimescaleDB and PipelineDB extensi...Time series data in a relational database. TimescaleDB and PipelineDB extensi...
Time series data in a relational database. TimescaleDB and PipelineDB extensi...Ivan Muratov
 
физическая структура хранения артемов Ready
физическая структура хранения артемов Readyфизическая структура хранения артемов Ready
физическая структура хранения артемов Readyrit2010
 
Тестирование программных фильтров безопасности
Тестирование программных фильтров безопасностиТестирование программных фильтров безопасности
Тестирование программных фильтров безопасностиSQALab
 
Стажировка-2015. Разработка. Занятие 2. Основы реляционных баз данных
Стажировка-2015. Разработка. Занятие 2. Основы реляционных баз данныхСтажировка-2015. Разработка. Занятие 2. Основы реляционных баз данных
Стажировка-2015. Разработка. Занятие 2. Основы реляционных баз данных7bits
 
Эксперименты с Postgres в Docker и облаках — оптимизация настроек и схемы ва...
 Эксперименты с Postgres в Docker и облаках — оптимизация настроек и схемы ва... Эксперименты с Postgres в Docker и облаках — оптимизация настроек и схемы ва...
Эксперименты с Postgres в Docker и облаках — оптимизация настроек и схемы ва...Nikolay Samokhvalov
 
лекция
лекциялекция
лекцияvuvuzella
 
PostgreSQL: практические примеры оптимизации SQL-запросов / Иван Фролков (Po...
PostgreSQL: практические примеры оптимизации SQL-запросов /  Иван Фролков (Po...PostgreSQL: практические примеры оптимизации SQL-запросов /  Иван Фролков (Po...
PostgreSQL: практические примеры оптимизации SQL-запросов / Иван Фролков (Po...Ontico
 

Similar to 2015-12-05 Александр Коротков, Иван Панченко - Слабо-структурированные данные в СУБД глазами и руками разработчиков PostgreSQL (20)

Новые возможности языка SQL в Firebird 3.0
Новые возможности языка SQL в Firebird 3.0Новые возможности языка SQL в Firebird 3.0
Новые возможности языка SQL в Firebird 3.0
 
PT MIFI Labsql
PT MIFI LabsqlPT MIFI Labsql
PT MIFI Labsql
 
Advanced Sql Injection
Advanced Sql InjectionAdvanced Sql Injection
Advanced Sql Injection
 
Web осень 2013 лекция 6
Web осень 2013 лекция 6Web осень 2013 лекция 6
Web осень 2013 лекция 6
 
Дмитрий Долгов
Дмитрий ДолговДмитрий Долгов
Дмитрий Долгов
 
PT Hackday#2
PT Hackday#2PT Hackday#2
PT Hackday#2
 
Расширение библиотеки Slick
Расширение библиотеки SlickРасширение библиотеки Slick
Расширение библиотеки Slick
 
Adymo Barcamp Presentation Faster Higher Sql
Adymo Barcamp Presentation Faster Higher SqlAdymo Barcamp Presentation Faster Higher Sql
Adymo Barcamp Presentation Faster Higher Sql
 
Три вызова реляционным СУБД и новый PostgreSQL - #PostgreSQLRussia семинар по...
Три вызова реляционным СУБД и новый PostgreSQL - #PostgreSQLRussia семинар по...Три вызова реляционным СУБД и новый PostgreSQL - #PostgreSQLRussia семинар по...
Три вызова реляционным СУБД и новый PostgreSQL - #PostgreSQLRussia семинар по...
 
Tagconf 13 - SphinxSearch - 2
Tagconf 13 - SphinxSearch - 2Tagconf 13 - SphinxSearch - 2
Tagconf 13 - SphinxSearch - 2
 
Тестирование программных фильтров безопасности
Тестирование программных фильтров безопасностиТестирование программных фильтров безопасности
Тестирование программных фильтров безопасности
 
Промышленный подход к тюнингу PostgreSQL: эксперименты над базами данных
Промышленный подход к тюнингу PostgreSQL: эксперименты над базами данныхПромышленный подход к тюнингу PostgreSQL: эксперименты над базами данных
Промышленный подход к тюнингу PostgreSQL: эксперименты над базами данных
 
Народные средства оптимизации PostgreSQL
Народные средства оптимизации PostgreSQLНародные средства оптимизации PostgreSQL
Народные средства оптимизации PostgreSQL
 
Time series data in a relational database. TimescaleDB and PipelineDB extensi...
Time series data in a relational database. TimescaleDB and PipelineDB extensi...Time series data in a relational database. TimescaleDB and PipelineDB extensi...
Time series data in a relational database. TimescaleDB and PipelineDB extensi...
 
физическая структура хранения артемов Ready
физическая структура хранения артемов Readyфизическая структура хранения артемов Ready
физическая структура хранения артемов Ready
 
Тестирование программных фильтров безопасности
Тестирование программных фильтров безопасностиТестирование программных фильтров безопасности
Тестирование программных фильтров безопасности
 
Стажировка-2015. Разработка. Занятие 2. Основы реляционных баз данных
Стажировка-2015. Разработка. Занятие 2. Основы реляционных баз данныхСтажировка-2015. Разработка. Занятие 2. Основы реляционных баз данных
Стажировка-2015. Разработка. Занятие 2. Основы реляционных баз данных
 
Эксперименты с Postgres в Docker и облаках — оптимизация настроек и схемы ва...
 Эксперименты с Postgres в Docker и облаках — оптимизация настроек и схемы ва... Эксперименты с Postgres в Docker и облаках — оптимизация настроек и схемы ва...
Эксперименты с Postgres в Docker и облаках — оптимизация настроек и схемы ва...
 
лекция
лекциялекция
лекция
 
PostgreSQL: практические примеры оптимизации SQL-запросов / Иван Фролков (Po...
PostgreSQL: практические примеры оптимизации SQL-запросов /  Иван Фролков (Po...PostgreSQL: практические примеры оптимизации SQL-запросов /  Иван Фролков (Po...
PostgreSQL: практические примеры оптимизации SQL-запросов / Иван Фролков (Po...
 

More from HappyDev

2015-12-05 Антон Непомнящих - Agile — как уложиться в сроки и бюджет?
2015-12-05 Антон Непомнящих - Agile — как уложиться в сроки и бюджет?2015-12-05 Антон Непомнящих - Agile — как уложиться в сроки и бюджет?
2015-12-05 Антон Непомнящих - Agile — как уложиться в сроки и бюджет?HappyDev
 
2015 12-05 Александр Шиповалов - Инструмент для тестирования Sikuli script
2015 12-05 Александр Шиповалов - Инструмент для тестирования Sikuli script2015 12-05 Александр Шиповалов - Инструмент для тестирования Sikuli script
2015 12-05 Александр Шиповалов - Инструмент для тестирования Sikuli scriptHappyDev
 
2015-12-06 Константин Борисов - Как собеседовать программиста?
2015-12-06 Константин Борисов - Как собеседовать программиста?2015-12-06 Константин Борисов - Как собеседовать программиста?
2015-12-06 Константин Борисов - Как собеседовать программиста?HappyDev
 
2015-12-05 Данил Никифоров - NoSQL для мобайла с синхронизацией данных
2015-12-05 Данил Никифоров - NoSQL для мобайла с синхронизацией данных2015-12-05 Данил Никифоров - NoSQL для мобайла с синхронизацией данных
2015-12-05 Данил Никифоров - NoSQL для мобайла с синхронизацией данныхHappyDev
 
2015-12-06 Букуров Алексей - Автоматическое формирование интерфейса по метаоп...
2015-12-06 Букуров Алексей - Автоматическое формирование интерфейса по метаоп...2015-12-06 Букуров Алексей - Автоматическое формирование интерфейса по метаоп...
2015-12-06 Букуров Алексей - Автоматическое формирование интерфейса по метаоп...HappyDev
 
2015-12-05 Вадим Литвинов - Нагрузочное тестирование с MZBench
2015-12-05 Вадим Литвинов - Нагрузочное тестирование с MZBench2015-12-05 Вадим Литвинов - Нагрузочное тестирование с MZBench
2015-12-05 Вадим Литвинов - Нагрузочное тестирование с MZBenchHappyDev
 
2015-12-05 Александр Бындю, Андрей Шапиро - Пять самых важных составляющих пр...
2015-12-05 Александр Бындю, Андрей Шапиро - Пять самых важных составляющих пр...2015-12-05 Александр Бындю, Андрей Шапиро - Пять самых важных составляющих пр...
2015-12-05 Александр Бындю, Андрей Шапиро - Пять самых важных составляющих пр...HappyDev
 
2015-12-06 Юрий Мельничек - Руководство для разработчиков по маркетингу мобил...
2015-12-06 Юрий Мельничек - Руководство для разработчиков по маркетингу мобил...2015-12-06 Юрий Мельничек - Руководство для разработчиков по маркетингу мобил...
2015-12-06 Юрий Мельничек - Руководство для разработчиков по маркетингу мобил...HappyDev
 
2015-12-06 Максим Юнусов - Проектирование REST приложения, или нужно ли прогр...
2015-12-06 Максим Юнусов - Проектирование REST приложения, или нужно ли прогр...2015-12-06 Максим Юнусов - Проектирование REST приложения, или нужно ли прогр...
2015-12-06 Максим Юнусов - Проектирование REST приложения, или нужно ли прогр...HappyDev
 
2015-12-06 Евгений Тюменцев - Разработка надежных параллельных, распределенны...
2015-12-06 Евгений Тюменцев - Разработка надежных параллельных, распределенны...2015-12-06 Евгений Тюменцев - Разработка надежных параллельных, распределенны...
2015-12-06 Евгений Тюменцев - Разработка надежных параллельных, распределенны...HappyDev
 
2015-12-06 Артем Зиненко - Что делать, если браузеры клиентов действуют проти...
2015-12-06 Артем Зиненко - Что делать, если браузеры клиентов действуют проти...2015-12-06 Артем Зиненко - Что делать, если браузеры клиентов действуют проти...
2015-12-06 Артем Зиненко - Что делать, если браузеры клиентов действуют проти...HappyDev
 
2015-12-06 Антон Тарасенко - Ваш следующий сервис будет асинхронным
2015-12-06 Антон Тарасенко - Ваш следующий сервис будет асинхронным2015-12-06 Антон Тарасенко - Ваш следующий сервис будет асинхронным
2015-12-06 Антон Тарасенко - Ваш следующий сервис будет асинхроннымHappyDev
 
2015-12-05 Максим Дорофеев - Сила первого шага или сессия групповой депрокрас...
2015-12-05 Максим Дорофеев - Сила первого шага или сессия групповой депрокрас...2015-12-05 Максим Дорофеев - Сила первого шага или сессия групповой депрокрас...
2015-12-05 Максим Дорофеев - Сила первого шага или сессия групповой депрокрас...HappyDev
 
2015-12-05 Александр Рожнов - Свое облако под стейджинг
2015-12-05 Александр Рожнов - Свое облако под стейджинг2015-12-05 Александр Рожнов - Свое облако под стейджинг
2015-12-05 Александр Рожнов - Свое облако под стейджингHappyDev
 
2015-12-05 Анатолий Орлов - Скорость с доставкой до пользователя
2015-12-05 Анатолий Орлов - Скорость с доставкой до пользователя2015-12-05 Анатолий Орлов - Скорость с доставкой до пользователя
2015-12-05 Анатолий Орлов - Скорость с доставкой до пользователяHappyDev
 
2015-12-05 Сергей Аверин - Javascript-фреймворки: должен остаться только один
2015-12-05 Сергей Аверин - Javascript-фреймворки: должен остаться только один2015-12-05 Сергей Аверин - Javascript-фреймворки: должен остаться только один
2015-12-05 Сергей Аверин - Javascript-фреймворки: должен остаться только одинHappyDev
 
2015-12-05 Дмитрий Еманов - Многоверсионная архитектура данных: аспирин или г...
2015-12-05 Дмитрий Еманов - Многоверсионная архитектура данных: аспирин или г...2015-12-05 Дмитрий Еманов - Многоверсионная архитектура данных: аспирин или г...
2015-12-05 Дмитрий Еманов - Многоверсионная архитектура данных: аспирин или г...HappyDev
 
2015-12-05 Андрей Сидоренко - Сценарии использования и их роль в процессе раз...
2015-12-05 Андрей Сидоренко - Сценарии использования и их роль в процессе раз...2015-12-05 Андрей Сидоренко - Сценарии использования и их роль в процессе раз...
2015-12-05 Андрей Сидоренко - Сценарии использования и их роль в процессе раз...HappyDev
 
2015-12-05 Алексей Зиновьев - Когда все данные станут большими...
2015-12-05 Алексей Зиновьев - Когда все данные станут большими...2015-12-05 Алексей Зиновьев - Когда все данные станут большими...
2015-12-05 Алексей Зиновьев - Когда все данные станут большими...HappyDev
 
2015-12-05 Александр Коротков, Иван Панченко - Слабо-структурированные данные...
2015-12-05 Александр Коротков, Иван Панченко - Слабо-структурированные данные...2015-12-05 Александр Коротков, Иван Панченко - Слабо-структурированные данные...
2015-12-05 Александр Коротков, Иван Панченко - Слабо-структурированные данные...HappyDev
 

More from HappyDev (20)

2015-12-05 Антон Непомнящих - Agile — как уложиться в сроки и бюджет?
2015-12-05 Антон Непомнящих - Agile — как уложиться в сроки и бюджет?2015-12-05 Антон Непомнящих - Agile — как уложиться в сроки и бюджет?
2015-12-05 Антон Непомнящих - Agile — как уложиться в сроки и бюджет?
 
2015 12-05 Александр Шиповалов - Инструмент для тестирования Sikuli script
2015 12-05 Александр Шиповалов - Инструмент для тестирования Sikuli script2015 12-05 Александр Шиповалов - Инструмент для тестирования Sikuli script
2015 12-05 Александр Шиповалов - Инструмент для тестирования Sikuli script
 
2015-12-06 Константин Борисов - Как собеседовать программиста?
2015-12-06 Константин Борисов - Как собеседовать программиста?2015-12-06 Константин Борисов - Как собеседовать программиста?
2015-12-06 Константин Борисов - Как собеседовать программиста?
 
2015-12-05 Данил Никифоров - NoSQL для мобайла с синхронизацией данных
2015-12-05 Данил Никифоров - NoSQL для мобайла с синхронизацией данных2015-12-05 Данил Никифоров - NoSQL для мобайла с синхронизацией данных
2015-12-05 Данил Никифоров - NoSQL для мобайла с синхронизацией данных
 
2015-12-06 Букуров Алексей - Автоматическое формирование интерфейса по метаоп...
2015-12-06 Букуров Алексей - Автоматическое формирование интерфейса по метаоп...2015-12-06 Букуров Алексей - Автоматическое формирование интерфейса по метаоп...
2015-12-06 Букуров Алексей - Автоматическое формирование интерфейса по метаоп...
 
2015-12-05 Вадим Литвинов - Нагрузочное тестирование с MZBench
2015-12-05 Вадим Литвинов - Нагрузочное тестирование с MZBench2015-12-05 Вадим Литвинов - Нагрузочное тестирование с MZBench
2015-12-05 Вадим Литвинов - Нагрузочное тестирование с MZBench
 
2015-12-05 Александр Бындю, Андрей Шапиро - Пять самых важных составляющих пр...
2015-12-05 Александр Бындю, Андрей Шапиро - Пять самых важных составляющих пр...2015-12-05 Александр Бындю, Андрей Шапиро - Пять самых важных составляющих пр...
2015-12-05 Александр Бындю, Андрей Шапиро - Пять самых важных составляющих пр...
 
2015-12-06 Юрий Мельничек - Руководство для разработчиков по маркетингу мобил...
2015-12-06 Юрий Мельничек - Руководство для разработчиков по маркетингу мобил...2015-12-06 Юрий Мельничек - Руководство для разработчиков по маркетингу мобил...
2015-12-06 Юрий Мельничек - Руководство для разработчиков по маркетингу мобил...
 
2015-12-06 Максим Юнусов - Проектирование REST приложения, или нужно ли прогр...
2015-12-06 Максим Юнусов - Проектирование REST приложения, или нужно ли прогр...2015-12-06 Максим Юнусов - Проектирование REST приложения, или нужно ли прогр...
2015-12-06 Максим Юнусов - Проектирование REST приложения, или нужно ли прогр...
 
2015-12-06 Евгений Тюменцев - Разработка надежных параллельных, распределенны...
2015-12-06 Евгений Тюменцев - Разработка надежных параллельных, распределенны...2015-12-06 Евгений Тюменцев - Разработка надежных параллельных, распределенны...
2015-12-06 Евгений Тюменцев - Разработка надежных параллельных, распределенны...
 
2015-12-06 Артем Зиненко - Что делать, если браузеры клиентов действуют проти...
2015-12-06 Артем Зиненко - Что делать, если браузеры клиентов действуют проти...2015-12-06 Артем Зиненко - Что делать, если браузеры клиентов действуют проти...
2015-12-06 Артем Зиненко - Что делать, если браузеры клиентов действуют проти...
 
2015-12-06 Антон Тарасенко - Ваш следующий сервис будет асинхронным
2015-12-06 Антон Тарасенко - Ваш следующий сервис будет асинхронным2015-12-06 Антон Тарасенко - Ваш следующий сервис будет асинхронным
2015-12-06 Антон Тарасенко - Ваш следующий сервис будет асинхронным
 
2015-12-05 Максим Дорофеев - Сила первого шага или сессия групповой депрокрас...
2015-12-05 Максим Дорофеев - Сила первого шага или сессия групповой депрокрас...2015-12-05 Максим Дорофеев - Сила первого шага или сессия групповой депрокрас...
2015-12-05 Максим Дорофеев - Сила первого шага или сессия групповой депрокрас...
 
2015-12-05 Александр Рожнов - Свое облако под стейджинг
2015-12-05 Александр Рожнов - Свое облако под стейджинг2015-12-05 Александр Рожнов - Свое облако под стейджинг
2015-12-05 Александр Рожнов - Свое облако под стейджинг
 
2015-12-05 Анатолий Орлов - Скорость с доставкой до пользователя
2015-12-05 Анатолий Орлов - Скорость с доставкой до пользователя2015-12-05 Анатолий Орлов - Скорость с доставкой до пользователя
2015-12-05 Анатолий Орлов - Скорость с доставкой до пользователя
 
2015-12-05 Сергей Аверин - Javascript-фреймворки: должен остаться только один
2015-12-05 Сергей Аверин - Javascript-фреймворки: должен остаться только один2015-12-05 Сергей Аверин - Javascript-фреймворки: должен остаться только один
2015-12-05 Сергей Аверин - Javascript-фреймворки: должен остаться только один
 
2015-12-05 Дмитрий Еманов - Многоверсионная архитектура данных: аспирин или г...
2015-12-05 Дмитрий Еманов - Многоверсионная архитектура данных: аспирин или г...2015-12-05 Дмитрий Еманов - Многоверсионная архитектура данных: аспирин или г...
2015-12-05 Дмитрий Еманов - Многоверсионная архитектура данных: аспирин или г...
 
2015-12-05 Андрей Сидоренко - Сценарии использования и их роль в процессе раз...
2015-12-05 Андрей Сидоренко - Сценарии использования и их роль в процессе раз...2015-12-05 Андрей Сидоренко - Сценарии использования и их роль в процессе раз...
2015-12-05 Андрей Сидоренко - Сценарии использования и их роль в процессе раз...
 
2015-12-05 Алексей Зиновьев - Когда все данные станут большими...
2015-12-05 Алексей Зиновьев - Когда все данные станут большими...2015-12-05 Алексей Зиновьев - Когда все данные станут большими...
2015-12-05 Алексей Зиновьев - Когда все данные станут большими...
 
2015-12-05 Александр Коротков, Иван Панченко - Слабо-структурированные данные...
2015-12-05 Александр Коротков, Иван Панченко - Слабо-структурированные данные...2015-12-05 Александр Коротков, Иван Панченко - Слабо-структурированные данные...
2015-12-05 Александр Коротков, Иван Панченко - Слабо-структурированные данные...
 

2015-12-05 Александр Коротков, Иван Панченко - Слабо-структурированные данные в СУБД глазами и руками разработчиков PostgreSQL

  • 1. Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) Александр Коротков, Иван Панченко Postgres Professional 2015 Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 1 / 72
  • 2. 1. Немного о массивах Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 2 / 72
  • 3. Исходные данные: products # d product Table ”public.product” Column | Type | Modifiers ---------------------+-----------------+----------- product_id | character(10) | not null product_title | text | not null product_sales_rank | bigint | not null product_group | text | not null product_category | text | product_subcategory | text | similar_product_ids | character(10)[] | not null Indexes: Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 3 / 72
  • 4. Subscrip on – вытащить элемент по заданному индексу # SELECT product_id, similar_product_ids FROM product LIMIT 5; product_id | similar_product_ids ------------+---------------------------------------------------------- 0001047655 | {0061007129,0061007358,0061007137,0061099341,0061007161} 0001053736 | {0440905605,0345336062,0140380531,0393320979,0395898714} 0001053744 | {} 0001054600 | {} 0001474103 | {0895403889,0001473123,0766177610,0001472933,0766187403} (5 rows) # SELECT product_id, similar_product_ids[2] FROM product LIMIT 5; product_id | similar_product_ids ------------+--------------------- 0001047655 | 0061007358 0001053736 | 0345336062 0001053744 | NULL 0001054600 | NULL 0001474103 | 0001473123 (5 rows) Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 4 / 72
  • 5. Subscrip on – вытащить slice # SELECT product_id, similar_product_ids[1:2] FROM product LIMIT 5; product_id | similar_product_ids ------------+------------------------- 0001047655 | {0061007129,0061007358} 0001053736 | {0440905605,0345336062} 0001053744 | {} 0001054600 | {} 0001474103 | {0895403889,0001473123} (5 rows) Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 5 / 72
  • 6. Subscrip on – обновление # UPDATE product SET similar_product_ids[1] = ’0061007129’ WHERE product_id = ’0001047655’; # UPDATE product SET similar_product_ids[1:2] = ’{0440905605,0345336062}’ WHERE product_id = ’0001047655’; Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 6 / 72
  • 7. Осторожно – произвольные границы! # SELECT (’[-3:-2]={1,2}’::int[])[1]; int4 ------ NULL (1 row) # SELECT (’[-3:-2]={1,2}’::int[])[-2]; int4 ------ 2 (1 row) Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 7 / 72
  • 8. Осторожно – многомерные массивы! # SELECT (’{{1,2},{3,4}}’::int[])[1]; int4 ------ NULL (1 row) # SELECT (’{{1,2},{3,4}}’::int[])[1][2]; int4 ------ 2 (1 row) Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 8 / 72
  • 9. array_lower и array_upper – верхняя и нижняя границы массива Откусываем у массива первый элемент. # SELECT product_id, similar_product_ids[ array_lower(similar_product_ids,1) + 1 : array_upper(similar_product_ids,1)] FROM product LIMIT 5; product_id | similar_product_ids ------------+----------------------------------------------- 0001047655 | {0061007358,0061007137,0061099341,0061007161} 0001053736 | {0345336062,0140380531,0393320979,0395898714} 0001053744 | NULL 0001054600 | NULL 0001474103 | {0001473123,0766177610,0001472933,0766187403} (5 rows) Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 9 / 72
  • 10. Поиск по массиву: ANY # SELECT product_id, product_title FROM product WHERE ’0061007137’ = ANY(similar_product_ids); product_id | product_title ------------+------------------------------------ 0001047655 | Prodigal Daughter 0061007129 | Kane & Abel 0061007145 | The Prodigal Daughter 0061007161 | First Among Equals 0061007358 | Not a Penny More, Not a Penny Less 0061013315 | The Eleventh Commandment 0061013706 | Shall We Tell the President? 0061092045 | Honor Among Thieves 0061093653 | Twelve Red Herrings 0061099341 | As the Crow Flies (10 rows) Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 10 / 72
  • 11. Разворачивание массива в rowset: unnest # SELECT unnest(similar_product_ids) FROM product WHERE product_id = ’0061007137’; unnest ------------ 0061007358 0061099341 0061007145 0061007161 0061007129 (5 rows) Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 11 / 72
  • 12. Сворачивание rowset в массив: array_agg # SELECT array_agg(product_id) FROM product WHERE ’0061093653’ = ANY(similar_product_ids); array_agg ----------------------------------------------- {006018552X,0060185805,006100717X,0061032077} (1 row) Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 12 / 72
  • 13. Задача #1 Для каждого продукта собрать массив тех, которые ссылаются на него через similar_product_ids. Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 13 / 72
  • 14. Задача #1: решение SELECT similar_id, array_agg(product_id) FROM ( SELECT product_id, unnest(similar_product_ids) AS similar_id FROM product) s GROUP BY similar_id; Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 14 / 72
  • 15. Задача #2 Сделать выборку продуктов, для которых все продукты, указанные в массиве similar_product_ids имеют рейтинг не меньше 100000. Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 15 / 72
  • 16. Задача #2: решение SELECT * FROM product p1 WHERE NOT EXISTS ( SELECT 1 FROM unnest(p1.similar_product_ids) sid JOIN product p2 ON p2.product_id = sid WHERE NOT (p2.product_sales_rank >= 100000)); Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 16 / 72
  • 17. Операторы &&, @>, <@ (1/2) ▶ a && b – у массивов a и b есть хотя бы один общий элемент. ▶ a @> b – в массиве a есть все элементы массива b и, быть может, другие. ▶ a <@ b – то же, что и b @> a. Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 17 / 72
  • 18. Операторы &&, @>, <@ (2/2) # SELECT count(*) FROM product WHERE similar_product_ids && ’{0061007137,0007149689}’; count ------- 11 (1 row) # SELECT count(*) FROM product WHERE similar_product_ids @> ’{0061007137,0061007161}’; count ------- 6 (1 row) Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 18 / 72
  • 19. Индексы по массивам (1/3) ▶ Встроенный GIN-индекс для массивов всех типов (операторы &&, @>, <@, =). ▶ GiST-индекс для int[] в contrib/intarray. ▶ Индексы по конкретным элементам массива (например, a[3]). Не очень интересно. Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 19 / 72
  • 20. Индексы по массивам (2/3) # EXPLAIN ANALYZE SELECT * FROM product WHERE similar_product_ids @> ’{0061007137,0061007161}’; QUERY PLAN --------------------------------------------------------------- Seq Scan on product (cost=0.00..9348.25 rows=1 width=161) (ac Filter: (similar_product_ids @> ’{0061007137,0061007161}’::b Rows Removed by Filter: 253614 Planning time: 0.120 ms Execution time: 97.547 ms Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 20 / 72
  • 21. Индексы по массивам (3/3) # CREATE INDEX product_similar_product_ids_idx ON product USING gin (similar_product_ids); CREATE INDEX Time: 18795,075 ms # EXPLAIN ANALYZE SELECT * FROM product WHERE similar_product_ids @> ’{0061007137,0061007161}’; --------------------------------------------------------------- Bitmap Heap Scan on product (cost=28.00..32.01 rows=1 width=1 Recheck Cond: (similar_product_ids @> ’{0061007137,006100716 Heap Blocks: exact=5 -> Bitmap Index Scan on product_similar_product_ids_idx (c Index Cond: (similar_product_ids @> ’{0061007137,00610 Planning time: 0.123 ms Execution time: 0.089 ms Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 21 / 72
  • 22. 2. Hstore Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 22 / 72
  • 23. Исходные данные: stocks (1/2) Table ”public.stocks” Column | Type | Modifiers ----------+---------+------------------------------------------ id | integer | not null default nextval(’stocks_id_seq’: country | text | not null industry | text | not null sector | text | not null company | text | not null ticker | text | not null volume | integer | not null h | hstore | not null Indexes: ”stocks_pkey” PRIMARY KEY, btree (id) Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 23 / 72
  • 24. Исходные данные: stocks (2/2) # SELECT * FROM stocks LIMIT 1; -[ RECORD 1 ]-------------------------------------------------- id | 1 country | USA industry | Semiconductor Equipment & Materials sector | Technology company | Brooks Automation Inc. ticker | BRKS volume | 516739 h | ”Gap”=>”0.0151”, ”P/B”=>”1.05”, ”P/E”=>”6.07”, ”P/S” Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 24 / 72
  • 25. Вытаскивание полей (1/2) # SELECT id, h -> ’Price’, h -> ’Change’ FROM stocks LIMIT 10; id | ?column? | ?column? ----+-------------------+---------- 1 | 10.24 | 0.0291 2 | 26.94 | -0.023 3 | 92.56999999999999 | 0.0016 4 | 14.95 | 0.0047 5 | 26.65 | 0.0013 6 | 25.33 | -0.0261 7 | 62.7 | 0.0061 8 | 11.9 | -0.0017 9 | 24.44 | 0.0188 10 | 36.87 | 0.0104 (10 rows) Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 25 / 72
  • 26. Вытаскивание полей (2/2) # SELECT company FROM stocks WHERE h -> ’Price’ > 1000.0; ERROR: operator does not exist: text > numeric # SELECT company FROM stocks WHERE (h -> ’Price’)::numeric > 1000.0; company ---------------------------- Seaboard Corp. Berkshire Hathaway Inc. Google Inc. priceline.com Incorporated (4 rows) Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 26 / 72
  • 27. Превращаем hstore в набор пар ключ-значение # SELECT (each(h)).* FROM stocks WHERE id = 4; key | value -------------------------------+---------------------- Gap | 0 Price | 14.95 Change | 0.0047 50-Day Low | 0.0381 50-Day High | -0.0177 52-Week Low | 0.3304 Short Ratio | 0.14 ...................................................... Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 27 / 72
  • 28. Задача #3 Собрать статистику по использованию различных ключей в поле h таблицы stocks: для каждого встречающегося ключа указать его частоту. Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 28 / 72
  • 29. Задача #3: решение # SELECT key, count(*)::float8 / (SELECT count(*) FROM stocks) freq FROM (SELECT (each(h)).* FROM stocks) kv GROUP BY key; key | freq -----------------------------------+------------------- Shares Float | 0.725725281231498 Analyst Recom | 0.616489046773239 Insider Transactions | 0.554026050917703 Institutional Transactions | 0.705743043220841 P/B | 0.71166370633511 ....................................................... Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 29 / 72
  • 30. Оператор @> a @> b тогда и только тогда, когда для каждой пары ключ => значение из b, такая же пара присутствует и в a. Примеры. key1 | key2 | result -----------------+--------------+-------- a=>x, b=>y, c=>z | a=>x, b=>y | true a=>x, b=>y | a=>x, b=>qqq | false a=>x, b=>y | t=>x, b=>y | false Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 30 / 72
  • 31. Операторы ?, ?&, ?| ▶ a ? b – проверяет наличие ключа b в массиве a. ▶ a ?& b – проверяет наличие всех ключей из массива b в массиве a. ▶ a ?| b – проверяет наличие хотя бы одного из ключей массива b в массиве a. # SELECT count(*), count(*) FILTER (WHERE h ? ’Short Ratio’), count(*) FILTER (WHERE h ?| ’{Short Ratio, Change from Open}’), count(*) FILTER (WHERE h ?& ’{Short Ratio, Change from Open}’) FROM stocks; count | count | count | count -------+-------+-------+------- 6756 | 5412 | 6743 | 5412 (1 row) Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 31 / 72
  • 32. Задача #4 Написать аналог оператора @> с помощью функций each(hstore) и операторов ->, ?. Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 32 / 72
  • 33. Задача #4: решение CREATE FUNCTION contains_sql(hstore, hstore) RETURNS bool AS $$ SELECT NOT EXISTS ( SELECT 1 FROM each($2) kv WHERE NOT ( $1 ? key AND $1 -> key IS NOT DISTINCT FROM value) ) $$ LANGUAGE sql; Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 33 / 72
  • 34. Конструируем hstore # SELECT hstore(’{key1, key2}’::text[], ’{value1, value2}’::text[]); hstore ------------------------------------ ”key1”=>”value1”, ”key2”=>”value2” (1 row) # SELECT hstore(array_agg(id::text), array_agg(company)) FROM stocks WHERE id <= 4; hstore ------------------------------------------------------ ”1”=>”Brooks Automation Inc.”, ”2”=>”Broadcom Corp.” (1 row) Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 34 / 72
  • 35. Задача #5 Посчитать для каждой отрасли (sector) из таблицы stocks суммарный объём ценных бумаг (volume), и выдать это в виде hstore вида: отрасль => суммарный объём ценный бумаг. Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 35 / 72
  • 36. Задача #5: решение # SELECT hstore( array_agg(sector), array_agg(volume::text)) h FROM (SELECT sector, SUM(volume) AS volume FROM stocks GROUP BY sector) s; -[ RECORD 1 ]-------------------------------------------------------- h | ”Services”=>”637878158”, ”Financial”=>”1389743864”, | ”Utilities”=>”94268768”, ”Healthcare”=>”381247435”, | ”Technology”=>”1225484169”, ”Conglomerates”=>”3547704”, | ”Consumer Goods”=>”276207382”, | ”Basic Materials”=>”625043686”, | ”Industrial Goods”=>”200105263” Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 36 / 72
  • 37. Индексы для hstore ▶ GIN/GiST индексы: индексируем ключи отдельно, значения отдельно (операторы @>, ?, ?&, ?|). ▶ GIN индекс: индексируем пары hash(key) + hash(value) (операторы @>, ?, ?&, ?|) https://github.com/postgrespro/hstore_ops ▶ Индекс по отдельному ключу (h->’key’). Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 37 / 72
  • 38. 3. Jsonb Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 38 / 72
  • 39. Исходные данные: company # d company Table ”public.company” Column | Type | Modifiers --------+-------+----------- js | jsonb | # SELECT js FROM company limit 5; --------------------------------------------------------------- {”_id”: {”$oid”: ”52cdef7c4bab8bd675297d8a”}, ”name”: ”Wetpain {”_id”: {”$oid”: ”52cdef7c4bab8bd675297d8b”}, ”name”: ”AdventN {”_id”: {”$oid”: ”52cdef7c4bab8bd675297d8c”}, ”name”: ”Zoho”, {”_id”: {”$oid”: ”52cdef7c4bab8bd675297d8d”}, ”ipo”: null, ”na {”_id”: {”$oid”: ”52cdef7c4bab8bd675297d8e”}, ”ipo”: {”pub_day (5 rows) Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 39 / 72
  • 40. Jsonb pre y print # SELECT jsonb_pretty(js) FROM company LIMIT 1; -[ RECORD 1 ]+------------------------------------------- jsonb_pretty | { | ”_id”: { | ”$oid”: ”52cdef7c4bab8bd675297d8a” | }, | ”name”: ”Wetpaint”, | ”image”: { | ”available_sizes”: [ | [ | [ | 150, | 75 ......................................................... Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 40 / 72
  • 41. Вытаскивание полей # SELECT js -> ’name’, js -> ’acquisition’ -> ’price_amount’, js #> ’{acquisition,price_amount}’ FROM company LIMIT 5; ?column? | ?column? | ?column? -------------------------+-----------+----------- ”Wetpaint” | 30000000 | 30000000 ”AdventNet” | NULL | NULL ”Zoho” | NULL | NULL ”Digg” | 500000 | 500000 ”Facebook” | NULL | NULL (5 rows) Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 41 / 72
  • 42. Вытаскивание полей и типы (1/2) -> вытаскивает тип jsonb # SELECT js -> ’name’ FROM company WHERE js -> ’name’ ILIKE ’%paint%’; ERROR: operator does not exist: jsonb ~~* unknown Приведение значения поля к строке # SELECT (js -> ’name’)::text, js ->> ’name’ FROM company LIMIT 5; text | ?column? -------------+----------- ”Wetpaint” | Wetpaint ”AdventNet” | AdventNet ”Zoho” | Zoho ”Digg” | Digg ”Facebook” | Facebook (5 rows) Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 42 / 72
  • 43. Вытаскивание полей и типы (2/2) # SELECT js ->> ’name’, js ->> ’number_of_employees’ FROM company WHERE js ->> ’name’ ILIKE ’%paint%’ AND (js ->> ’number_of_employees’)::int >= 10; ?column? | ?column? ----------+---------- Wetpaint | 47 (1 row) Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 43 / 72
  • 44. Вытаскивание элементов массивов # SELECT js -> ’offices’ -> 0 ->> ’city’, js #>> ’{offices,0,city}’ FROM company LIMIT 5; ?column? | ?column? ---------------+--------------- Seattle | Seattle Pleasanton | Pleasanton Pleasanton | Pleasanton San Francisco | San Francisco Menlo Park | Menlo Park (5 rows) Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 44 / 72
  • 45. Индексы по выражениям # CREATE UNIQUE INDEX company_id_idx ON company ((js -> ’_id’ ->> ’$oid’)); CREATE INDEX # EXPLAIN ANALYZE SELECT js -> ’name’ FROM company WHERE js -> ’_id’ ->> ’$oid’ = ’52cdef7c4bab8bd675297d8a’; QUERY P --------------------------------------------------------------- Index Scan using company_id_idx on company (cost=0.29..8.31 r Index Cond: (((js -> ’_id’::text) ->> ’$oid’::text) = ’52cde Planning time: 0.084 ms Execution time: 0.156 ms (4 rows) Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 45 / 72
  • 46. Разворачивание JSON-массивов в rowset # SELECT jsonb_array_elements(js -> ’competitions’) FROM company WHERE js -> ’_id’ ->> ’$oid’ = ’52cdef7c4bab8bd675297d8a’; jsonb_array_elements --------------------------------------------------------------------- {”competitor”: {”name”: ”Wikia”, ”permalink”: ”wikia”}} {”competitor”: {”name”: ”JotSpot”, ”permalink”: ”jotspot”}} {”competitor”: {”name”: ”Socialtext”, ”permalink”: ”socialtext”}} {”competitor”: {”name”: ”Ning by Glam Media”, ”permalink”: ”ning”}} {”competitor”: {”name”: ”Soceeo”, ”permalink”: ”soceeo”}} {”competitor”: {”name”: ”Yola”, ”permalink”: ”yola”}} {”competitor”: {”name”: ”SocialGO”, ”permalink”: ”socialgo”}} {”competitor”: {”name”: ”IslamNor”, ”permalink”: ”islamnor”}} (8 rows) Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 46 / 72
  • 47. Разворачивание JSON-объекта в key-value rowset # SELECT (jsonb_each(js #> ’{offices, 0}’)).* FROM company WHERE js -> ’_id’ ->> ’$oid’ = ’52cdef7c4bab8bd675297d8a’; key | value --------------+-------------------- city | ”Seattle” address1 | ”710 - 2nd Avenue” address2 | ”Suite 1100” latitude | 47.603122 zip_code | ”98104” longitude | -122.333253 state_code | ”WA” description | ”” country_code | ”USA” (9 rows) Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 47 / 72
  • 48. Оператор @> ▶ Для скалярных a и b, a @> b тогда и только тогда, когда a = b. ▶ Если a и b объекты, то для каждого ключа в b должен существовать ключ в a, содержащий соответствующее значение. ▶ Если a и b массивы, то для каждого элемента в b должен существовать содержащий его элемент в a. Примеры. arg1 | arg2 | result ---------------------+----------------------+-------- 1 | 1 | true 1 | ”1” | false {”a”: 1, ”b”: 2} | {”a”: 1} | true {”a”: 1, ”b”: 2} | {”a”: 2} | false [1, 2] | [1] | true [{”a”: 1, ”b”: 2}] | [{”a”: 1}, {”b”: 2}] | true [{”a”: 1}, {”b”: 2}] | [{”a”: 1, ”b”: 2}] | false Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 48 / 72
  • 49. Установка plv8 $ git clone https://github.com/plv8/plv8.git $ cd plv8 $ make USE_PGXS=1 $ sudo make USE_PGXS=1 install $ make USE_PGXS=1 installcheck $ psql DB -c ”CREATE EXTENSION plv8;” Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 49 / 72
  • 50. Задача #6 Написать на plv8 функцию, которая для компании выводит список стран, где у неё есть офисы. Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 50 / 72
  • 51. Задача #6: решение CREATE FUNCTION extract_countries(company jsonb) RETURNS text[] AS $$ var tmp = {}, result = []; for(var i = 0; i < company.offices.length; i++) tmp[company.offices[i].country_code] = true; for(var i in tmp) result.push(i) return result; $$ LANGUAGE plv8 IMMUTABLE STRICT; Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 51 / 72
  • 52. Индекс по странам CREATE INDEX company_countries_idx ON company USING gin(extract_countries(js)); # EXPLAIN ANALYZE SELECT * FROM company WHERE extract_countries(js) @> ’{RUS}’; QUER --------------------------------------------------------------- Bitmap Heap Scan on company (cost=8.73..348.48 rows=94 width= (actual time=0.038..0.089 rows=50 loops=1) Recheck Cond: (extract_countries(js) @> ’{RUS}’::text[]) Heap Blocks: exact=48 -> Bitmap Index Scan on company_countries_idx (cost=0.00.. Index Cond: (extract_countries(js) @> ’{RUS}’::text[]) Planning time: 0.057 ms Execution time: 0.113 ms (7 rows) Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 52 / 72
  • 53. Задача #7 Написать на plv8 агрегат, который который посчитает частоты различных размеров картинок. Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 53 / 72
  • 54. Задача #7: решение (1/2) CREATE FUNCTION image_size_agg_sfunc(state jsonb, company jsonb) RETURNS jsonb AS $$ if (!company.image) return state; var sizes = company.image.available_sizes for (var i = 0; i < sizes.length; i++) { var sizeKey = sizes[i][0][0] + ’x’ + sizes[i][0][1]; if (sizeKey in state) state[sizeKey]++; else state[sizeKey] = 1; } return state; $$ LANGUAGE plv8 IMMUTABLE STRICT; Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 54 / 72
  • 55. Задача #7: решение (2/2) CREATE AGGREGATE image_size_agg (jsonb) ( SFUNC = image_size_agg_sfunc, STYPE = jsonb, INITCOND = ’{}’); # SELECT image_size_agg(js) FROM company; -[ RECORD 1 ]--+----------------------------------------------- image_size_agg | {”1x1”: 15, ”32x8”: 3, ”150x7”: 1, ”150x8”: 5, Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 55 / 72
  • 56. Установка jsquery $ git clone https://github.com/postgrespro/jsquery.git $ cd jsquery $ make USE_PGXS=1 $ sudo make USE_PGXS=1 install $ make USE_PGXS=1 installcheck $ psql DB -c ”CREATE EXTENSION jsquery;” Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 56 / 72
  • 57. Индексы для jsonb ▶ GIN jsonb_ops: индексируем ключи отдельно, значения отдельно (операторы @>, ?, ?&, ?|). ▶ GIN jsonb_path_ops: индексируем hash(path + value) (операторы @>). ▶ jsonb_path_value_ops: индексируем hash(path) + hash(value) (операторы @>, jsonb @@ jsquery). ▶ jsonb_value_path_ops: индексируем hash(value) + bloom(path) (операторы @>, jsonb @@ jsquery). ▶ Индексы по отдельным ключам (js -> ’key’). Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 57 / 72
  • 58. Пример: найти комании с офисами в России -- Оператор @> # SELECT js->’name’ FROM company WHERE js @> ’{”offices”:[{”country_code”: ”RUS”}]}’; -- Оператор jsquery # SELECT js->’name’ FROM company WHERE js @@ ’offices.#.country_code = ”RUS”’; -- Разворачивание jsonb в rowset # SELECT js->’name’ FROM company WHERE EXISTS ( SELECT 1 FROM jsonb_array_elements(js->’offices’) el WHERE el ->> ’country_code’ = ’RUS’); Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 58 / 72
  • 59. Задача #8 Найти компании, конкуренты Wikia, у которых есть офис в США. Реализовать решение с помощью: ▶ оператора @>, ▶ jsquery, ▶ разворачивания jsonb в rowset. Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 59 / 72
  • 60. Задача #8: решение (1/3) -- Оператор @> # SELECT js->’name’ FROM company WHERE js @> ’{”competitions”:[{”competitor”: {”name”: ”Wikia”} }]}’ AND js @> ’{”offices”:[{”country_code”: ”USA”}]}’; Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 60 / 72
  • 61. Задача #8: решение (2/3) -- jsquery # SELECT js->’name’ FROM company WHERE js @@ ’competitions.#.competitor.name = ”Wikia” AND offices.#.country_code = ”USA”’; Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 61 / 72
  • 62. Задача #8: решение (3/3) -- Разворачивание jsonb в rowset SELECT js->’name’ FROM company WHERE EXISTS ( SELECT 1 FROM jsonb_array_elements(js->’competitions’) el WHERE el -> ’competitor’ ->> ’name’ = ’Wikia’ ) AND EXISTS ( SELECT 1 FROM jsonb_array_elements(js->’offices’) el WHERE el ->> ’country_code’ = ’USA’ ); Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 62 / 72
  • 63. Задача #9 Найти компании, в которые финансовая организация Trinity Ventures инвестировала в 2007 или 2008 году. Реализовать решение с помощью: ▶ оператора @>, ▶ jsquery, ▶ разворачивания jsonb в rowset. Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 63 / 72
  • 64. Задача #9: решение (1/3) -- Оператор @> # SELECT js->’name’ FROM company WHERE js @> ’{”funding_rounds”:[{”funded_year”: 2007, ”investments”:[{”financial_org”: {”name”:”Trinity Ventures”}} ]} ]}’ OR js @> ’{”funding_rounds”:[{”funded_year”: 2008, ”investments”:[{”financial_org”: {”name”:”Trinity Ventures”}} ]} ]}’; Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 64 / 72
  • 65. Задача #9: решение (2/3) -- jsquery # SELECT js->’name’ FROM company WHERE js @@ ’funding_rounds.#( funded_year IN (2007,2008) AND investments.#. financial_org.name = ”Trinity Ventures”)’; Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 65 / 72
  • 66. Задача #9: решение (3/3) -- Разворачивание jsonb в rowset # SELECT js->’name’ FROM company WHERE EXISTS ( SELECT 1 FROM jsonb_array_elements(js->’funding_rounds’) el WHERE el -> ’funded_year’ IN (’2007’,’2008’) AND EXISTS (SELECT 1 FROM jsonb_array_elements(el -> ’investments’) el2 WHERE el2 -> ’financial_org’ ->> ’name’ = ’Trinity Ventures’)); Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 66 / 72
  • 67. Задача #10 Найти компании, которые в 2008 году привлекли более 100 000 000 USD инвестиций. Реализовать решение с помощью: ▶ jsquery, ▶ разворачивания jsonb в rowset. Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 67 / 72
  • 68. Задача #10: решение (1/2) -- jsquery # SELECT js -> ’name’ FROM company WHERE js @@ ’funding_rounds.# (funded_year = 2008 AND raised_currency_code = ”USD” AND raised_amount > 100000000)’; Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 68 / 72
  • 69. Задача #10: решение (2/2) -- Разворачивание jsonb в rowset # SELECT js->’name’ FROM company WHERE EXISTS ( SELECT 1 FROM jsonb_array_elements(js->’funding_rounds’) el WHERE el -> ’funded_year’ = ’2008’ AND el ->> ’raised_currency_code’ = ’USD’ AND el -> ’raised_amount’ > ’100000000’); Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 69 / 72
  • 70. Задача #11 Найти компании, у которых суммарный объём инвестиций был более 1 000 000 000 USD. Реализовать решение с помощью разворачивания jsonb в rowset. Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 70 / 72
  • 71. Задача #11: решение -- Разворачивание jsonb в rowset SELECT js->’name’ FROM company WHERE ( SELECT SUM((el ->> ’raised_amount’)::numeric) FROM jsonb_array_elements(js->’funding_rounds’) el WHERE el ->> ’raised_currency_code’ = ’USD’) > 1000000000; Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 71 / 72
  • 72. Спасибо за внимание! Александр Коротков, Иван Панченко Слабо-структурированные данные в СУБД PostgreSQL (мастер-класс) 72 / 72