Пользователь
0,0
рейтинг
27 сентября 2012 в 12:16

Разработка → NoSQL базы данных: понимаем суть из песочницы

В последнее время термин “NoSQL” стал очень модным и популярным, активно развиваются и продвигаются всевозможные программные решения под этой вывеской. Синонимом NoSQL стали огромные объемы данных, линейная масштабируемость, кластеры, отказоустойчивость, нереляционность. Однако, мало у кого есть четкое понимание, что же такое NoSQL хранилища, как появился этот термин и какими общими характеристиками они обладают. Попробуем устранить этот пробел.



История.


Самое интересное в термине, что при том, что впервые он стал использоваться в конце 90-х, реальный смысл в том виде, как он используется сейчас, приобрел только в середине 2009. Изначально так называлась опенсорсная база данных, созданная Карло Строззи, которая хранила все данные как ASCII файлы и использовала шелловские скрипты вместо SQL для доступа к данным. С “NoSQL” в его нынешнем виде она ничего общего не имела.

В июне 2009 в Сан-Франциско Йоханом Оскарссоном была организована встреча, на которой планировалось обсудить новые веяния на ИТ рынке хранения и обработки данных. Главным стимулом для встречи стали новые опенсорсные продукты наподобие BigTable и Dynamo. Для яркой вывески для встречи требовалось найти емкий и лаконичный термин, который отлично укладывался бы в Твиттеровский хэштег. Один из таких терминов предложил Эрик Эванс из RackSpace — «NoSQL». Термин планировался лишь на одну встречу и не имел под собой глубокой смысловой нагрузки, но так получилось, что он распространился по мировой сети наподобие вирусной рекламы и стал де-факто названием целого направления в ИТ-индустрии. На конференции, к слову, выступали Voldemort (клон Amazon Dynamo), Cassandra, Hbase (аналоги Google BigTable), Hypertable, CouchDB, MongoDB.

Стоит еще раз подчеркнуть, что термин “NoSQL” имеет абсолютно стихийное происхождение и не имеет общепризнанного определения или научного учреждения за спиной. Это название скорее характеризует вектор развития ИТ в сторону от реляционных баз данных. Расшифровывается как Not Only SQL, хотя есть сторонники и прямого определения No SQL. Сгруппировать и систематизировать знания о NoSQL мире попытались сделать Прамод Садаладж и Мартин Фаулер в своей недавней книге “NoSQL Distilled”.

Характеристики NoSQL баз данных


