20080415 rit2008 pgsql web20 samokhvalov

Post on 18-May-2015

720 Views

Category:

Technology

1 Downloads

Preview:

Click to see full reader

TRANSCRIPT

PostgreSQL.Лучшая СУБД для Web 2.0

Николай Самохвалов,ООО «Постгресмен»,

Российское сообщество пользователей PostgreSQL

PostgreSQL + Web 2.0 = ?PostgreSQL — самая развитая из

открытых систем баз данных в мире

Используют:

Что такое Web 2.0?

Что такое Web 2.0?Для пользователей:● collaborative web (UGC, комментарии,

рейтингование и т.д.);● веб-приложения, а не веб-сайты

(AJAX, новый уровень интеграции)● веб как платформа

(интероперабельность, RSS, микроформаты и т.д.)

● закруглённые уголки, отражения в логотипах и т.д. :-)

___________________*) UGC (user-generated content) — контент, созданный пользователями

Что такое Web 2.0?Для разработчиков:

больше пользователей

большеразработчиков

большепроектов

больше конкурентовна рынке

выше темпыразработки,итерации

короче

высокаяизменчивость

бизнес-требований

растущиеобъёмыданных

пользователи,хиты, TPS и пр.:

N = et

Лучшие технологии помогают побеждать!

Почему PostgreSQL?1. Производительность,

масштабируемость

2. Надёжность

3. Богатые возможности

4. Соответствие стандартам, “правильность”

5. Свобода

Почему PostgreSQL?1. Производительность,

масштабируемость

2. Надёжность

3. Богатые возможности

4. Соответствие стандартам, “правильность”

5. Свобода

Качество

} Эффективная разработка

}} HR

Как работать с UGC?1. Таксономия

● Каталоги

2. Фолксономия● Теги

3. Комплексный подход, два пути:● Теги + Каталоги● И пользователи, и редакторы управляют

каталогами

UGC: таксономия1. Таксономия (Каталоги)

● EAV, где таблица Атрибут [почти] неизменна● intarray / hstore

EAV: Entity-Attribute-ValueEntity Value

Attribute

contrib/intarray, contrib/hstore

● Позволяет существенно сэкономить место на диске● Производительность хороша, если вы сочетаете GiST и GIN

индексы● Иногда разумно кэшировать значения тегов во внешнем

кеше (напр., Memcache; можно применять pgmemcache в триггерах для инвалидации кэша), если используется intarray => меньше соединений в SELECT-ах

item

obj_id INT8item_section_id INT8item_vendor_id INT8item_model_id INT8item_year INT2item_price NUMERIC(30,6)item_props intarray

UGC: фолксономия1. Фолксономия (Теги)

● EAV (снова), таблица Атрибут под контролем пользователей

● intarray / hstore (снова)

UGC: комплексный подходДва возможных варианта:

1. Теги + Каталоги

— часто используемый вариант

2. И пользователи, и редакторы контролируют Каталоги

— наиболее перспективный, но сложный для разработки и поддержки подход

● UGC-записи каталогов не отображаются в общих списках выборки <SELECT>, ждут одобрения редакторов.

● Процедура 'слияния' далеко не простая (как правильно объединять UGC и редакторский контент?; дубликаты; синонимы и т.п.).

● полнотекстовый поиск (стемминг, морфология, тезаурус), pg_trgm, metaphone, soundex и т.д. могут помочь. НО: работа человека по-прежнему необходима

UGC: подробнее о тегах1. Используйте FTS (бывший tsearch2) для интеграции

поиска по тегам и текстового поиска:● категории FTS, чтобы отличать теги от обычных

слов при поиске (когда необходимо);● для обработки тегов можно создать отдельную

конфигурацию FTS.

2. Используйте «префиксный поиск» для поиска по тегам. Решение пока не тривиально (см. следующие слайды ;-) )

UGC: теги и префиксный поискПример префиксного поиска:

Решение “в лоб” разочаровывает:test=# EXPLAIN ANALYZE SELECT * FROM tag WHERE tag_name LIKE 'postgr%';                                               QUERY PLAN­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ Seq Scan on tag  (cost=0.00..6182.75 rows=1 width=105) (actual time=0.951..102.779 rows=162 loops=1)     Filter: ((tag_name)::text ~~ 'postgr%'::text) Total runtime: 102.871 ms(3 rows)

