К своей статье о хранении объектов я получил некоторое количество откликов, некоторые из которых были полезными (спасибо!), а некоторые немало меня удивили. Настолько, что я не могу удержаться от разъяснений.

В частности, мне посоветовали посмотреть в сторону объектных БД. Да, я понимаю, что красной линией в статье проходит несоответствие между объектной моделью и реляционной, но ведь в качестве вывода я написал, что собираюсь вообще отказаться от БД. Это и было основной мыслью. Видимо, я выразил эту мысль недостаточно явно, хотя мне казалось, что упоминания в названии статьи должно хватить. Однако, даже после еще одного упоминания в комментариях, мне все равно советуют объектные БД :-).

Надо сказать, что я сходил по совету из одного комментария на форум сайта sql.ru, где решил почитать тему с заинтересовавшим меня названием "РМД пора на пенсию?". Первые два ответа на обстоятельный пост живо напомнили мне, почему я не участвую во многих форумах, читать остальные 14 страниц охота сразу отпала, хотя возможно там было что-то полезное.

Помимо объектных БД еще несколько комментариев упоминают, что БД - это не просто тупое хранилище, а сложный и умный механизм. Ага. Я в статье отдельно упомянул, что подобный механизм в рассматриваемых случаях избыточен. Это как раз одна из причин, которой я обосновывал отказ от БД.

