среда, 27 июля 2011 г.

Re: Как хранить разнотипные данные?

Вот тоже сомнительно хранить сериализованные данные. Сфинкс, конечно, поищет по ним, но блин, как же это геморойно для тестирования и вообще для работы с этим. Хранить поля вида key-value - очень тяжёлая штука для rdbms.
Лично я вижу тут 2 варианта - использовать key-value бд для дополнительных данных - тогда и поиск будет достаточно быстр, но, опять же, очень сложные интерфейсы реализовать придётся. Самый простой вариант, подходящий к предметной области - документоориентированные бд. Пишем map-reduce функцию для выборки, ну или пользуемся встроенным  языком запросов для выборки - милое дело.

27 июля 2011 г. 10:44 пользователь Max Lapshin <max.lapshin@gmail.com> написал:
Насколько я понимаю, речь идет о чем-то типа того, что я делал ещё для
профотоса: есть фотоаппарат/объектив и т.п., у них есть по две сотни
параметров (группирующихся), которые ещё и разнотипные:
строка/число/словарь.

Пусть Серега расскажет, оказалась ли схема жизнеспособной, но для меня
работало так:

таблица devices -- тут хранятся экземпляры устройств. Разделение по
полю kind, потому что для товаров STI был лишним -- никакого разделения
логики нет.
таблица attributes -- тут хранятся типы свойств. Например:  title =
"Диафрагма мин.", name = "aperture_min", prop_type = "n"
В ней как раз писался тип значения: число, строка и т.п.
таблица attribute_dictionaries:  attribute_id, attribute_title, attribute_value

таблица device_attributes:  attribute_id, device_id, value_s (string),
value_n(numeric), value_d(attribute_dictionary_id) и сюда же
кешировалось поле prop_type
Обратите внимание на то, что в этой таблице хранится три разных value,
интерпретация которых зависит от значения в attributes.
Это хорошо, правильно, и работает, потому что на value_n можно
наложить индекс. Хранить всё в text -- очень, очень, очень плохая идея.

Дальше понятно: вытаскиваем device, тянем его device_attributes,
джойним с attributes и по необходимости attribute_dictionaries

Сложно? Соразмерно сложности предметной области. Это всё оказалось
очень удобно в перспективе, когда можно было интерпретатором
специального языка вида:

aperture_min:[2,6]
kind: camera
price:[15000,23000]

выбрать пристойные мыльницы с хорошим объективом.

Такая конструкция чрезвычайно удобна для редактирования и поиска. В
несравненное количество раз удобнее, чем хранение JSON/YAML. Говорят,
что так же удобно в MSSQL можно положить XML, заботать XPATH в
реализации MS и получить то же самое. Но зачем, если это ровно та
задача, под которую создавался SQL?

Есть одна проблема: вытаскивание этих данных мучительно. Я её решил не
самым лучшим образом: создал постгресовые типы и одним большим
апдейтом заливал все данные одного девайса в поле cached_attributes в
постгресовом представлении. Это было очень удобно в том смысле, что
один UPDATE где-то на 5-10 секунд заливал кеш всей базы данных в поля.
После этого парсил хранящееся представление и вытаскивал в нужном виде
поле attributes, пригодное для рендеринга в шаблоне.

Это решение плохо тем, что ни рельсы, ни datamapper, ни какой ещё
другой ORM на руби, оказались совершенно бессильны перед кастомным
типом данных в БД. В итоге засунуть этот кеш в тесты оказалось
невозможно.
Наверное, будет работать существенно более ресурсоёмкий способ с
генерацией такого кеша на уровне руби: когда поправилось поле,
аггрегируем все поля и заливаем их в один большой блоб. Но по этому
блобу искать не получится, для этого есть прекрасно работающая таблица
devise_attributes


После всего этого я попытался залить такую структуру в mongodb.
Собственно говоря, получил ровно тот же JSON-кеш, но без возможности
поиска и выборки.

--
--
Данное сообщение отправлено Вам, так как Вы являетесь подписчиком группы "RubyOnRails to russian" на группах Google.
FAQ группы находится по адресу: http://ru.wikibooks.org/wiki/RubyFAQ

 Для того, чтобы отправить сообщение в эту группу, пошлите его по адресу
ror2ru@googlegroups.com
 Чтобы отменить подписку на эту группу, отправьте сообщение по адресу: ror2ru-unsubscribe@googlegroups.com
 Дополнительные варианты находятся на странице группы http://groups.google.com/group/ror2ru?hl=ru

--
--
Данное сообщение отправлено Вам, так как Вы являетесь подписчиком группы "RubyOnRails to russian" на группах Google.
FAQ группы находится по адресу: http://ru.wikibooks.org/wiki/RubyFAQ
 
Для того, чтобы отправить сообщение в эту группу, пошлите его по адресу
ror2ru@googlegroups.com
Чтобы отменить подписку на эту группу, отправьте сообщение по адресу: ror2ru-unsubscribe@googlegroups.com
Дополнительные варианты находятся на странице группы http://groups.google.com/group/ror2ru?hl=ru

Комментариев нет:

Отправить комментарий