Замечание: ~300 000 уникальных тегов

Префиксный поиск: как сделать быстрее1. Используем text_pattern_ops     LIKE 'postgr%':для ускоренияtest=# CREATE INDEX i_tag_prefix ON tag             USING btree(lower(tag_name) text_pattern_ops);CREATE INDEX

test=# EXPLAIN ANALYZE SELECT * FROM tag                        WHERE lower(tag_name) LIKE lower('bla%');                                           QUERY PLAN­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ Bitmap Heap Scan on tag  (cost=43.55..2356.16 rows=1096 width=105) (actual time=0.164..0.791 rows=235 loops=1)     Filter: (lower((tag_name)::text) ~~ 'postgr%'::text)     ­>  Bitmap Index Scan on i_tag_prefix  (cost=0.00..43.28    rows=1096width=0) (actual time=0.116..0.116 rows=235 loops=1)                 Index Cond: ((lower((tag_name)::text) ~>=~ 'bla'::text) AND(lower((tag_name)::text) ~<~ 'postgs'::text)) Total runtime: 0.885 ms

Префиксный поиск: как сделать быстрее2. Создаём таблицу tag_words (уникальные теги), чтобы работать со словами, а не фразами:CREATE TABLE tag_words AS     SELECT DISTINCT word     FROM ts_stat('SELECT to_tsvector(tag_name) FROM tag'); ­­  , ждём ждёмDROP INDEX i_tag_prefix;CREATE INDEX i_tag_fts ON tag USING gin(to_tsvector(tag_name));CREATE INDEX i_tag_words_prefix ON tag_words     USING btree(lower(word) text_pattern_ops);

test=# EXPLAIN ANALYZE   SELECT * FROM tag   WHERE to_tsvector('utf8_russian'::regconfig, tag_name::text)         @@ to_tsquery('utf8_russian', '(' || (          SELECT array_to_string(array_accum(lower(word)), '|')          FROM tag_words          WHERE lower(word) LIKE 'postgr%') || ')'); ­­   добавляем

­­'...&word1&word2',   если надо/*     */план опущен Total runtime: 13.243 ms(11 rows)

Комментарии и рейтинги для всего

obj

obj_id      INT8obj_status_did INT8obj_creator_obj_id INT8obj_created TIMESTAMPobj_modified TIMESTAMPobj_commented TIMESTAMPobj_marks_count INT4obj_marks_rating FLOAT8obj_tsvector tsvector

user

group

— Не SERIAL, см. следующий слайд— Значение из справочника— ID создателя (если применимо)

}­ NOT NULL DEFAULT CURRENT_TIMESTAMP

— Почти везде нужен полнотекст.

}- оцениваем всё!

comment

comment_author_obj_idcomment_text

comment

comment_text

user2obj

u2o_user_obj_idu2o_obj_obj_idu2o_marku2o_is_favorite

Комментарии и рейтинги для всегоcreate table comment (   obj_id INT8 not null default (((nextval('comment_obj_id_seq'::regclass) 

* 223072849) % (1000000000)::bigint) + 41000000000)     constraint c_obj_comment_obj_id check         (obj_id between 41000000000 and 41999999999),   comment_author_obj_id INT8,   comment_body VARCHAR (2000) NOT NULL,   constraint PK_MESSAGE primary key (obj_id))inherits (obj);

­­     ID:Как генерируются­­ nextID = (N mod Y) * X + S, ­­        where X & Y are co­primes, and S is an interval shift 

­­     sequence      !Используем отдельный для каждой таблицы

­­    :не забытьSET constraint_exclusion ON;

Google Maps mashup: с PostgreSQL это просто!

Как хранить и индексировать гео-данные в PostgreSQL:

– two integer columns and B-tree

– point column and R-tree

– PostGIS

– pgSphere

– Q3CGiST

Итоги

PostgreSQL обладает отличными возможностями, отвечающими нуждам Web 2.0 разработчиков

PostgreSQL позволяет разрабатывать быстро, без потери качества

Создавайте Web 2.0 проекты с PostgreSQL!

Контакты

nikolay@samokhvalov.comBlog: http://nikolay.samokhvalov.comXMPP/GTalk: samokhvalov@gmail.comSkype: samokhvalov OR postgresmen+7 905 783 9804

Спасибо!Спасибо!

Вопросы?Вопросы?

top related