И последнее, что меня удивило, это сквозящий в некоторых комментариях тон "мальчик придумывает велосипед, сейчас мы его ткнем носом куда надо". Может мне и почудилось это, но я хочу попросить всех, кто так и вправду считает, все-таки прочитать статью. В смысле, еще раз. И если будут возражения по сути и с обоснованием - милости прошу прокомментировать :-)

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

  1. Юзабилист

    Поддерживаю Ваш вывод о том, что база данных не нужна. Для многих практических решений набор операций над данными довольно небольшой, причём обычно выборка используется чаще, чем добавление или изменение.

    Поэтому связка ДанныеВВидеXMLФайлов + XQueryНаЛюбомДоступномПарсере с успехом заменяет базу данных. При этом формат хранения получается независимым от используемого механизма доступа.

  2. Иван Сагалаев

    Вот с XQuery я, опять же, не согласен. Принципиальная разница, которую я хочу подчеркнуть, это как раз отсутствие произвольного доступа к данным на диске. Они даже не должны быть пригодны для внешнего доступа, а быть только отображением объектного кода. И уже объекты, восстанавливая состояние из данных на диске, могут с ними оперировать, и только они. Это дает гарантию того, что данные всегда находятся в логически правильном виде (ну с точностью до багов, конечно :-) ). Если же к данным на диске дать некий обобщенный доступ (неважно, СУБД или X-что-нибудь), то на логическую корректность данных, которая поддерживается набором методов объектов программы, уже нельзя будет положиться.

  3. Сергей Осипчук

    Этот подход надо иметь на вооружении, но пропогандировать его как основное средство сложно - причины огромный выбор инструментария, стандарты (те же транзакции например, сам язык SQL) которые известны всем, концепции которые тоже всем известны.
    Я на должности архитектора в одном крупном проекте (>5 человеколет) отказывался от определённых отличных идей просто потому что это слишком необычные идеи, которые будет сложно понять человеку, который будет разбираться с этим кодом через n лет.
    Как говориться, будьте проще - и к вам потянутся люди :)
    И поэтому во многих случаях лучше взять велосипед, прикрутить к нему что-то, чем делать своё суперовый 5ти колёсный.

  4. Сергей Петров

    Объясни дураку, пожалуйста.

    Вот имеем мы набор из пары сотен тысяч сущностей. Каждая - нормальный такой объект. С данными килобайта на два и кучкой методов.

    Как ты делаешь из них выборку по определенному признаку?

  5. Иван Сагалаев

    В такие объемы я не лезу. Ты много видел форумов или внутренних баг-тракингов с парой сотен тысяч объектов?

    Отвечая же по сути, сам вопрос о таких выборках не стоит. Почти никогда в оперативном использовании тебе не нужна возможность делать быстро абсолютно произвольные запросы. Вместо этого есть с десяток конкретных задач, которые можно решить индексами, кешированием, другой логикой, бог знает чем еще. Когда у тебя нет БД, то ты не связан никакой моделью доступа к данным. Если считать 200000 файлов по 2 килобайта из директории дорого, то никто не заставляет тебя это делать.

    В БД другой подход: ты не контролируешь эффективность механики доступа к данным, полгагаясь на математическую модель оптимизации, заложенную в базе. В каких-то случаях она окажется очень хорошей, а в каких-то - нет. Другое дело, что если у тебя реально большой проект, то БД выигрывают тем, что избавляют от необходимости писать большое количество оптимизирующего кода. Пусть это не максимально эффективно, но зато на разработку не уйдет 20 лет.

    Вот поэтому я и не говорю про сотни тысяч записей.

    Повторюсь еще раз, я нигде не сказал, что БД - это зло. Я сказал, что для форума/баг-тракинга/wiki среднего размера отказ от БД может принести большую выгоду в удобстве скорости и надежности разработки. И эта выгода будет больше чем минимальная потеря или выигрыш в эффективности особенно странных выборок.

  6. Лобанов Леонид

    Я сказал, что для форума/баг-тракинга/wiki среднего размера отказ от БД может принести большую выгоду в удобстве скорости и надежности разработки.

    Официально заявляю - отказ от БД вам никакой выгоды не принесёт! Работа с файлами намного менее надёжна, чем работа с БД (да хоть бы из-за переносов строк). Сам когда-то БД не использовал - как раз при переходе к использованию скорость разработки и удобство возросли. Разумеется, если у Вас однотипные данные о товарах, которые добавляются не через веб-интерфейс, а, к примеру, после парсинга каталога в excel - их можно хранить в текстовом файле (если память не жалко его грузить при каждом обращении к странице). Однако хранить при этом сделанные заказы и данные пользователей тоже в текстовых файлах - совершенно расточительно по отношению к времени программиста. Для форума вообще без вариантов - хранить сообщения в БД и только в БД.

    P.S. статью, про которую разговор не читал :). Сейчас прочитаю, там в комментах если что, напишу :).
    P.P.S. RSS найти не могу. Где он?
    __
    Фильмы на CD

  7. Лобанов Леонид

    Атом нашёл. Но только на главной - зря. На каждой странице надо. Да и вообще - это ж WordPress - насколько сильно его кастрировали, что он alternate link не выдаёт? А то опера его очень хорошо распознаёт и выдаёт кнопочку на feed прям рядом с урлом.
    __
    Фильмы на CD

  8. Иван Сагалаев

    Не только на главной. Еще на каждой странице категории.

    И alternate там есть. Но на каждой странице его пихать неверно, потому что фид ко всему сайту не является альтернативным представлением одного поста.

  9. Сергей Петров

    Все равно не понимаю.

    Вот у тебя багтракинговая система. Скажем, 5 тысяч багов - вполне реальное число.

    Предположим, я хочу увидеть все баги, заведенные определенным пользователем.

    Как это у тебя реализовано в коде?

  10. Иван Сагалаев
        <p>Ну, как совсем прямо в коде, можно посмотреть. Скачай [бету](http://softwaremaniacs.org/soft/taco/taco-beta.zip), там bugs.py.</p>
    

    Но упрощенно это примерно так.

    • Создается список TBugList(Project,{'Owner':[UserId]})

    • У него в конструкторе перебираются файлики из директории проекта:
        for File in os.listdir(CurrentProject.BugsPath()):
          Bug=TBug(File)
          if Bug['Owner']==Query['Owner']:
            list.append(Bug)

    • Конструктор же TBug парсит файлик и достает оттуда значения полей. Файлик выглядит например вот так: http://softwaremaniacs.org/taco/projects/Test/bugs/1.bug

  11. Максим Ищенко

    Надеюсь, мой комментарий менторским тоном не прозвучал - его там не было. :)

  12. Лобанов Леонид

    И alternate там есть.

    У данной страницы - нет.

    Но на каждой странице его пихать неверно, потому что фид ко всему сайту не является альтернативным представлением одного поста.

    Неверно - заставлять юзера идти на главную, что б подписаться, если ему блог понравился. Ведь он может и не пойти.

    Конструктор же TBug парсит файлик и достает оттуда значения полей.

    То есть, парсим все 5 тыс файлов? Ничего не скажешь, выгода отказа от БД налицо.

  13. Yura Ivanov

    Ну можно же создать индексный файл и парсить UserBugsCount+1 файлов. Хотя в любом случае оптимальности здесь приходится добиваться - анализировать объекты целиком если нужен один реквизит не очень хорошая идея, имхо.

  14. Иван Сагалаев

    Ага. Именно так и будет :-). У меня уже запланирована пара индексов (Task 15, Task 48). Больше того, я вообще собираюсь строить индексы динамически для всех сохраненных запросов юзеров.

    Другое дело, что сейчас в самом большом проекте 160 тасков, а не 5000, поэтому эта штука меня еще не скоро озаботит.

    Касаемо парсинга тоже все не так просто, как я написал :-). Когда от таска нужен только хедер, парсится только он. SAX рулит :-)

  15. Денис Зайцев

    Интересная задумка :-)
    Ведь действительно, если не нужна большая расширяемость, простота обслуживания, произвольные запросы, согласованный доступ, кеширование, транзакции, защита и т.п. фичи, традиционно решаемые dbms'ами, то можно и самому написать простой доступ к xml-файлам. Лишь бы не получилась замечательная однопользовательская система ;-)
    Впрочем, если изначально разработать простенький api для доступа к объектам (а насколько я понял, он реализован классом TBug), то если понадобится что-то из перечисленного - можно и db прикрутить ;-)
    На мой взгляд, нужно еще добавить какой-то несложный механизм контроля целостности файлов (crc?): помнишь как в нашей bugzill'е однажды пропали некоторые баги, пока мы mysql'ные таблички не починили? А ведь это какая-никакая, но dbms... что произойдет, если xml'ные файлы побъются?
    Или в таком случае xml просто не распарсится?
    К слову сказать, в мире уже полно dbms c "врожденной" и "естественной" поддержкой xml, объектно-ориентированных и не очень, с разными наборами "фич": тот же Berkeley XML DB может устанавливаться в комбинациях single writer, multiple readers; multiple writers and readers, ets... Кстати, поддерживает Python ;-)
    Быть может даже удастся найти dbms без поддержки запросов.

  16. Иван Сагалаев

    Некоторый контроль целостности получается с XML'ом бесплатно. Он же должен быть well-formed, поэтому при нарушении структуры парсер тут же ругнется. Другое дело, что если, скажем, часть текстового комментария побьется, то есть вероятность, что парсер этого не заметит.

  17. Евгений Кремер

    Всё это конечно интересно, о чём здесь идет речь, но как уже было сказано выше, использование БД ускорит процесс разработки. И пожалуйста не отмахивайтесь от этих слов. Сам язык запросов очень гибок, у меня иногда складывается мнение он может все. Базы данных намного быстрее обрабатывают данные чем парсер для XML. В то время как Вы отлаживаете работу с файлами, БД уже установлена и работает. Нужно концентрироваться на задаче, а не на второстепенных отвлетвлениях.
    Огромная благодарнось Автору этого Блога, очень хорошо и интересно пишете!

  18. Иван Сагалаев

    Хм... Как раз из-за ускорения процесса обработки я и начал думать о том, чтобы не использовать БД :-). В общем и целом, при наличии библиотек с точки зрения кода выборка из БД и парсинг файла одинаково просты: вызов одной-двух функций. С XML'ом не надо ничего отлаживать, там все работает.

    Но с БД обязательно добавляется еще одна головная боль: ее обслуживание. И оно как раз и есть - второстепенные ответвления. Я сделал объект, в котором у меня есть поля. Если мне надо записать это в файл, я просто записываю это в файл. В случае БД мне надо еще создать табличку, которая будет повторять структуру объекта, менять ее, если меняю объект. Вот это - лишние действия.

    P.S. Насчет гибкости - тоже наоборот. SQL - декларативный язык - в принципе менее гибок, чем любой императивный :-). Он просто не полный по Тьюрингу.

  19. Евгений Кремер

    Я не хочу ввязываться в спор, т.к я Вас уважаю и думаю Вы знаете, что говорите. SQL - я хотел сказать, что в плане запросов он могуч, а БД быстра и никакому парсеру до них не добраться. Только даже по одной причине - "Способ хранения данных". Конечно, если скорость не важна и есть желание ковыряться, можно только похвалить.
    Я бы сделал предка для класса, который умеет модифицировать БД (заводить новые таблицы для новых потомков[при первом инстанциировании], или БД.поля, если у класса добавились поля). Но это дело вкуса и стечения обстоятельств.
    Удачи и хороших идей для этого проекта!

Добавить комментарий