hstore и целочисленные значения

Xupypr

Новичок
День добрый.

Такой вопрос.

Есть данные в формате hstore, например таблица items_count, поля пусть будут items_order::int() и items::hstore

Значения к примеру
items_order:11
items: '1'=>'11', '2'=>'0', '5'=>'8'

тут ключь - id вещи, значение - количество, т.е. всегда int

к примеру я хочу увеличить значение вещи 5 на 2, чтоб стало 10.

приходится делать так
UPDATE items_count SET items=items || '5=>10'::hstore WHERE items_order=11;

т.е. надо предварительно через php протащить селект, вытащить значения 5го ключа, сложить и потом только записать... тут как бы вероятен race condition, т.к. нагрузки не малые, поэтому хотелось бы к значению в базе просто прибавлять нужное значение по типу item=item+2;

чту доку: http://www.postgresql.org/docs/9.0/static/hstore.html
както не обнаружил там такого.
 

Xupypr

Новичок
UPDATE items_count SET items=items || ('5'=>to_char((
to_number(items::hstore->'5', '999999999999999999')+2), 'FM999MI'))::hstore WHERE items_order=11;


все пашет, но есть одно но - когда ключа такого нет, то он его добавляет, но со значением NULL ... а надоб чтоб если нету, то бралось как 0 и прибавлялось сколько надо.
 

Xupypr

Новичок
переписал запрос, упростил в разы ))

UPDATE items_count SET items=items||('5'=>(((items::hstore->'5')::int+2))::text)::hstore WHERE items_order=11;

но проблема с NULL при отсутствии осталась
 

~WR~

Новичок
(items::hstore->'5') оберните в
PHP:
COALESCE((items -> '5')::int, 0)
Будет ноль в случае отсутствия значения.

Вообще, разрывной type casting - это общая проблема типов данных из contrib. Я бы очень хотел видеть в PostgreSQL типы ltree_int и hstore_int, которые были бы дополнительно оптимизированы для работы только с int'ами. Для меня это наиболее частый случай.
 

Xupypr

Новичок
(items::hstore->'5') оберните в
PHP:
COALESCE((items -> '5')::int, 0)
блестяще! то что нужно! да оптимизации под нужный тип очень не хватает.


для страждущих, итоговый запрос

PHP:
UPDATE items_count SET items=items||('5'=>((COALESCE((items::hstore->'5')::int, 0)+2))::text)::hstore WHERE items_order=11;
 

MiksIr

miksir@home:~$
Один из случаев, ИМХО, когда лучше "по старинке" делать один-ко-многим.
 
Сверху