Общих характеристик для всех NoSQL немного, так как под лэйблом NoSQL сейчас скрывается множество разнородных систем (самый полный, пожалуй, список можно найти на сайте http://nosql-database.org/). Многие характеристики свойственны только определенным NoSQL базам, это я обязательно упомяну при перечислении.

1. Не используется SQL

Имеется в виду ANSI SQL DML, так как многие базы пытаются использовать query languages похожие на общеизвестный любимый синтаксис, но полностью его реализовать не удалось никому и вряд ли удастся. Хотя по слухам есть стартапы, которые пытаются реализовать SQL, например, в хадупе (http://www.drawntoscalehq.com/ и http://www.hadapt.com/ )

2. Неструктурированные (schemaless)

Смысл таков, что в NoSQL базах в отличие от реляционных структура данных не регламентирована (или слабо типизированна, если проводить аналогии с языками прогаммирования) — в отдельной строке или документе можно добавить произвольное поле без предварительного декларативного изменения структуры всей таблицы. Таким образом, если появляется необходимость поменять модель данных, то единственное достаточное действие — отразить изменение в коде приложения.

Например, при переименовании поля в MongoDB:

BasicDBObject order = new BasicDBObject();
order.put(“date”, orderDate); // это поле было давно
order.put(“totalSum”, total); // раньше мы использовали просто “sum”

Если мы меняем логику приложения, значит мы ожидаем новое поле также и при чтении. Но в силу отсутствия схемы данных поле totalSum отсутствует у других уже существующих объектов Order. В этой ситуации есть два варианта дальнейших действий. Первый — обойти все документы и обновить это поле во всех существующих документах. В силу объемов данных этот процесс происходит без каких-либо блокировок (сравним с командой alter table rename column), поэтому во время обновления уже существующие данные могут считываться другими процессами. Поэтому второй вариант — проверка в коде приложения — неизбежен:

BasicDBObject order = new BasicDBObject();
Double totalSum = order.getDouble(“sum”); // Это старая модель
if (totalSum  == null)
	totalSum = order.getDouble(“totalSum”); // Это обновленная модель


А уже при повторной записи мы запишем это поле в базу в новом формате.

Приятное следствие отсутствия схемы — эффективность работы с разреженными (sparse) данными. Если в одном документе есть поле date_published, а во втором — нет, значит никакого пустого поля date_published для второго создано не будет. Это, в принципе, логично, но менее очевидный пример — column-family NoSQL базы данных, в которых используются знакомые понятия таблиц/колонок. Однако в силу отсутствия схемы, колонки не объявляются декларативно и могут меняться/добавляться во время пользовательской сессии работы с базой. Это позволяет в частности использовать динамические колонки для реализации списков.

У неструктурированной схемы есть свои недостатки — помимо упомянутых выше накладных расходов в коде приложения при смене модели данных — отсутствие всевозможных ограничений со стороны базы (not null, unique, check constraint и т.д.), плюс возникают дополнительные сложности в понимании и контроле структуры данных при параллельной работе с базой разных проектов (отсутствуют какие-либо словари на стороне базы). Впрочем, в условиях быстро меняющегося современного мира такая гибкость является все-таки преимуществом. В качестве примера можно привести Твиттер, который лет пять назад вместе с твиттом хранил лишь немного дополнительной информации (время, Twitter handle и еще несколько байтов метаинформации), однако сейчас в дополнение к самому сообщению в базе сохраняется еще несколько килобайт метаданных.

(Здесь и далее речь идет в-основном о key-value, document и column-family базах данных, graph базы данных могут не обладать этими свойствами).

3. Представление данных в виде агрегатов (aggregates).

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



В этом примере продемонстрированы агрегаты для стандартной концептуальной реляционной модели e-commerce “заказ — позиции заказа — платежи — продукт”. В обоих случаях заказ объединяется с позициями в один логический объект, при этом каждая позиция хранит в себе ссылку на продукт и некоторые его атрибуты, например, название (такая денормализация необходима, чтобы не запрашивать объект продукта при извлечении заказа — главное правило распределенных систем — минимум “джоинов” между объектами). В одном агрегате платежи объединены с заказом и являются составной частью объекта, в другом — вынесены в отдельный объект. Этим демонстрируется главное правило проектирования структуры данных в NoSQL базах — она должна подчиняться требованиям приложения и быть максимально оптимизированной под наиболее частые запросы. Если платежи регулярно извлекаются вместе с заказом — имеет смысл их включать в общий объект, если же многие запросы работают только с платежами — значит, лучше их вынести в отдельную сущность.

Многие возразят, заметив, что работа с большими, часто денормализованными, объектами чревата многочисленными проблемами при попытках произвольных запросов к данным, когда запросы не укладываются в структуру агрегатов. Что, если мы используем заказы вместе с позициями и платежами по заказу (так работает приложение), но бизнес просит нас посчитать, сколько единиц определенного продукта было проданно в прошлом месяце? В этом случае вместо сканирования таблицы OrderItem (в случае реляционной модели) нам придется извлекать заказы целиком в NoSQL хранилище, хотя большая часть этой информации нам будет не нужна. К сожалению, это компромисс, на который приходится идти в распределенной системе: мы не можем проводить нормализацию данных как в обычной односерверной системе, так как это создаст необходимость объединения данных с разных узлов и может привести к значительному замедлению работы базы
Плюсы и минусы обоих подходов я попытался сгруппировать в табличке:



4. Слабые ACID свойства.

Долгое время консистентность (consistency) данных была “священной коровой” для архитекторов и разработчиков. Все реляционные базы обеспечивали тот или иной уровень изоляции — либо за счет блокировок при изменении и блокирующего чтения, либо за счет undo-логов. С приходом огромных массивов информации и распределенных систем стало ясно, что обеспечить для них транзакционность набора операций с одной стороны и получить высокую доступность и быстрое время отклика с другой — невозможно. Более того, даже обновление одной записи не гарантирует, что любой другой пользователь моментально увидит изменения в системе, ведь изменение может произойти, например, в мастер-ноде, а реплика асинхронно скопируется на слейв-ноду, с которой и работает другой пользователь. В таком случае он увидит результат через какой-то промежуток времени. Это называется eventual consistency и это то, на что идут сейчас все крупнейшие интернет-компании мира, включая Facebook и Amazon. Последние с гордостью заявляют, что максимальный интервал, в течение которого пользователь может видеть неконсистентные данные составляют не более секунды. Пример такой ситуации показан на рисунке:



Логичный вопрос, который появляется в такой ситуации — а что делать системам, которые классически предъявляют высокие требования к атомарности-консистентности операций и в то же время нуждаются в быстрых распределенных кластерах — финансовым, интернет-магазинам и т.д? Практика показывает, что эти требования уже давно неактуальны: вот что сказал один разработчик финансовой банковской системы: “Если бы мы действительно ждали завершения каждой транзакции в мировой сети ATM (банкоматов), транзакции занимали бы столько времени, что клиенты убегали бы прочь в ярости. Что происходит, если ты и твой партнер снимаете деньги одновременно и превышаете лимит? — Вы оба получите деньги, а мы поправим это позже.” Другой пример — бронирование гостиниц, показанный на картинке. Онлайн-магазины, чья политика работы с данными предполагает eventual consistency, обязаны предусмотреть меры на случай таких ситуаций (автоматическое решение конфликтов, откат операции, обновление с другими данными). На практике гостиницы всегда стараются держать “пул” свободных номеров на непредвиденный случай и это может стать решением спорной ситуации.

На самом деле слабые ACID свойства не означают, что их нет вообще. В большинстве случаев приложение, работающее с реляционной базой данных, использует транзакцию для изменения логически связанных объектов (заказ — позиции заказа), что необходимо, так как это разные таблицы. При правильном проектировании модели данных в NoSQL базе (агрегат представляет из себя заказ вместе с перечнем пунктов заказа) можно добиться такого же самого уровня изоляции при изменении одной записи, что и в реляционной базе данных.

5. Распределенные системы, без совместно используемых ресурсов (share nothing).

Опять же, это не касается граф баз данных, чья структура по определению плохо разносится по удаленным нодам.

Это, возможно, главный лейтмотив развития NoSQL баз. С лавинообразным ростом информации в мире и необходимости ее обрабатывать за разумное время встала проблема вертикальной масштабируемости — рост скорости процессора остановился на 3.5 Ггц, скорость чтения с диска также растет тихими темпами, плюс цена мощного сервера всегда больше суммарной цены нескольких простых серверов. В этой ситуации обычные реляционные базы, даже кластеризованные на массиве дисков, не способны решить проблему скорости, масштабируемости и пропускной способности. Единственный выход из ситуации — горизонтальное масштабирование, когда несколько независимых серверов соединяются быстрой сетью и каждый владеет/обрабатывает только часть данных и/или только часть запросов на чтение-обновление. В такой архитектуре для повышения мощности хранилища (емкости, времени отклика, пропускной способности) необходимо лишь добавить новый сервер в кластер — и все. Процедурами шардинга, репликации, обеспечением отказоустойчивости (результат будет получен даже если одна или несколько серверов перестали отвечать), перераспределения данных в случае добавления ноды занимается сама NoSQL база. Вкратце представлю основные свойства распределенных NoSQL баз:

Репликация — копирование данных на другие узлы при обновлении. Позволяет как добиться большей масштабируемости, так и повысить доступность и сохранность данных. Принято подразделять на два вида:
master-slave:



и peer-to-peer:



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

Шардинг — разделение данных по узлам:



Шардинг часто использовался как “костыль” к реляционным базам данных в целях увеличения скорости и пропускной способности: пользовательское приложение партицировало данные по нескольким независимым базам данных и при запросе соответствующих данных пользователем обращалось к конкретной базе. В NoSQL базах данных шардинг, как и репликация, производятся автоматически самой базой и пользовательское приложение обособленно от этих сложных механизмов.

6. NoSQL базы в-основном оупенсорсные и созданы в 21 столетии.

Именно по второму признаку Садаладж и Фаулер не классифицировали объектные базы данных как NoSQL (хотя http://nosql-database.org/ включает их в общий список), так как они были созданы еще в 90-х и так и не снискали большой популярности.

Дополнительно я хотел остановиться на классификации NoSQL баз данных, но, пожалуй, сделаю это в следующей статье, если это будет интересно хаброюзерам.

Резюме.


NoSQL движение набирает популярность гигантскими темпами. Однако это не означает, что реляционные базы данных становятся рудиментом или чем-то архаичным. Скорее всего они будут использоваться и использоваться по-прежнему активно, но все больше в симбиозе с ними будут выступать NoSQL базы. Мы вступаем в эру polyglot persistence — эру, когда для различных потребностей используются разные хранилища данных. Теперь нет монополизма реляционных баз данных, как безальтернативного источника данных. Все чаще архитекторы выбирают хранилище исходя из природы самих данных и того, как мы ими хотим манипулировать, какие объемы информации ожидаются. И поэтому все становится только интереснее.
Anton Lisovenko @bitec
карма
29,0
рейтинг 0,0
Пользователь
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Спецпроект

Самое читаемое Разработка

Комментарии (75)

  • +2
    О плюсах вижу много и везде.
    Хотелось бы узнать от профессионалов о минусах NoSQL (по сравнению с SQL)
    • +17
      Да много «минусов». При этом, рассматривать нужно каждую систему отдельно.
      Например, в известных мне NoSQL-системах нет контроля целостности данных — транзакций, внешних ключей.
      Производительность сложных выборок (которые в SQL реализовывались бы JOIN'ами и GROUP BY) сильно страдает. Зато записывать данные можно быстро и непринуждённо :)
      Отсутствие чётко заданной структуры данных во многих случаях тоже может быть рассмотрено как минус — становится сложнее поддержка системы.

      Вообще говоря, сравнивать лучше на каких-то примерах. Например, такие типы БД как OLTP и OLAP тоже сложно сравнивать абстрактно.
      У нас, вот, mongoDB используется чисто для записи больших объёмов данных. Потом эти данные прогоняются через map/reduce фреймворк и частично попадают в SQL-БД в нормализированном виде.
      А из SQL-БД, в целях анализа, часть данных выбирается ETL-скриптами и перекочёвывает в data warehouse, с помощью которого далее процессится OLAP-куб.

      Каждому продукту — своё применение.
      • +1
        Прямо описали датафлоу компании, где я сейчас работаю, и технологии те же.
        Btw сейчас переходим на tokuMX вместо стандартного движка MongoDB — в плане производительности на запись намного лучше и полностью совместим с монгой.
    • +1
      Значительная часть статьи именно о минусах.
    • +10
      С надежностью всё печально.
      В классических реляционных СУБД вы можете загнать всю логику в транзакции в хранимых процедурах и ограничить права доступа приложения только вызовом этих процедур. Инкапсулировать данные, короче. И прикладному программисту будет ненужно думать о транзакциях, джойнах, схеме базы — он просто запускает нужную процедуру и получает результат, с соблюдением ACID.
      (В известных мне) NoSQL системах ничего похожего нет даже близко. Все join-ы, вложенные select-ы, транзакции — всё это должен делать прикладной программист, который в базах вобщем-то не специалист чаще всего.
      Ну и в бэкграунде SQL лежит доказанный мат. аппарат (реляционная алгебра), которая накладывает на клиентский код кучу ограничений. В результате SQL заставляет сначала подумать, потом сделать. В NoSQL никаких рамок нет, что хочу то ворочу — понятно к чему это приводит. Программистам предлагается самим написать свой слой объектов модели, которые лучше или хуже реализует нечто подобное SQL.
      Для быстрого прототипирования и массового выкатывания на рынок сырых бета-версий NoSQL конечно лучше. Для нормального софта — я не уверен.
      • +2
        > SQL заставляет сначала подумать, потом сделать

        Как раз-таки думать там надо меньше, потому что за тебя часто думает система и просто не пропустит ошибку. При работе с NoSQL думать надо гораздо больше, потому что даётся очень много свободы, которая может, при недостаточном продумывании, вылезти, что называется, боком.

        > В NoSQL никаких рамок нет, что хочу то ворочу — понятно к чему это приводит

        К чему? У нас проект почти 2 года живёт исключительно на MongoDB, и пока всё довольно неплохо. Не без узких мест (что есть, то есть), но не по вине хранилища, честно говоря. Как всегда, всё решают кадры. И на более привычных SQL решениях можно такого нагородить — мало не покажется. :)
        • +2
          В ситуации вседозволенности возникает соблазн по-быстрому влепить дополнительное поле или слабать отчетик на прямых запросах. Через какое-то время получится каша-каша, так как код работы с базой размазан тонким слоем по всему приложению.
          • +1
            Так я ж с этим и не спорю. Я ж говорю, что думать надо больше, чтоб этого не случилось. :)
      • –1
        Под надежностью обычно понимают другое. А вообще, то что всё должен делать прикладной программист — это правда. Более того NoSQL базы намного более понятны и приятны в работе для программистов. Следовательно DBA теряют востребованность и им это не нравится. :)
        • 0
          Я имел в виду надежность всего приложения, а не только базы. Если юзер ввел какие-то данные и система их приняла, эти данные ни при каких условиях не должны потеряться.
      • +1
        Да, в классических реляционных СУБД мы можем загнать всю логику в транзакции в хранимых процедурах и ограничить права доступа приложения только вызовом этих процедур. Но так делать на самом деле не нужно. И опа, NoSQL-подход становится не так уж и плох.
        • +1
          Можете привести хоть один аргумент, почему «на самом деле не ненужно»? Ну кроме инфантильного «это ж кому-то придется достаточно глубоко изучить SQL»?
          Плюсов у такого подхода дофига:
          1. Весь SQL код собран в одном месте, а не размазан по всей программе.
          2. Инкапсуляция. Изменилась внутренняя схема — подправили процедуры, остальное приложение может об этом и не узнать.
          3. Выше гадежность. Когда SQL-команды формируются клиентским приложением, возможна ситуация, когда из-за бага например отломалась секция WHERE в инструкции DELETE, и команда ушла без этой секции. Прощай, табличка:)
          4. Выше безопасность — даже если Ева сперла пароль от базы, она не может, допустим, достать оттуда пароли юзеров — потому как нет такой процедуры.

          А вот минусов, кроме «надо знать SQL», я как-то не вижу.
          • +1
            в п.3. следует читать «надежность», разумеется.
          • +3
            Могу чуть-чуть в другом ключе:

            1. Это не зависит от наличия\отсутствия хранимых процедур. Весь SQL (будь это даже просто вызовы хранимок) итак нужно держать в одном месте

            2. Сомнительный плюс, ИМХО. Если инкапсулировать логику и схему внутри БД и дать приложению только API — да, некоторые вещи сможет дорабатывать БД-специалист, без изменения кода приложения. Но при этом, стоимость первоначальной разработки всё же будет выше — ибо мы вводим дополнительный слой API, который резко ограничивает пространство для манёвра. На любой чих придётся пинать БД-шников и просить новую хранимку. Как результат — со временем это может вылиться в неподдерживаему кашу из процедур, делающих одно и тоже, но со своими нюансами. При этом, клиентский код будет ограничен спецификой БД и некоторые вещи будут выполняться неоптимально. Примеров из моей профессиональной практики — пруд пруди.

            3. А в процедуре такое невозможно? :-) В большинстве приложений SQL-запросы будут генериться автоматом (ORM) или забиты в код методов репозиториев. Вероятность бага там всё же презрительно мала и будет отловлена на этапе тестирования, после убивания всего-лишь никому не нужных тестовых данных.

            4. Сперев пароль от базы, кто мне запретит сделать select * from users?
            • 0
              1. Да, да, но в реальных проектах часто всё печальней.

              2. Отвечу в стиле вашего п.1: весь SQL код должен писать тот, кто хорошо знает SQL. Так какая разница, где именно пишет SQL-код этот специалист — в хранимой процедуре или где-то в недрах модели на прикладном языке?

              3. Ну в общем вероятность подобных ошибок в ХП ниже, чем без них. Про ОРМ не надо, сложные запросы они строить не умеют или делают это очень неэффективно. И чаще всего приходится либо делать пару джойнов «руками», либо писать SQL в обход ОРМа.
              Ну в общем могу согласиться, реляционные СУБД предполагают процедурное программирование и довольно плохо дружат с ООП (связть многие-ко-многим, напримре, в ООП представить не так-то просто. Обратный пример — наследование).

              4. Настройки грантов этого юзера БД, который имеет право только вызывать определенный список ХП и всё.
              • 0
                1. Ну, как же без этого :-)

                2. По сути, разницы нет. Изначально моя мысль заключалась в том, можно обойтись без транзакций, хранимок на стороне СУБД. В принципе, если опустить нюанс с тем, что прикладной программист должен быть чуточку умнее, нежели при использовании SQL — не думаю, что вы всё же против этой мысли.

                3. Не недо «не надо про ОРМ» :-) Это понятно, что не стоит пихать их везде и всюду, стоит иметь голову на плечах. Но разве вы со мной не согласитесь, что почти все сложные запросы, которые с трудом осилит ОРМ — это скорее всего будут отчёты? Даже я бы не советовал их делать с использованием чего-либо, отличного от SQL. Он здесь естественно на коне и совершенно в тему. Можно даже reporting database денормализованную подготовить, нагенерить её по триггерам из основной NoSQL/реляционной базы…

                4. Ну здесь я уже не знаю что сказать. Не встречал примеров, когда это оправданно (защищаться от коллег!). Видимо, мне повезло :-)
                • 0
                  3. Отчеты ладно. Более геморный пример из жизни — поиск по параметрам. А вот найди мне то, не знаю что, но чтоб недорого и с перламутровыми пуговицами. И рейтинг чтоб хороший был. И цвет — бордо или зеленый.

                  4. Ну вы же используете private в своём коде?
                  • 0
                    Ну, задача поиска это тоже, знаете ли. Не всегда хорошо ложится и на SQL. Но да, руками (в т.ч. через ОРМ) такое делать тоже не стоит :)

                    Private в коде классов и инкапсуляция модели данных приложения внутри СУБД — это всё же разные вещи. Зачем прятать от приложения то, что является его частью?
                  • 0
                    3. Отчеты ладно. Более геморный пример из жизни — поиск по параметрам. А вот найди мне то, не знаю что, но чтоб недорого и с перламутровыми пуговицами. И рейтинг чтоб хороший был. И цвет — бордо или зеленый.
                    Вы знаете эту задачу как раз noSQL аля Solr/Sphinx/Cloud Search решат скорее всего лучше чем любая БД и не помогут ручками написанные запросы.
          • 0
            Большое количество лишнего (причем довольно унылого) кода всех этих процедур, которого могло бы и вовсе не быть.

            У нас, например, в новой части системы есть сборка с чистыми классами с моделью предметной области, и есть дополнительная сборка, описывающая отображение этого хозяйства в БД (.NET, POCO, EF Code First, DB Migrations).

            При этом над схемой БД контроль полный, все изменения схемы, в т.ч. и при деплое новой версии кода и базы на live полностью автоматизированы.

            И по вашим пунктам:
            1. SQLя вообще нигде нет
            2. Если я добавляю в объект поле, в вашем случае нужно еще добавить его в таблицу и в *-цать процедур, с ней работающих, да не забыть нигде, да при отсутствии компиляции… беда. А структура базы «изнутри» не так часто меняется (если эта БД — просто слой сохраняемости для данного приложения). А вот изменения со стороны функционала, т.е. со стороны объектов, гораздо более часты.
            3. См п.1 — нет SQL — нет ошибок конкатенации. А просто DELETE без WHERE и процедуре точно так же напишете.
            4. Единственное — согласен. Но для большинства реальный ситуаций это не самая актуальная проблема, и есть много других решений у нее.

            А вот главный минус наличия чего-либо руками написанного на стороне БД — это лишнее место, куда может просочиться прикладная логика, что будет дополнительным усложнением и без того сложной программной системы.
        • +1
          «Но так делать на самом деле не нужно»

          Почему вдруг? Ни разу не слышал внятных ответов. (Кстати когда-то сам так думал, когда опыта было 1-2 года, но тогда просто где-то вычитал и просто хотел работать на своем языке, а SQL казался тяжелочитаемым).

          Но всё не так. Большая СУБД разрабатывается как сервер. Хорошо продумывается математика, оптимизация. Обычно, разрабатывают много неглупых людей.
          А потом появляются домашние программисты бизнес-логики, которые уверены, что базы нужны только для хранения объектов, а логику, включая транзакции, они будут писать сами.

          Мне нравится такая аналогия: пещерные люди за бешеные деньги покупают очень дорого танк последней модели. Привязывают тачку и возят танком копья.

          Если есть желание не пользовать реляционные БД — так кто мешает. Фокус в том, что простые базы для хранения в файлах и быстрого поиска по хешу — делаются нормальным программистом за день.

          Лично мне кажется, что мода на NoSql — слишком временна. Да, есть проблемы с производительностью. Но в большинстве случаев они не такие большие и эти проблемы берет на себя СУБД. И кстати, в большинстве случаев прекрасно справляется. Не хорошо программисту думать об оптимизациях. Надежность на первом месте. Скорость разработки.

          Проблемы производительности связаны с текущим железом. В частности, очень сильно с разделением на ОЗУ и файловую системы. Работа с файлами пока не очень быстрая. Это вообще узкое место во всём. И это узкое место в любом случае уберут. Сделают возможно специальные машины для реляционных — и тогда все эти вопросы оптимальности NoSql перестанут быть аргументом.
          • +5
            Я уже ответил на этот вопрос выше. Отвечу чуть более развёрнуто. Только предупреждаю: это мой личный опыт, основанный на тех десятках проектов, которые я лично (в составе команды) реализовал. Пишу не ради холивара, а для обмена мнениями и опытом.

            Допустим, в приложении есть много данных. Мы решили их инкапсулировать в СУБД и ограничить доступ к ним из клиентского кода. Сделали кучу хранимок по базовым операциям, CRUD, поиск, отчёты, ещё что-нибудь. Окей, молодцы. Что мы имеем в сухом остатке?
            Сложную логику SQL'ем (декларативно) не описать — нужны циклы, условия. динамические запросы и т.д. Выходит, необходим поверх языка запросов ещё и язык программирования. Лично мне кажется, C#/Java с этим справятся лучше. Это то, ради чего их создали и свою задачу эти языки выполнят лучше — там есть и коллекции, и мощные библиотеки базовых типов, операций. (Да, большие объёмы данных лучше перемалывать максимально близко к этим самим данным. Давайте писать на Java/C# прямо внутри хранимок. И отсылать электронные письма. Работать с ХМЛ, вебсервисами, файловой системой. Всё это — функционал современных СУБД. NoSQL появились как раз по этой причине — в 80% софта всё это не нужно. Но даёт некислый оверхед, потому что поддержка — есть. В NoSQL это всё повыкидывали и часть оставшихся задач осознанно перекинули на плечи разработчиков клиентского кода. Получилось быстро, но — сложно, да. Нужен адекватный мозг).

            Что ещё? Хранимые процедуры — это некий срез модели данных, лежащей внутри БД. Что-то трансформировали, что-то — слили воедино для простоты. Кто гарантирует, что клиентский код удобно ляжет на этот срез и не захочет в каких-то случаях получать данные в другом срезе? Доступ к некоторой сущности, которую для простоты объединили с другой или вообще спрятали. Или сгруппированные данные по другому полю? Список сущностей, но немного не так отфильтрованный? Результат — ещё больше хранимых процедур. Одна работает так, другая выдаёт те же данные, но с другой сортировкой, в третью мы добавили параметр «отсылать ли уведомление по завершению», четвёртая возвращает статус обработки запроса и т.д. При этом, первоначально, табличка всего-лишь одна. Или две. (Утрирую). Но срезов, необходимых приложению — больше. И на каждый из них необходимо родить процедуру, потому что процедура = ограничение. В итоге, чтобы сделать простую вещь, мы вызываем 5 процедур подряд, затем первые три ещё раз, но уже с результатом из последних двух. И т.д.

            Зачем тратить на это всё своё время, если мы не пишем распределённого (в т.ч. географически) монстра? Спроектировать систему в целом, нежели разбить её на два независимых (!) модуля через узкую прослойку-интерфейс — проще (речь не о декомпозиции задач на более мелкие). Лично мне идея защищать (инкапсулировать) свой код от коллег кажется неоправданной. В огромных проектах, возможно, это уже обретает смысл. Но не в 80% остальных.
            • +8
              Наш программистский народ почему-то плохо учится.

              Всё, что вы описали, это просто опыт, но опыт, который звучит примерно так:
              «Я обходился всегда без этого и поэтому я думаю, что это не нужно.»
              Это замкнутый круг. Например, многие программисты утверждают, что им не нужна математика совершенно. Потому что им в работе это не нужно. Тоже замкнутый круг. Им эту работу никто и не даст никогда. Будут гуи интерфейс простой клепать до конца дней.

              Теперь применительно к ответу выше.
              Сложную логику SQL'ем (декларативно) не описать — нужны циклы, условия

              Да почти всё можно описать. Есть небольшие места, где не всё. Например:
              динамические запросы

              Но такие запросы в большинстве случаев означают непонимание реляционной модели и плохую (иногда крайне плохую) архитектуру.

              Чтобы было понятнее, приведу пример с шарпом. Оказывается, там то же самое. Представьте, что вы в коде вдруг не смогли выразить предметную область средствами самого языка и прибегаете к механизму отражения. И пишете код, вроде такого:
              «если объект имеет тип такой-то, то сделаем вот это».
              Хреново, правда? Вот что-то похожее с динамическим SQL. Значит неудача постигла в понимании как надо выразить задачу запросом. Как надо смоделировать таблицы. Например, забыли, что таблица является сущностью, а решили, что это контейнер просто. Далее, напихали одну и ту же по сути сущность в две таблицы. Конечно, теперь джойн не очень получится, лучше делать динамический запрос, чтобы в каждом случае подставлять желаемую таблицу. А то SQL сам по себе плохо выбирает в чистом и понятном для него коде.

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

              Т.е. понятно, думаю, что такое язык поверх языка. Аналогично, вы не хотите работать с SQL.

              При этом язык SQL во много раз мощнее, чем С#. Конечно, я рассматриваю просто императивную часть, без linq и лямбд, т.е. изначальную основу шарпа. На линькью, кстати, тоже не стоит городить огород там где может работать SQL. Т.к. линькью заточен на работу со списками. А значит, более широкого применения. И это же значит, что более опасный, более многословный. Захотите бОльшей жесткости, чтобы получить реляционные отношения, вам придется всё это ручками делать. Вопрос большой — зачем? Повторюсь, ручками сделать можно всё что угодно. Готовы спорить, что умнее команды Оракла или SQL-Server?

              Циклы и ветвления, которые якобы нужны — это пусть к сложным багам и тяжелой поддержки. Это императивный код со всеми вытекающими, вроде — вероятность бесконечной рекурсии и переполнения стека. Или просто не выхода из цикла. Не говоря уже о том, что вы пишете по шагам, что нужно делать а не «как».

              Что-то трансформировали, что-то — слили воедино для простоты. Кто гарантирует, что клиентский код удобно ляжет на этот срез и не захочет в каких-то случаях получать данные в другом срезе? Доступ к некоторой сущности, которую для простоты объединили с другой или вообще спрятали. Или сгруппированные данные по другому полю? Список сущностей, но немного не так отфильтрованный? Результат — ещё больше хранимых процедур

              Никто не гарантирует, что не захотят в другом срезе. И да, результат — процедур больше. Но хочу вас разочаровать, на шарпе даже хуже. Там тоже код не телепатически узнает что делать надо. Если вы не захотите писать процедуры, то придется писать на шарпе. Неужели это так сладко писать на шарпе?

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

              Да, SQL не идеален — нет инкапсуляции, не очень с тьюринг-полнотой. Но плюсы все таки есть и огромные. Оверхед волнует? Мне лично его в рюкзаке не носить. Написать быстро приложение и не думать о производительности (это на счет монстра) — это как раз реляционные СУБД.

              А желание перейти на NoSQL звучит где-то так: давайте писать всё с нуля. NoSQL базы — это по сути очень обрезанные по функционалу базы в сравнению с реляционными. И всё, что я про них хорошего слышал, это то, что на них работают такие большие монстры, вроде твиттера, выдерживая нагрузку. Повторюсь, такие базы и покупать не нужно, их можно сделать, умея работать с файлами, за день (с самым простым функционалом). А такие «монстры», вроде твиттера или фейсбука имеют потребности в моделировании предметной области совершенно примитивные, которые наверное проще, чем бухгалтерские приложения для обслуживания ларька.

              Поэтому я бы не кидался в NoSQL. А и еще думаю, что оптимизация почти всегда предварительна. И пока мы тут спорим, в районе 5 лет железо кардинально изменит взгляды на то, как можно строить СУБД и на оптимальность.
              • +4
                Начну с конца: да никто и не кидается в NoSQL. В нашем треде идёт холивар на тему «логика в БД» vs «БД — лишь хранилище данных» :)

                Нет, всё же вы не угадали. Я побывал и в проектах, где ни один чих не обходился без ХП, и в проектах, где кроме NHibernate не было ни строчки SQL-кода. Да, плохо было везде :-) Но в итоге мне показался эффективнее второй вариант. (Как раз дело в том, что в детстве я не верил в нужность математики, окончил математический факультет и в итоге укрепился в своих первоначальных суждениях, но уже без фанатического экстремизма, сместившись чуть ближе к балансу.)

                Про динамические запросы я понимаю вашу мысль. Да, это так. Про циклы и ветвления тоже согласен. Именно это я и хотел сказать — если в ХП всё это есть, значит «Хьюстон, у нас проблема». Но, чёрт возьми, рассчёт перерасхода сотрудника в заданном периоде согласно его лимиту и настройкам бухгалтерии, переход документа дальше по цепочке авторизации — всё это не реализовать на голом SQL, простыми запросами. А если подобную логику тащить на уровень клиентского кода, то будет нужен доступ к недрам модели данных, её особенностям реализации. Идея инкапсуляции логики модели, ограничение прав доступа пользователя только на выполнение ХП — всё это терпит крах. Иначе придётся программировать слишком много процедур, почти полностью повторяя исходную структуру таблиц. Так зачем же тратить на это время (при проектировании, кодировании и поддержке)? Почему люди стараются упрятать максимум в ХП, скрыть все детали от прикладных программистов? Когда есть доступ к полноценной, целостной модели — как и у кода, так и у ХП, разработка же становится на порядок проще!

                По поводу сложности реализации описанных мною срезов на шарпе — вы меня не совсем поняли. В этом треде витает спор между «ВСЯ логика в ХП» vs «ничего в ХП». Лично я — за золотую середину, смещённую в сторону шарпа :) Не нужно писать на нём сложные запросы, если в SQL их сделать проще. И не нужно оборачивать в ХП запросы вида select id, name from blah order by id и select id, name from blah order by name. Их будет всё же большинство. Не думаю, что вы с этим будете спорить. И как раз отсюда и пошла, на мой взгляд, идея NoSQL — если в 80% случаев нам не нужна вся мощь SQL, зачем тратить процессорное время на лог транзакций, ACID и внешние ключи? Зачем ограничивать зазря прикладных программистов? Вот банковские системы и иже с ним пускай как писали на J2EE + Oracle, так и продолжают. Но сейчас наконец-то появилась альтернатива. И кому-то хватит даже key-value… Но в том, что их можно реализовать самому за день — вы не правы. Вон Ayende уже сколько пилит свою RavenDB :)
                • +1
                  Именно это я и хотел сказать — если в ХП всё это есть, значит «Хьюстон, у нас проблема».

                  Нельзя не согласиться. Если такое г начали использовать в хранимках, то лучше это в шарп вынести.

                  Но, чёрт возьми, рассчёт перерасхода сотрудника в заданном периоде согласно его лимиту и настройкам бухгалтерии, переход документа дальше по цепочке авторизации — всё это не реализовать на голом SQL, простыми запросами.

                  Вопрос только в знании SQL (и набить руку). Я не увидел в таком примере ничего пугающего. Скорее всего реализуется без единого цикла или ветвления. Набором запросов. Конечно, нужно, чтобы адекватно были созданы таблицы.

                  Иначе придётся программировать слишком много процедур, почти полностью повторяя исходную структуру таблиц

                  Иначе в шарпе придется повторять всю исходную структуру таблиц. Разница только в объеме кода и где лучше, быстрее исправлять.

                  Почему люди стараются упрятать максимум в ХП, скрыть все детали от прикладных программистов? Когда есть доступ к полноценной, целостной модели — как и у кода, так и у ХП, разработка же становится на порядок проще!

                  Мне не нравится, что многие почему-то считают, что есть некие прикладные программисты, а есть базовики. И базовики пишут SQL-код. Я не люблю базовиков как класс. Они, те кто не были программистами, редко и хранимки пишут так как надо. Думаю, что программист, пишущий код приложения, должен одинаково хорошо и SQL владеть и писать код в любом месте, ограничиваясь задачей, а не компонентом. Тогда проблем не будет. Вы, как программист, имеете доступ ко всему коду.

                  Скрывать любые части кода от разработчика вообще по-моему плохая практика. Это антипаттерн управления «Разведение грибов».

                  В этом треде витает спор между «ВСЯ логика в ХП» vs «ничего в ХП». Лично я — за золотую середину, смещённую в сторону шарпа :)

                  Я вынуждено тоже имею такую т.з., только шарп у меня не выигрывает. Конечно, какие-то вещи тяжело сделать в БД. Но тут стоит задуматься о правильности архитектуры или даже о качестве задачи (возможно задачу можно решить гораздо более простыми средствами). Одна из задач, тяжело поддающихся реляционным БД — это динамическое количество атрибутов у сущности. Но в принципе, это если бы на шарпе мне захотелось написать класс, который имеет динамическое количество свойств (настоящих). Пришлось бы шаманствами с отражением заниматься. Это плохо. Но плохо еще то, что шарп намного более гибкий и носом сам по себе не ткнет, что есть проблемы в задаче. Вы себе сделаете Dictionary, не будете пользоваться свойствами, и вам покажется, что классная и красивая архитектура.

                  SQL — прекрасный язык. Расширенные языки для написания хранимок — очень плохие языки. И вынуждено приходится идти на то, что если появляются в хранимках циклы, ветвления — это в шарп. Но часто это из-за низкой квалификации в базах данных появляется.

                  А если рассуждать вообще, в отрыве от конкретных БД (к сожалению работаем только на конкретных), то я уверен, что данные и их обработка должны быть как можно ближе. Не должно быть понятия отдельно — это хранилище, а тут мы прикрутим шарп и будем работать. Это чревато написанием второй БД на шарпе. Начинаются пляски с кешированием (т.е. дублированием данных, что очень не гуд), потом, эти данные уже в памяти и программист создает свою бд, с транзакциями, с оптимизациями. Конечно, эти попытки выглядят очень убого, а безопасность и целостность данных на порядок всегда ниже. Но программист, видимо, горд таким умением. С другой стороны, да, это говорит, что СУБД в большинстве своем для бизнес-приложений тащат большой оверхед. Раз сплошь и рядом делают свои поделки, херят безопасность и при этом считается почти стандартом разработки бизнес-приложений.

                  И кому-то хватит даже key-value… Но в том, что их можно реализовать самому за день — вы не правы. Вон Ayende уже сколько пилит свою RavenDB :)

                  Иногда и за час. Всё зависит от задач. БД — понятие гораздо более широкое. Не стоит подразумевать под этим нечто монументальное. (Я имею опыт разработки разных нереляционных БД, на разных языках, не шарп).
                  Key-Value на каком-то другом языке и отдельном сервере (процессе), придется делать. Если же вы на шарпе пишете, то тут вообще и писать почти ничего не надо. Дублирование данных — это зло. Значит и другого процесса не надо. Будете писать библиотеку. Заводите инкрементальный идентификатор для всех любого типа объектов. И даже хеш вычислять не нужно будет. И или скрываете в коде (лучше сгенерированном) классов-сущностей вызовы по связям через поиск по этим идентификаторам, либо пишете простой менеджер, который этим управляет. Можете сделать файл с индексами и файл для хранения (сбрасывания сериализированных объектов). Можете чуть сложнее — много файлов и разбиение на таблицы через хеш. Плюс, учитываете, если хотите, какую-то безопасность, на случай аппаратного сбоя. Но это не обязательно, учитывая уровень безопасности обычных наших руками сделаных кэшей.
                  Всё это довольно просто. Всегда удивляло, почему люди используют SQL-Server или Оракл, когда верят, что это просто мешок для поднятия и прятания объектов. На стыковку с ними больше усилий тратят.

                  • 0
                    Иначе в шарпе придется повторять всю исходную структуру таблиц. Разница только в объеме кода и где лучше, быстрее исправлять.


                    А она там итак будет, практически в неизменном виде.

                    Извиняюсь, что не отвечаю так же развёрнуто на ваш объёмный комментарий. Просто вижу, что мы не спорим, а излагаем одну и ту же мысль, но разными словами. Для каждой задачи — свой инструмент. Фанатики, пихающие совершенно всю логику в ХП — не правы. Я их за свою карьеру видел достаточно много, чтобы начать эмоционально реагировать на любое упомянание ХР. При этом, на шарпе всю логику тоже эффективно не опишешь (как минимум поиск, фильтры, отчёты). Должен быть разумный симбиоз. При таком раскладе, в большинстве случаев, полноценная навороченная СУБД уже становится не нужна и хватает какого-нибудь легковесного NoSQL. С чем вы, похоже, тоже не спорите.

                    А если данных ну очень много и мы готовы смириться с eventual consitency, их использование становится ещё более оправданно, в разрезе скорости работы (не разработки). ИМХО
                    • 0
                      Не совсем. Я бы использовал реляционные СУБД. И по максимуму бы использовал хранимки (в меру, не превращая в кашу).
                      Вообще, очень неплохо было бы, чтобы придумали нечто поинтереснее, чем императивные и такие «топорные» процедуры. В принципе это получается.

                      А что не получается, то получается «доработать напильником». Некоторые рекурсивные задачи или парсеры или динамические объекты — дописываются, хранятся в таблицах и вполне можно писать и хранимки на шарпе.

                      Если бы был такой хороший язык, позволяющий легко оперировать кодом, инкапсулировать его, делать свои объекты для кода, давать им имена, да и лучшей строгости в типизации хочется — я вполне за, чтобы этим занимался один сервер. Не нужен сервер СУБД, и отдельно АПП.

                      А пока, приходится разделять. Но для меня такая условная черта. Если можно и код не легаси, а я пишу, то СУБД — по сути содержит нормализованные сущности с хорошей моделью предметной области, хорошо обернутые в хранимки и доступ через них, а в АПП слой модели либо отражает базу, либо более высокого уровня, либо имеет объекты, близкие к обработке ГУИ.

                      Но и не спорю, что у нереляционных СУБД есть свои области применения. Сейчас сам одну делаю. Но там реально, совершенно другие требования и другая задача. Там не моделирование предметной области, а вычислительная конкретная задача.

                      Я писал о том, что многим хватит легковесного NoSQL. Но не потому, что оно легковеснее. Как раз почти всегда вижу с этим только бОльшие проблемы для кодирования. Но если человек по факту не использует SQL, то конечно, ему хватит NoSQL. Это самозамкнутое измерение — хватит или не хватит. Человек сам определяет свой темп работы, регулирует поток задач, а потом говорит, что ему быстрее не надо — он с потоком вполне справляется.

                      Мне не нравится тоже что код в двух местах. И тут уже кому как нравится на какой стороне кодировать.
                      • +1
                        жесть, такой вроде бы опытный ( DBшник я так полагаю?), а так уверенно учите плохому — класть бизнес логику в хранимки. У нас по этой причине целый проект двухлетний на заказ поступил на переработку с пометкой «только ни каких больше хранимок», потому что его поддерживать уже стало невозможно. Перечитайте Фаулера что ли, про предметную область и её роль и про роль слоя баз данных. БД отвечать должна только и исключительно ЗА ХРАНЕНИЕ, запись и чтение данных. Но ни как не за логику использования, условия получения данных и т.д. Это не её.
                        Вы где-то наверху написали «Я обходился всегда без этого и поэтому я думаю, что это не нужно» только это скорее про логику в БД: «Я ни когда не сталкивался с удобством правильной предметной области, поэтому буду хранить все в SQL»
                        • 0
                          Я Фаулера, конечно, читал. И с этим его взглядом не согласен. И этот взгляд, кстати, не является единственным. Читайте Best Practices майкрософт. Там говорится, что только в маленьких проектах можно давать доступ напрямую коду к таблицам. Т.е. формировать запросы.

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

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

                          Нет, я не базовик. Разрабатываю всё, от гуи, до хранимок. И мой взгляд на эти вещи выработался со временем и опытом. Мне не составит большого труда создавать предметную область и на шарпе. Но вижу в этом бОльшие проблемы и больше потенциальных мест для ошибок.
                          • +1
                            Ох я прошу прощения, но имхо Майкрософт — это последние, кому стоит доверять в плане архитектуры ПО.
                          • 0
                            Я думаю комментатор выше хотел сказать, что это выглядит действительно странно — класть в хранимки логику, если ровно тот же SQL-запрос можно послать на БД из самого приложения. Только при этом, будет меньше ограничений для разработчика. В чём здесь профит от хранимок то? Я реально из ваших объяснений не вижу.
                            Вроде бы верно излагаете: не стоит впадать в крайности, нужно выбирать правильный инструмент, но в конце концов всё-равно «И по максимуму бы использовал хранимки».
                            Зачем то, что можно вызвать из кода приложения — загонять внутрь хранимки и давать наружу только сигнатуру? Кроме ограничений, мы (авторы комментов) здесь больше ничего не видим.
                            • 0
                              Я думаю комментатор выше хотел сказать, что это выглядит действительно странно — класть в хранимки логику, если ровно тот же SQL-запрос можно послать на БД из самого приложения. Только при этом, будет меньше ограничений для разработчика.

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

                              Другое дело, когда у вас и не будет записанного кода, а будет формироваться. Опасность уже выше. И большая связь с кодом на ЯОП.

                              Методологически я считаю, что СУБД должна использоваться как сервер, полностью. Не нужна в принципе прослойка еще какого-то сервера. Потому что по сути вы создаете второй сервер и дублируете данные и строите тупой упрощенный, опасный второй сервер.

                              Но так как мы живем не в идеальном мире, то надо сказать, что Transact-SQL (я его использую для хранимок), имеет много минусов. SQL — хорош. Транзакт — это жуткая вещь. Если вы умеете готовить хранимки по минимуму используя IF, WHILE, то всё отлично. Если же код превращается в императивщину (возможно из-за вас или плохой архитектуре БД), то есть смысл такие части писать на ЯОП. Поэтому, я бы по максимуму использовал бы хранимки. В редких местах, можно использовать шарп. Это практический совет, как провести черту.

                              Очень надеюсь, что придумают что-то более адекватное, чем транзакт, и тогда вопросы снимут на чем писать
                            • 0
                              Только при этом, будет меньше ограничений для разработчика.


                              Не отгораживайтесь от БД ;)
                              Запросы тоже пишет разработчик. Вам запрещают работать с хранимками? Хранимки — это код. И не надо думать, что их должны писать кто-то избранный, какой-то базовик.
                              • 0
                                Я не отгораживаюсь, вроде. Просто реально пытаюсь понять их смысл. Если нужно перелопатить тучу данных, в несколько этапов — да, смысл в хранимках вижу: не нужно по сети гонять кучу данных туда-сюда, а сразу всё происходит в одном месте. В других случаях же вообще не могу понять их смысла. Я уже спрашивал: назовите хотя бы парочку плюсов такого подхода? Кроме мифической инкапсуляции внутренней структуры, которая мало того что мифическая, так ещё и есть зло.
                                • 0
                                  1. Вы не строите дополнительную СУБД. Это уже всё объясняет.

                                  Этого уже достаточно. Давайте сделаем шаг назад и представим себе, что база данных не реляционная. И внутри использует ваш любимый язык. Допустим, шарп или джаву. Т.е. там вы внутри могли бы работать с объектами, как хотели бы. И они сразу же при фиксации транзакции были бы сохраненными, вам даже знать не надо, куда. Здесь же, это всё сервер БД.

                                  Вы бы в этом случае делали бы еще какой-то другой сервер, через который общались с такой СУБД? Т.е. решили, что этот сервер плохой, давайте ка сделаем свою поделку. Очевидно, что решение плохое?

                                  Точно та же логика касается и обычных реляционных СУБД. Они разрабатываются для обработки данных. Они могут обслуживать одновременно много запросов. Они могут поддерживать много коннекшинов. Но вы почему-то думаете, что это всего лишь мешок для прятания и доставания объектов и упорно пытаетесь делать свои поделки, т.е. свою прослойку, ведущую себя как СУБД, только тупую, опасную и с нуля. При этом в вашу СУБД данные загружаются из реляционной СУБД. А значит находятся в двух местах сразу. А значит появляются еще и дополнительные расходы на синхронизацию. Дополнительные потенциальные баги. Вы вообще делаете кучу всего лишнего. Это как бы если бы задача у вас стояла «купить хлеб», а вы строите завод для изготовления бетона, строите дорогу к предполагаемому магазину, строите магазин, завозите хлеб, а потом только у вас всё готово, чтобы купить хлеб.

                                  Хлеб можно покупать сразу. Таблицами можно моделировать вполне жестко и успешно предметную область. Да, это не ООП. Но ряд плюсов даже получше, чем в ООП есть.
                                  • 0
                                    Я понял. Вы говорите про data-centric приложения. О них ещё в середине 2000х Майкрософт везде писал.

                                    Сейчас, в большинстве случаев, БД — мешок для прятания объектов и не более того. От СУБД не требуется много параллельных соединений и запросов. И реляционная модель с её нормализациями и прочими прелестями — только мешает. А те минусы, о которых вы пишете — здесь не актуальны. Все подобные проблемы решены, всё-таки.

                                    Ваши изречения имеют право на существования, но просто в другом контексте, где применение NoSQL даже и не всплывает.
            • 0
              Как известно, развитие движется по спирали.
              Ситуации, когда бизнес логика уходит в базу данных и это вызывает кучу трудностей — действительно неприятны. Парадигма «давайте сделаем вообще всё на SQL» ничем не лучше парадигмы «дайте мне key-value storage, а всё остальное я сделаю сам».
              Но тут на сцену выходит архитектура REST, которая отлично ложится на реляционную алгебру.
              Вам нужно перекинуть N едениц ресурса Х от объекта 1 к объекту 2? Сделайте POST для объекта типа «переброска ресурса».
              На уровне классических БД это реализуется легко и просто, на любом другом это нескончаемый поток геморроя по обеспечнию ACID…
          • 0
            Проблема в том что не перестанут.
            Да через пять лет железо справится и нормальный объем ОЗУ Low-Cost сервера будет исчисляться терабайтами. И ядра сотнями. Беда в том что необходимые объемы данных будут исчисляться петабайтами. И их придется хранить на петабайтных винтах, которые по прежнему будут медленнее.

            И это я еще оптимист. Несколько лет назад объем дискового хранилища в 1 тер достигался парой десятков винтов, и мы имели 20 шпинделей на этот объем.
            Теперь 146ГБ SAS 15k это уже «старье» и в тренде 300 а то и 600 винты. И теперь мы имеем пяток винтов на этот тер и производительность дисковой системы снизилась в 4 раза на произвольный доступ.

            Классические БД монолитны. В случае ахтунга ничего не теряется, но обламываются все и пока не накатится бекап мы стоим. Чем больше данных тем дольше восстановление. Тем больше клиентов простаивают.

            NoSQL как правило shared-nothing и бекап надо катить не на всю базу, а только на отдельный кусок. Остальные не затрагиваются.

            Ну и соглашусь с другими ораторами: современные СУБД это монстры. Мне не нужна вся мощь PL/SQL. Но нужен JOIN между двумя террабайтными таблицами фактов. Редко, разово, но этот раз требуется директору.

            Я готов потерять часть данных старше пары суток, но чтобы не случилось я должен иметь возможность сохранять поступающие данные. Ну вообщем у нас CAP в действии. :)

            И мне нужен MPP. И вынужден покупать топовые Oracle/MSSQL хотя остальные 90% их возможностей мне просто не нужны, а некоторые типа MVCC и просто иногда вредны.
            • 0
              Я на самом деле не противник NoSQL баз. Но только для очень ограниченных случаев. Сам ровно сейчас создаю свою с нуля СУБД. Но там четкая и строгая задача, задача датамайнинга. С такими алгоритмами, что нужно заточить субд полностью.

              Но вообще их делать и не пользоваться реляционными в общем случае — совсем не гуд. Создавая такие мелкие свои СУБД я уже давно осознал, какое это благо пользоваться готовыми. Для моделирования, для бизнес-задач, пока ничего лучше не придумали. Брать NoSQL-льные базы для таких задач — ну прямо зло. Это огрызки реляционных баз данных по функционалу.
              Вы так боитесь за оптимальность работы вашего приложения? Любая оптимизация (абсолютно) до написания кода является преждевременной. Думать об оптимальности до получения продукта — самое большее зло, которое можно придумать.
              Реляционные БД во-первых очень оптимальные, над ними работают много людей. Неглупых. Во-вторых они строгие. Декларативно можно большую половину работы с данными описать. А что важнее правильности работы программы и надежности? Оптимальность, повторю, на двадцать пятом месте. Неприятно, что программисты почему-то считают оптимальность своих программ большим достоинством. Это что-то психологическое.

              Плюсуем к плюсам еще скорость разработки — и видим большой профит.

              О будущем.
              1. Алгоритмы работы с данными — это в первую очередь связано с архитектурой машины. Оптимизация алгоритмов на данный момент происходит в несколько шагов и главная особенность, связанна с машиной — это маленькая и дорогая ОЗУ (энергозависимая) и большой медленный винт. То, что происходит в памяти, происходит значительно быстрее. Поэтому одна из задач оптимизации — загрузить по полной процессор и почти по полной память, но не выйти в своп. Из этого алгоритмы усложняются. Большие объемы данных начинают бить на куски и т.д.
              Все знают об этом узком месте. И работы ведутся. Насколько я знаю, уже есть способы хранить энергонезависимо данные со скоростью обращения к ним заметно превышающую скорость обращения к текущей ОЗУ. Ведутся исследования и испытания по доработке, чтобы это попало в производство. Думаю, в районе 5-10 лет такое произойдет.
              А как только это произойдет, сам подход к алгоритмам и их оптимизациям изменится.
              2. Очевидно, что алгоритмы также связаны с моделью работы с памятью. Базы данных — это одно из важнейших направлений в разработке. И я не удивлюсь, если в скором времени придумают железные решения для реляционных СУБД. Т.к. они себя хорошо зарекомендовали в течении многих лет.

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

              Но взять и отказаться в пользу NoSQL-льных огрызков… Почему это огрызки. Реляционная СУБД позволяем матипулировать данными в разных направлениях, как захотите. Поддерживает фильр, сортировку, группировку по любым колонкам и джойны.

              Древовидная база будет сильно оптимально заточена под джойны, с учетом если угадали, как эти джойны будут происходить. Как только нужно будет делать непредусмотренные джойны — приехали. То же с группировкой.

              А программисты, хвалящие NoSQL базы, может быть думают, что будут только гуглы и фейсбуки создавать? Размечтались. )))

              Да, объем данных будет расти. Но и железо будет расти. Возможно, реляционные СУБД как раз станут не медленнее всяких NoSQL. Во вторых, на очень больших объемах данных, обычно, операционная деятельность не ведется. Большие объемы нужны для аналитики. Там и БД другие. Нереляционные. Олапы и всякое другое.
      • 0
        «Подумать, а потом сделать» — это универсальная формула. Если сначала думать, то всё получается хорошо и в SQL, и в NoSQL. А вот если не думать, то в SQL можно легко написать неэффективный запрос. А на NoSQL, когда вся «схема выполнения запроса» реализуется в самом приложении, более наглядно видно, что будет работать быстро, а что медленно. С оговорками, конечно, но есть и такое наблюдение.
      • +5
        Если использовать хранимые процедуры, то вычислительная нагрузка на сервер с БД неизбежно увеличится и как результат — она начнет быстрее захлёбываться. Если же запросы формировать в приложении, то его можно легко распараллелить на два и более серверов, что с базой сделать сложнее, особенно когда она уже находится в эксплуатации.
        А так же, справедливости ради, стоит заметить, что к примеру в той же Монго хранимые процедуры также поддерживаются, если очень уж надо.
        В общем, считаю данное утверждение как минимум спорным.
        Вообще идеализировать какое-то отдельное решение не совсем корректно на мой взгляд. По части возможностей NoSQL базы уже не так далеки от своих SQL собратьев. и так просто сравнить их по каким-то точечным характеристикам не так просто. Нужно смотреть на конкретную задачу. В этом смысле в своём коллективе мы предпочитаем классифицировать БД несколько иначе: реляционные, структурные (где хранится json или xml), key-value и raw-stored (один или несколько бинарных файлов, доступ к данным по оффсетам. Довольно удобно для некоторых задач и очень быстро)
        • 0
          Кто-то же запускает эти процедуры. Репликацию никто не отменял, потому они могут запускать на разных серверах одни и те же процедуры.
        • 0
          Хранимые процедуры задуманы не для дополнительной нагрузки на БД. Напротив, если правильно их использовать, то нагрузку можно снизить.
          Например, можно написать процедуру, в которой разбить сложный запрос на несколько простых и выдать готовый результат. Выполнение будет несколько выше, нежели выполнять у себя в коде несколько отдельных запросов или лепить какой-нибудь сложный запрос с вложенностью и/или хитрыми сортировками и группировками. (мне очень помогло решение с процедурой, когда требовалось очень часто выполнять сложный запрос. Разница во времени была ощутима)
          Кроме этого, в некоторых случаях выносить часть логики в БД куда целесообразнее, нежели писать ее в коде.
          • 0
            Да, вы правы. В ряде случаев это отличное решение. Нельзя вообще сказать, что некое решение однозначно плохое или хорошее. Фичи в БД вообще появляются не от капризов «а давайте сделаем вона как!» — это, прежде всего, чья-то насущная необходимость и над ней работало множество умнейших людей. Любая фича проходит множество этапов тестирования и оптимизаций. Это справедливо как для SQL так и для NoSQL. Где-то нужен один набор функциональности, где-то другой. База данных — это не просто хранилище данных. Хранилище данных — это несколько файлов в файловой системе. Вопрос заключается именно в том, как в какой ситуации с этими файлами эффективнее работать? С помощью какого языка эффективнее оперировать с тем набором данных, который представлен? Какая логика лежит в основе? И т.д.
            Другими словами, выбор базы данных и используемых в ней средств должно быть мотивировано требованиями. То же самое относится к языкам программирования, операционной системе, железу и т.д.
            Лично для меня не существует абстрактного вопроса использовать хранимые процедуры или нет. Использовать можно только где, как и почему. Ровно тоже самое относится и к вопросу SQL против NoSQL. Для меня это вопросы настолько же странные, как вопрос что лучше: шрифты с засечками и без. Говорят, что без засечек теперь популярнее. Что тут можно сказать?
            В большинстве проектов, с которыми мне приходилось сталкиваться походу работы, я не встретил ни одного единообразного решения. Были плохие архитектуры, были лучше, были и классические и несколько более неожиданные. Но все они лучше или хуже были адаптированы под конкретную ситуацию. И кстати, если говорить о таких вещах как производительность, надёжность или масштабируемость — то эти вопросы на самом деле являются, как правило, решаемы на любой стадии развития проекта. Вопрос только в цене на железо и иногда на лицензии. И конечно в наличии специалиста (группы), который готов это реализовать. Гуру хранимок сделает всё что угодно на хранимках и это будет хорошо. Другой гуру обойдётся без них, третий сделает то же самое на NoSQL и все эти решения в принципе идентичны. В основном, выбор зависит только от наличия специалиста и какого-то уже имеющегося legasy. Если нет ни того ни другого, то тогда в основном и начинается брожение, так как нет понимания. В этом смысле, на мой взгляд, шумиха вокруг SQL vs NoSQL — война не технологий, а специалистов по этим технологиям.
      • 0
        Я вот даже не уверен, что NoSQL лучше для быстрого прототипирования.

        Реляционная нормализованная база позволяет на лету добавлять новые непредвиденные запросы, что очень хорошо на этапе прототипирования.
      • 0
        Когда все радетели мат апарата ни сном ни духом о CAP-теореме, конечно NoSQL ненадёжно.
        Нам что, Сбербанк может 1,5 дня поднимать базу из бэкапа и это надёжно у них мейнфреймы и супернадёжная DB2.
        Разработчики NoSQL конечно безответсвенные сволочи и воротят с данными что хотят, а админы SQL баз данных все отвественные люди, всё проводят по процедурам, ничего не хачат на живой системе втихаря(как один большой спец по мэйнфреймам здесь на хабре) и укладываются всегда в отведённое окно(вот у Амазона минута простоя ещё в 2007-мом стоила 15000$, интересно у Сбербанка сколько).

        Когда клиенты вам начнут выставлять счета с шестью нулями нерусских тугриков изза неисполения SLA по части Availability, тогда кому-то наверху дойдёт, что держать людей которые кроме своего уютного SQL ничего не видят нет смысла.
        С SQL и NoSQL главное правило know your data. Так же как DBD должен оптимизировать запросы после достижения некоторых объёмов данных в выборке, так и разработчик NoSQL должен менять структуру данных и выборки после изменения требований к системе или объёмов данных на порядок.

    • +1
      Очень хорошее замечание, ведь действительно, слишком как-то однобоко получилось.

      В дополнение хотелось бы, чтобы автор хотя бы кратко коснулся текущего тренда по уходу от NoSQL к NewSQL в новейших приложениях. Собственно, NewSQL сейчас и выкатывается на сцену потому, что у NoSQL есть определенные ограничения/проблемы.
      • 0
        Ну, я не ставил целью рассмотреть плюсы и минусы NoSQL. Главная цель была — сгруппировать все характеристики и помочь новичкам создать себе представление о том, что такое NoSQL. По сравнению с стройными реляционными базами данных это — лес дремучий, даже для знающих людей. Слишком все стихийно и быстро развивается.
        Я, кстати, не фанат NoSQL, мне больше по душе (да и опыта больше) дата гриды. Плюс распределенные базы данных еще не сказали свое слово, особенно в контексте последних успехов Гугла с F1 и Спаннером. Возможно, NoSQL базы стали предшественниками распределенных систем с консистентными операциями и мощью SQL в распределенных масштабах.
        Плюс есть очень любопытные наработки в попытке скрестить распределенные хранилища с реляционными базами данных (HadoopDB).

        Статью почитаю на досуге, спасибо.
  • +1
    Нельзя джойнить.
    • 0
      В реляционных базах тоже нельзя джойнить между шардами.
      • +5
        Ну почему же…

        SELECT 
           customer.customer_name, 
           order.order_date, 
           orderline.quantity_ordered
        FROM 
           customer@london, 
           order, 
           orderline@paris
        WHERE
         customer.cust_number = order.customer_number
         AND
         order.order_number = orderline.order_number;
        


        Это оракл. MS SQL, на сколько я знаю, тоже не запрещает джойны с удалёнными базами.
        • 0
          А консистентность и изоляция сохраняется? Если да, то наверняка это очень медленно, если нет — тоже самое можно сделать в NoSQL вручную.
          • 0
            вот кусок доки по этому поводу: docs.oracle.com/cd/E14072_01/server.112/e10595/ds_txnman010.htm
            • +1
              Выходит консистентность сохраняется, но теряется availability. Ну правильно, это прямое следствие CAP-теоремы — если добавить распределенность, надо убрать или availability или consistency.
              • +2
                консистентность согласованность
                availability доступность
                Fixed.
  • +1
    Интересно. Жду вторую статью.
  • 0
    ATMs (честно, не знаю что это такое)

    Это банкоматы
    • 0
      Спасибо, поправил
  • –1
    Пункт 5 тут излишен.
    Первое: мощный сервер с объемом ОЗУ, в который полностью влезает вся база + вынесенное файловое хранилище на серверных SSD дают фантастическую производительность для всех современных СУБД, будьто SQL или NoSQL.
    Второе: в большинстве приложений 95% запросов это чтение, поэтому мастер-слейв репликация, которая есть у всех баз, дает очень хороший буст производительности.
    Ну и третье — шардинг на уровне приложения: если юзеры слабо связаны друг с другом, их можно разбрасывать каждого на свой сервер при логине.
    Действительно распределенная СУБД нужна совсем единичным проектам. Тем, кто делает такие системы, эта статья ни к чему. Так что пункт 5 не нужен:)
    • +2
      Мощный сервер стоит гораздо дороже чем кластер из слабых, еще надо умножить на количество реплик. При этом если база всё таки достигнет потолка — будет очень неприятно. И зачем нужен этот риск?
      Для заведомо простых приложений есть еще Redis. Супер быстрый и прикольный — сделан для программистов, работа с данными происходит похоже на работу с памятью, привычные структуры данных и т.д.
  • +10
    Бум!

    highscalability.com/blog/2012/9/24/google-spanners-most-surprising-revelation-nosql-is-out-and.html

    We believe it is better to have application programmers deal with performance problems due to overuse of transactions as bottlenecks arise, rather than always coding around the lack of transactions.
    • –1
      Наверное поэтому gmail стал самым тормозным веб-приложением :)
  • +2
    Статья интересная, но с выводом о новой эре, мне кажется, вы погорячились. Грамотные разработчики/архитекторы всегда выбирали инструменты адекватные решаемой задаче и такие инструменты существовали еще в 20 веке.
  • +1
    Статья замечательная, но вывод нелеп. Ясное дело, что вначале были сплошь NOSql хранилища, затем попытались это дело стандартизировать и придумали SQL.
    Даже любой большинство джуниоров боясь страшного SQL вначале карьеры придумывают свои NOSql хранилища на файлах.
    Так что NOSql был, есть и будет, это не навинка, а возвращение к корням, дургое дело что для большинства проектов решения на базе стандартных SQL баз данных подходят лучше.
  • –1
    Недавно попробовал NoSQL и был просто в восторге от простоты и удобства, так как у меня не большой проект то эта база как раз для меня
    Всем рекомендую пройти туториал — времени займет не больше одного вечера, но в будущем позволит его сэкономить
    • 0
      Туториал по NoSql?
      • 0
        туториал по MongoDB
  • +2
    раньше говорили о разделении слоев представления данных в СУБД — физического и логического. в этом смысле SQL является не архитектурой БД, а интерфейсом слоя логического преставления данных, который позволяет приложению работать с данными в терминах реляционной модели.
    Смысл таков, что в NoSQL базах в отличие от реляционных структура данных не регламентирована
    мне кажется, что рассуждать в ключе, дескать NoSQL базы снимают ограничения реляционных — занятие, в достаточной степени, бестолковое. это все равно, что искать преимущества какого-нибудь типа, типа dict, над каким-нибудь типом, типа tuple. модели всякие нужны, модели всякие важны. они предоставляют различные интерфейсы, каждый со своими особенностями.

    идея реляционной модели состоит в представлении базы данных как коллекции логических высказываний (что характерно, где в каждый конкретный момент времени удовлетворены абсолютно все из них).т.е., по сути, это навороченный логический аппарат для оперирования высказываниями, касательно фактов предметной области. самостоятельно кодить такое внутри приложения — занятие достойное лишь Чака Норриса. поэтому жить реляционные будут еще очень долго и счастливо. просто нужно понимать, что структуры данных, c которыми эти базы предлагают работать приложению, относятся не приложению вовсе, а к самой модели базы данных и являются частью её интерфейса. отсюда все заморочки, если база нужна приложению не для извлечения логических утверждений, а для чего-то иного.

    для чего-то иного, нужно выбирать более подходящие модели представления данных. нужно, и даже — можно. сейчас мне кажется, что эта простая мысль стоит за всей шумихой вокруг NoSQL (по сути, такой выбор программисты делаю по сто раз на дню, пока не начинают относится к вопросу как задаче хранения данных :))
  • +2
    Расшифровывается как Not Only SQL
    кстати, ни что не мешает одной СУБД выставлять разные интерфейсы наружу, и давать, тем самым, возможность приложению использовать для работы с данными наиболее подходящие модели, в зависимости от решаемой задачи. например:
    * *
  • 0
    «Вы оба получите деньги, а мы поправим это позже.”

    Оригинальный подход. Действительно, вместо того, чтобы расчитывать на 100% надежности — закладываем страховку в бизнес-процессы. Талеб бы одобрил.
    • 0
      100% надежность бывает только на кладбище — там уже с гарантией никто не встанет. Все остальное до такой надежности не дотягивает, поэтому используется универсальное решение — дополнительные ресурсы про запас.
      • 0
        Да я и не спорю, подход очень грамотный. Жаль мы его часто забываем и зацикливаемся только на одном звене (ве — на разработке)
  • +4
    Всегда было интересно — так как же обыгрывается ситуация, когда у какого-то продукта меняется название. Неужели устраивается пробег по всем order_items?
    • 0
      Я думаю, на этот вопрос зачастую отвечает предметная область. Если я один раз купил себе Renault Clio (когда он ещё был только седаном), а затем его переименовали в Renault Symbol, то всё же в договоре купли-продажи всё-равно будет написано Clio. А когда через 5 лет он у меня развалится и я пойду в автосалон, в новом договоре уже будет обновлённое название…
  • 0
    Вы забыли главный аргумент и математическое подтверждение noSQL, eventual consistency — CAP-теорему.
    Как раз из-за математически доказанной невозможности построить расспределённую, надёжную, постоянно доступную систему придуманы eventual consistency и noSQL. И теорема имеет применение даже в пределах одного узла, если рассмотреть компъютер как набор узлов процесор, память, шина данных.ю внешняя память.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.