o7412369815963
пока не делал, но все равно пока вариантов нет. буду делать так.
Попробовал потестить. Создал таблицу, где один столбец - данные, другой - тег:
/*create table*/
CREATE TABLE entry (
id SERIAL,
data varchar(32),
tag varchar(32)
);
Забил таблицу записями. На каждую единицу данных - пять различных тегов. Теги добавлялись в список последовательно, по мере заполнения таблицы, чтобы одни теги встречались чаще других.
import random
import hashlib
import psycopg2
CONN_STRING = "dbname=tags user=pmaster"
RECORDS = 1000000
TAGS = 1000
TAGS_FOR_RECORD = 5
def main():
tags = ['a', 'b', 'c', 'd', 'e']
progress = 0
record_list = []
for i in xrange(RECORDS/TAGS_FOR_RECORD):
#generating data to be saved
use_tags = random.sample(tags, 5)
data = hashlib.md5(str(i)).hexdigest()
record_list.append([data, use_tags])
#splitting data into portions
if i % (RECORDS/(TAGS_FOR_RECORD*TAGS)) == 0:
#printing progress
progress += 1
print progress
save_records(record_list)
record_list = []
#adding new tags
tags.append('tag%s' %i)
save_records(record_list)
print '---'
print 'records:', (i+1)*TAGS_FOR_RECORD, 'tags:', len(tags)
def save_records(record_list):
conn = psycopg2.connect(CONN_STRING)
cur = conn.cursor()
for data, tags in record_list:
for tag in tags:
cur.execute('insert into entry (data, tag) values (%s, %s)', (data, tag))
conn.commit()
cur.close()
conn.close()
Получаем начальное облако:
/* get tag cloud of most popular tags*/
select
count(tag), tag
from
entry
group by
tag
order by
count(tag) desc fetch first 100 rows only
/* 0.39 s */
Сужаю теги:
select
count(tag), tag
from
entry
where (data in (
select
data
from
entry
where
tag='d'))
and (tag!= 'd')
group by
tag
order by
count(tag) desc
fetch first 100 rows only
/* 0.79 s */
А вот получение самих данных уже по-быстрее:
select distinct
data
from
entry
where
(tag = 'b') and data in (
select
data
from
entry
where
tag = 'c')
fetch first 100 rows only
/* 0.25 s */
Если убрать distinct, то еще вдвое быстрее.
В общем, не фонтан, конечно, тестил на ноутбуке core 2 duo 2.1 GHz, 2Gb mem. Вопрос в том какое будет железо, ну и запросы влоб, какие я для тестов использовал, нужно заменить скорее всего на что-то более адекватное.