Pull to refresh

Comments 286

Redis лучше рассматривать как альтернативу MemcacheD/DB/Q — т.е. систему кэширования.
Redis это всё-таки как его определяли профи «in-memory data structures server».
Я знаю что там в полнюю версию включили репликацию и Lua скрипты, но ИМХО — превратить Redis в полноценную БД очень сложно, если модель данных умещается в парадигму кэшей — то все ОК, если нет — то все очень и очень печально.
Да, Redis не супер-функциональная база для любых задач, но уже далеко не лишь система кэширования.
Поясню на пальцах — если Вам/Ваша ORM больше укладывается в парадигму кэшей (ключ-значение) — то выбор Redis оправдан, если Вы хотите сделать что-либо сложнее — то на Redis это очень сложно, даже несмотря на то что уже есть поддержка Lua в мастре бранче и репликации более-менее юзабельны.
Я уже согласился выше. Я всё к фразе «Redis лучше рассматривать как альтернативу MemcacheD/DB/Q — т.е. систему кэширования.» придираюсь. Есть вещи, которые на Redis давно можно было сделать (без LUA), а на Memcache нет.
Мммм… Есть мнение что SQL как таковой избыточен для 80% задач типичного веба. Предлагаю обсудить.
сейчас SQL используется зачастую там, где нам нужно просто key-value хранилище. просто для того, чтобы упростить установку веб-приложения и не вводить новых компонент.
действительно на базовом веб-сайте SQL нам необходим лишь в паре «модулей», в остальных NoSQL / Key-Value хранилищ будет с избытком.
мне кажется именно с этим связано
Я думаю, в будущем, мы увидим больше комбинированных решений, которые включают SQL и NoSQL.
Так NoSQL-хранилище развернуть проще вроде бы.

Я думал над этим вопросом и для веба, имхо, sql реально нужен только для какого-то сложного BI (OLAP, отчеты и тому прочее), для чего все равно разворачивается обычно отдельный инстанс, который не нагружен продакшном, либо для комплексных операций где нужны нормальные транзакции. Но по большей части это банальный CRUD.
OLAP это вообще отдельная история.
SQL сложно использовать для сложных аналитических запросов.
Для это существуют специальные языки MDX, и новое веяние от майкрософт — DAX.
Спасибо за наводку, ушел читать ;)
Хотя если уже существует инфраструктура, построенная на SQL, включая оборудование и специалистов, то внедрение NoSQL может оказаться дороже, чем поддержка и доработка существующего.
Я думаю, в будущем, мы увидим больше комбинированных решений, которые включают SQL и NoSQL.
Такие на рынке есть уже давно.
Дореляционные СУБД (60/70-е гг.) тоже на месте не стоя́т.
Cache — довольно занятная система.
Из боевых систем (про которые я в курсе) — используется в работе ДЛО
кхм… если случайно навести мышку на аббревиатуру — то появится расшифровка.
Дополнительное Лекарственное Обеспечение
Грубо говоря — это льготное обеспечение лекарствами.

«ДЛО» — это дополнительное лекарственное обеспечение отдельных категорий граждан, имеющих право на государственную социальную помощь в виде набора социальных услуг».

Федеральный закон от 17 июля 1999 года № 178-ФЗ «О государственной социальной помощи» в редакции Федерального закона от 22 августа 2004 года № 122-ФЗ.
в какой части? там оракл всегда был.
В «клиентской» части, которая в аптеках ставилась.
«М-Аптека Льгота», если склероз не изменяет
Базовые классы тестовых данных там шикарны. Одно удовольствие потом наполнять базу тестовым контентом для проверки.
>>действительно на базовом веб-сайте SQL нам необходим лишь в паре «модулей», в остальных NoSQL / Key-Value хранилищ будет с избытком.

Если нужно в паре модулей, то зачем в остальных плодить сущности и использовать еще одну базу данных? Мне трудно представить модуль в котором nosql облегчит разработку. Там где требуется key=>value интуитивно понятно будет использовать простые запросы, типа SELECT * from table WHERE `id` = '1'

>>Так NoSQL-хранилище развернуть проще вроде бы.
Mysql разворачивается в пару кликов в windows и немногим более в linux. А также присутствует практически на всех хостингах и предустанавливается бесплатно практически на всех VDS/VPS и выделенных серверах.
«key-value»-базами NoSQL не ограничивается. Есть множество всяких специализированных БД — документо-ориентированные, объектно-ориентированные и так далее.

Там где требуется key=>value интуитивно понятно будет использовать простые запросы, типа SELECT * from table WHERE `id` = '1'


Встречный вопрос — ну и зачем для таких запросов городить реляционную (то есть со «связями») БД, если точно так же интуитивно понятно что-то типа
db.entity.find( { _id: 1 } );

Ну и если мы говорим о чем-то серьезном, то в любом случае ваш запрос будет скрыт за DAL в любой его форме.
Ну даже в простейшем бложике, может быть сортировка списка постов по дате к примеру, или автору, или количеству просмотров/комментов, плюс это может быть для разных разделов. А уже после этого выбор по id конкретного поста.
db.entity.find({author:ObjectId(author_id)}).sort({date:-1}).skip(page*count).limit(count)
Я как бы не писал, что это невозможно :)
SELECT * FROM posts WHERE author = &author ORDER BY date DESC LIMIT page*count, count

Кажется, такой будет MySQL-аналог. Выглядит, на мой пристрастный взгляд, проще вашего. Ну, и у вас фильтр простой. А можете так же „все комментарии пользователей из группы «друзья» за сегодня“? Мне кажется, будет трудночитаемая каша.
Навскидку, что типа этого:
db.comments.find({ author:{ $in:friends }, when:{ $gt:yesterday } })

А как это будет на SQL?
Мм, не понял, у вас подразумевается, что список членов группы «друзья» уже выбран и передаётся как объект-список?
Я подразумевал аналог примерно такого запроса (с выборкой из двух таблиц — комментариев и пользователей):
SELECT * FROM comments JOIN users ON comments.author = users.id WHERE DATE(comments.date) = DATE(NOW()) AND users.group = 'friends'
У вас запрос не полноценный — любой пользователь системы входит сразу в несколько групп, например он для Васи — друг, для Оли родственник, а для Пети просто знакомый.
Я думаю что вам в запрос нужно добавить таблицу «Группы Пользователей».

у вас подразумевается, что список членов группы «друзья» уже выбран и передаётся как объект-список?

Да, группы пользователя — это личные списки пользователя, поэтому их можно хранить готовыми в объекте пользователя (что я и сделал в одном соц. проекте). Вот для получения «друзья друзей» нужно (не всегда, зависит от реализации) выполнить такой же запрос на вхождение.
Изначально речь шла о личном бложике, поэтому имелось в виду что «друзья» — это друзья его владельца. А так пусть группа будет «администраторы», например.
Некоторые задачи решаются через MapReduce, что несколько сложнее, но зато можно сделать всё что угодно на обычном языке программирования, а не специализированным языком запросов.

Схема соответствия SQL запроса и MapReduce

Дело не в том, что это проще, а что это можно сделать, ну нужно учесть плюсы NoSQL решений, для многих проектов это было бы лучше, чем костылить на реляционной базе.
Именно, что список уже выбран.
Вы пытаетесь использовать нормализованные данные, это неправильный путь в случае с key-value хранилищами. Здесь лучше денормализовать данные, и, например, хранить список друзей пользователя прямо в его профиле, откуда он легко достается.
Я плохо пояснил — имелась в виду глобальная группа привилегированных пользователей (речь шла не о соц. сети, а о личном блоге)
Ну, достаем объект «группа» по id «friends», и вытаскиваем список пользователей оттуда, делов-то.
В общем, мысль такова: нет ни одной задачи по выборке данных, которую можно было бы решить на MySQL, и нельзя было бы решить с помощью NoSQL. Возможно, придется самому поработать интерпретатором и оптимизатором запросов, но тем не менее, ничего невозможного. Разница между ними в другом — тут уже много говорили про это.
Мне кажется, так можно и в Мускуле реализовать что угодно из «Носкула». Будет сложно, костыльно, велосипедно и неоптимально, но будет.
Суть SQL (для меня) в простоте выборок жёстко структурированных данных из более чем одной таблицы. Суть NoSQL, как я для себя понял из этого обсуждения — в простоте выборок сложных объектов из не связанных отношениями списков.
Меня смущает слово «городить», я бы заменил его на «использовать по назначению». Mysql жрать не просит, не требует ежедневных танцев с бубнами, подключается с помощью пары строк и довольно прост в применении.

>>Ну и если мы говорим о чем-то серьезном, то в любом случае ваш запрос будет скрыт за DAL в любой его форме.
Давайте определимся что такое базовый сайт. У меня ассоциации всплывают с блогами, информационными сайтами, интернет-магазинами и корпоративными сайтами. Большинство из них нет смысла создавать с помощью собственного велосипеда, достаточно напильником доработать один из сотни готовых движков, большинство из которых уже написаны с использованием той или иной sql. Миллионы посетителей и петабайты информации им не грозят и скорость sql если и является бутылочным горлышком, то лечится простым и дешевым апгрейдом сервера (намного более дешевым, чем поиск специалиста по nosql и переписывании кода).

>>db.entity.find({author:ObjectId(author_id)}).sort({date:-1}).skip(page*count).limit(count)
>>db.entity.find( { _id: 1 } );

Выглядит как SQL-запрос, пропущенный, через обфускатор
Полностью согласен. В довесок хотелось бы озвучить еще один момент.

Я может быть ошибаюсь, но разве эта ваша монга научилась ограничивать себя по памяти?
Раньше это было вопиющей проблемой, о которой все молчали, а доки стыдливо рекомендовали использовать отдельный сервер, сугубо под монгу.

Больше всего меня удивляет как разработчикам подсовывают schema-less под видом того что они смогут работать быстрее, а разработчики не видят, что при этом им втюхивают дополнительные приключения на app уровне. Выглядит как банальный маркетинг (одна несетевая ололо-гридфс чего стоит).

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

It is possible to achieve a multi-master replication scheme beginning with MySQL version 3.23. MySQL Cluster supports conflict detection and resolution between multiple masters since version 6.3 for true multi-master capability for the MySQL Server.

Используем в своём проекте, как и Redis.

Все как-то разом забыли историю СУБД и то, что реляционные хранилища (выражающий отношение; связанный с выражением отношений между чем либо) пришли на смену нереляционным.
История циклична и вправду.
Возможно, я неправ, и кластер (про который я, разумеется, слышал еще тогда :-) реально работает и так далее. Однако, о массовом его применении речь не идет. А вот в Монге — вполне. Вопрос же не только в том, что возможно сделать. Дело еще и в том, сколько придется затратить усилий… С монго, считай, и делать ничего не надо — мультимастер работает «из коробки». Если вы мне сейчас скажете, что я просто дремуч, и мультимастер с кластером — это такое же отлаженное и реально работающее бесплатное решение, как и сам мускуль — я, конечно, скажу спасибо и пойду читать.

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

Мы тоже редис используем. Монгу я использовал в одном из прошлых проектов. Я не бешеный евангелист РСУБД, просто не нужно наговаривать :)
Хранить древовидную структуру комментов в SQL это боль, а в докумето-ориентированных типа Couch, Mongo и Riak это элементарно и интуитивно.
Хотя бы тем, что документы можно легко вкладывать в другой документ.
Если у вас есть нормальная ОРМ, то я даже не задумываюсь, над тем, как хранятся данные. В нашем случае нестед сеты автоматически поддерживаются ОРМ, мне же остается делать только что-то типа item.GetChildren() / item.GetParents() и т.п.
Далеко вы так не уедете. Нужно получать весь список сразу (все дерево или ветку).
… если дерево статическое
Знаю, давно уже «просветился». У каждого подхода есть недостатки.
На активно меняющемся дереве с большим количеством элементов NS не будет работать. Если небольшая менюшка, то да.
У нас отлично работает на десятках тысяч элементов, а деревья больше мало кому нужны
И сколько времени выполняется обновление записи и какой уровень изоляции?
Спасибо за ссылку. Интересно посмотреть на производительность всего этого дела по сравнению с noSQL. Запросы выглядят адово.
Запросы выглядят адово.


Ну, тут уж приходится мириться — или простая вставка(id-parent), но долгая выборка, или сложная модификация, но быстрая выборка дерева.
Не знаю что все так стремятся сравнивать не-реляционные хранилища с реляционными. Они не про скорость :)
А у вас нет примера как это дерево по алфавиту отсортировать на каждом уровне?
Т.е. без извращений никак.
Предложите ваш вариант решения этой проблемы для какой-нибудь нереляционной СУБД.
А я ими вообще не интересуюсь и не являюсь специалистом в данной области. Сам использую данный подход для хранения структуры меню, каталогов, комментариев и пр.; а вот когда список большой хочется отсортировать его для удобства поиска, и варианта два: либо сохранять/дублировать в нужном виде, либо тратить вычислительные ресурсы, я пока выбрал программно обходить дерево и выстраивать его в нужном виде.
Ясно. Обычно разного рода сортировки над сложными сущностями, если весь массив данных и так получаем, имеет смысл делать на стороне UI — тут и возможностей больше и нагрузки на хранилища меньше.
Мне кажется, что сортировка дерева что для NoSQL, что для SQL будет происходить программно.
В языке M/MUMPS — для такого достаточно Order
>на базовом веб-сайте SQL нам необходим лишь в паре «модулей», в остальных NoSQL / Key-Value хранилищ будет с избытком

Можно поподробней?
Я сичтаю, что на базовом сайте key-value хранилище нужно только для сессий и то не везде они нужны — сессии это зло.
Остальное это как раз SQL (новости, комментарии, ордеры).
И за что минусовали, можно комментарий? Если вы утверждаете что на базовом сайте очень надо NOSQL, просьба аргументировать где именно, поскольку я ещё не встречал в базовый сайтах NOSQL.
Минус мне, это поддержка вашей идеи — обоснуйте, пожалуйста.
На базовом сайте SQL тем более не нужен. А вот в зависимости от того что именно вы считаете базовым сайтом, подходящие технологии могут быть различными.
Почему же SQL не нужен на базовом сайте?
Для меня базовый сайт, это:
— новости
— комментарии
— аутентификация
— какая-то специфика

Выбрать новости нужно джоинить новость с пользователем и с рубрикой, например или тегом.
Комментарии тоже нужен пользователь.
В NOSQL, правильно в статье замечено, вы рано или поздно потеряете контроль над своими данными, когда нужно будет удалить пользователся, например или собрать статистику. Да и делать такую избыточность ИМХО нет никакого смысла, когда это очень быстро решается в SQL.

NOSQL применяется в кешировании, сессиях, хранения прерасчитанных отчетов с избыточностью.
Я, к сожалению, не силён в NoSQL, спецы, при желании, поправят:

Пользователь(ЙДПользователь)= ИмяПользователя, пароль
+Индексы: ИмяПользователя => ЙДПользователь

Новость(Рубрика, Дата, ЙДНовость)= Тема, Пользователь, Тэги
+Индексы: Пользователь => его Новости, Тег => Новости

Комментарий(ЙдНовость, Дата, ЙдКомментарий)= Пользователь, Текст
+ Индексы: Пользователь => его коментарии,

Физическое удаление пользователя и в SQL и в NoSQL вариантах — глупость. Надо выбрать наиболее подходящий под логику вариант, например пометка на удаление, login=false и т.п.

Какую именно статистику?

И SQL и NoSQL не являются панацеей. В SQL тоже не трудно потерять контроль над данными при неверном проектировании, просто в SQL вероятнее получить другую проблему — тормоза.

Т.е. базовые сайты вы делаете именно в такой схеме и до сих пор не сильны в NOSQL?
Контроль даже над собой можно потерять. Если структура база нормализированна, то ничего вы не потеряете.
Удаление это не глупость, а часть жизненного цикла объекта.

Статистика нужна для разных вещей: пользователей (топ каких-то, топ коментаторов), новостей (топ по комментариям) и т.д.

нет, я вообще сайты не делаю. :( А в NoSQL не силён т.к. изучаю в свободное от работы время.

Полная нормализация — вещь вообще-то абсолютная. И в реальной применима на очень маленьких примерах. Вы вот например Фамилию пользователя будете хранить в одтельной таблице Фамилий?

Удаление логическое — да, а вот физическое не всегда.

Понятно. Пример наверно не очень удачный — его легко сделать на чём угодно. Разве, что на plain-text файлах повозится чуток придётся.
А почему вы считаете, что NoSQL будет работать быстрее при выборках по первичным ключам? Почему 3 запроса (джоинов то нету) в NoSQL базу должны отработать быстрее, чем 1 запрос с джоинами на 3 таблицы, в каждой из которых будем по первичным ключам получать данные?

Особенно интересны ответы на эти вопросы в случае с объёмом данных, не влезающим в память.
Во первых, я кажется не писал что будет гарантированно быстрее. Я писал что без всего можно обойтись.

Во вторых, в примере будет 1 NoSQL запрос. И в примере они уже будут как я решил отсортированы.

В третих, мне интересны только persistent NoSQL, и у них никаких проблем с поиском «вне памяти» нету.

Во-первых, вы писали:
В SQL тоже не трудно потерять контроль над данными при неверном проектировании, просто в SQL вероятнее получить другую проблему — тормоза.

Тормоза = производительность хуже = дольше извлекаются данные. Или вы что-то другое имели в виду?

Во-вторых, чтобы показать комментарий + новость, к которой он был сделан + автора вам надо получить 3 строки/объекта, как вы это сделаете за 1 NoSQL запрос?

В третьих, проблемы ой как есть. Допустим, у Mongodb, одной из самых популярных NoSQL баз, нету практически никаких оптимизаций при чтении данных с диска. Я просто оставлю тут ссылки на 2 картинки:

www.mysqlperformanceblog.com/wp-content/uploads/2010/04/InnoDB_int.png
qanswers.files.wordpress.com/2012/06/p1.png

Кстати, если вы в монге не будете удалять данные — то вы будете тратить page cache на кеширование удалённых записей.
Так не на таких же данных! Вы тут и NoSQL запутаь не сможете.

Именно это.

Я говорил про главную страницу.
А для примера «показать комментарий + новость, к которой он был сделан + автора» мне тоже достаточно 1го NoSQL запроса(но лучше сказать прохода). Но тогда я не верно спроектировал структуру.

Новость(Рубрика, Дата, ЙДНовость)= Тема, Пользователь, Тэги
Новость(Рубрика, Дата, ЙДНовость, Дата,)= ЙдКомментарий, Пользователь, Текст.

А путь до аватарки пользователя где хранится, в каждом комментарии? Как он её будет менять?

Комментарий, кстати, всё равно непонятно как показать вместе с новостью, даже если вашей новой схемой пользоваться.

А что там с главной страницей?
Тогда больше запросов нужно.

это будет в терминах SQL выборка из одной таблицы с одним условием на ЙД новости в WHERE секции.

Аналогично.
Я вообще не понимаю ваших ответов, если честно. Вы могли бы подробно описать в одном комментарии, какие данные и как хранятся, и как вы их извлекаете.

Допустим, это страница комментария, как в ЖЖ: надо показать новость, 1 комментарий, автора с аватаркой и прочими его атрибутами.
Вот вариант. Это сделано на M/MUMPS для GT.M.

Данные
Set ^Users("4dmonster","avatar")="/avatars/green_monster.png"
Set ^Users("4dmonster","email")="4dmonster@gmail.com"
Set ^Users("4dmonster","password")="********"
Set ^Users("ANDcle","avatar")="/avatars/BigDollar.jpg"
Set ^Users("ANDcle","email")="navel@whole.earth"
Set ^Users("ANDcle","password")="i am the god of data"
Set ^Users("YourSQL","avatar")="/avatars/HasNoFuture.bmp"
Set ^Users("YourSQL","email")="over@the.sun"
Set ^Users("YourSQL","password")="i can run SP"
Set ^Users("internet","avatar")="/avatars/inet.jpg"
Set ^Users("internet","email")="root@127.0.0.1"
Set ^Users("internet","password")="***"

Set ^News(1,"Author")="internet"
Set ^News(1,"Caption")="RDBS vendors strikes back"
Set ^News(1,"Section")="HolyWars"
Set ^News(1,"Text")="RDBMS vendors are trying to catch the NoSQL train dispite their own bullshit  fire on opponents' technology."
Set ^News(1,"comments",1,"author")="4dmonster"
Set ^News(1,"comments",1,"date")=201302221604
Set ^News(1,"comments",1,"text")="Тtrue story"
Set ^News(1,"comments",1,"vote")=-2
Set ^News(1,"comments",1,"vote","ANDcle")=-1
Set ^News(1,"comments",1,"vote","YourSQL")=-1
Set ^News(1,"comments",2,"author")="ANDcle"
Set ^News(1,"comments",2,"date")=201302221605
Set ^News(1,"comments",2,"text")="I'll sue you!"
Set ^News(1,"comments",2,"vote")=0
Set ^News(1,"comments",3,"author")="YourSQL"
Set ^News(1,"comments",3,"date")=201302221608
Set ^News(1,"comments",3,"text")="It wasn't me!"
Set ^News(1,"comments",3,"vote")=1
Set ^News(1,"comments",3,"vote","4dmonster")=1
Set ^News(1,"picture")="/pics/Motaro_vs_ShangTsung.gif"
Set ^News(1,"vote")=-1
Set ^News(1,"vote","ANDcle")=-1
Set ^News(1,"vote","YourSQL")=-1
Set ^News(1,"vote","monster")=1


Вот файл forHabr.m
root@flexy:~/.fis-gtm/V6.0-001_x86_64/r# cat forHabr.m 

ExampleNews(NewsId)
    write !,"=================================================",!
    write "Category       :",^News(NewsId,"Section"),!
    write "Caption        :",^News(NewsId,"Caption"),!
    write "Picture        :",^News(NewsId,"picture"),!
    write "Text           :",^News(NewsId,"Text"),!
    write "Author         :",^News(NewsId,"Author"),!
    write "Author's avatar:",^Users(^News(NewsId,"Author"),"avatar"),!

    write !,"Rating         :",^News(NewsId,"vote"),!    
    write "Voters: "
    set voter=""
    For  Do  Quit:voter=""
    .Set voter=$Order(^News(NewsId,"vote",voter))
    .Quit:voter=""
    .write voter,"(",^News(NewsId,"vote",voter),") "

    write !,!,"Comments: "
    set comm=""
    For  Do  Quit:comm=""
    .Set comm=$Order(^News(NewsId,"comments",comm))
    .Quit:comm=""
    .write !,"-----------------------------------------------"
    .write !,^News(NewsId,"comments",comm,"author"),"(",^News(NewsId,"comments",comm,"date"),") avatar:",^Users(^News(NewsId,"comments",comm,"author"),"avatar")
    .write !,": ",^News(NewsId,"comments",comm,"text")
    .write !,"Rating: ",^News(NewsId,"comments",comm,"vote")
    .write " Voters: "
    .set voter=""
    .For  Do  Quit:voter=""
    ..Set voter=$Order(^News(NewsId,"comments",comm,"vote",voter))
    ..Quit:voter=""
    ..write voter,"(",^News(NewsId,"comments",comm,"vote",voter),") "

    write !!,"===================================================",!


Вот результат работы продедуры:
GTM>Do ExampleNews^forHabr(1)

=================================================
Category       :HolyWars
Caption        :RDBS vendors strikes back
Picture        :/pics/Motaro_vs_ShangTsung.gif
Text           :RDBMS vendors are trying to catch the NoSQL train dispite their own bullshit fire on opponents' technology.
Author         :internet
Author's avatar:/avatars/inet.jpg

Rating         :-1
Voters: ANDcle(-1) YourSQL(-1) monster(1) 

Comments: 
-----------------------------------------------
4dmonster(201302221604) avatar:/avatars/green_monster.png
: Тtrue story
Rating: -2 Voters: ANDcle(-1) YourSQL(-1) 
-----------------------------------------------
ANDcle(201302221605) avatar:/avatars/BigDollar.jpg
: I'll sue you!
Rating: 0 Voters: 
-----------------------------------------------
YourSQL(201302221608) avatar:/avatars/HasNoFuture.bmp
: It wasn't me!
Rating: 1 Voters: 4dmonster(1) 

===================================================



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

Код программы компилируется один раз и исполняется на сервере БД, т.е. это аналог не SQL запроса а хранимой процедуры.

Обращение к ^News это как внутри хранимки открыть курсор таблицы без джойнов но со всеми данными в столбцах, кроме аватарок.

Обращение к аватаркам это почти как обращение к полю по первичному кластерному индексу.

А теперь представьте тоже самое для РСУБД, да ещё без денормализации.
В вашем варианте вы сэкономили ровно 2 похода в индексы — сразу извлекаете комментарии вместе со статьёй и её оценки. Это хорошо.

Но при этом каждая запись в таблице новостей постоянно растёт. Здесь возникает тот самый вопрос нормализации-денормализации: а будет ли так быстрее? Может быть, вы потеряете больше, чем получите? Ведь тут встаёт вопрос об эффективности работы той части базы даных, что работает непосредственно с диском. Есть ли в базе данных возможность эффективно обновлять данные на диске, как эффективно она рабоатет в случае постоянно растущих по объёму записей? В зависимости от профиля нагрузки ваш вариант может оказаться как быстрее аналогичного в SQL базе, так и медленнее.

Что касается консистентности — в случае такой схемы вам надо как-то решать проблему консистентности на уровне приложения. В одном потоке добавляете комментарий к статье, а в другом автор этого же комментария удаляется — что делать, если второй поток придёт чуть раньше первого?
Удаление автора комментария вообще-то обычно не должно приводить к удалению комментария.
Но вообще да — в подобных системах подразумевается, что согласованностью данных будет заниматься приложение.
Эффективность работы с диском вполне может быть сравнимой с RDBMS — можно, например, максимально хранить данные в памяти, а на диск писать changelog. Учитывая то, что обычно у подобных систем нет проблем с шардингом, можно обеспечить вариант, когда диск используется только на случай отключения питания, а работа ведется с данными в памяти.
Работать в памяти и изредка синкать — довольно дорого в случае больших объёмов. И почти наверняка по скорости не будет разницы с RDBMS просто потому, что всё остальное (шаблонизатор, бизнес-логика) будет работать существенно медленней. Да и накладно — 1 тебарайт данных потребует минимум 6 машин (на сколько я в курсе, за вменяемые деньги сейчас можно запихать не больше 192 гигабайт в один сервер), если делать репликацию — то уже 12 получается.

Я к чему — дисковая подсистема в InnoDB в разы лучше большинства NoSQL, но никто этого не замечает. Зато все кричат, что MySQL плохо шардируется. Но, может, на 1 машинке со 192 гигабайтами памяти и 1 тебарайтом данных он будет работать не сильно хуже, чем NoSQL на 6 машинах с 192 гигами каждая, и шардировать то не надо?
А терабайт пытались с ленты восстановить, например? Это достаточно долго, в отдельных случаях подобная задержка недопустима (я недавно с таким сталкивался — как раз терабайт был, восстановление из бэкапа несколько часов шло). Так что уже в любом случае не один сервер нужен, а минимум два. Опять же, в случае смерти одного из зеркалируемых серверов получаем задержку (если это был мастер) на подъем слейва до мастера, потом значительное падение производительности (остался-то один сервер), а потом еще тратим время на синхронизацию, причем до полной синхронизации есть вероятность вообще все потерять, т.к. живой сервер только один. Так что добавляем еще третий сервер, падение производительности меньше, но все равно есть задержка на переключение мастера, например.

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

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

1. Все сервера одинаковые, по 192 гигабайта памяти в каждом. Вы сами предложили 1 терабайт в память положить, итого надо 6 серверов в реплике для NoSQL и 1 сервер в реплике для MySQL.

2. Если добавляем реплики — то добавляем в обоих вариантах, получается 12 против 2 серверов или 18 против 3. Повторюсь, сервера одинаковые.

3. Репликация. Если Master-Slave, то в обоих случаях переключение не моментально и есть риск потери данных. Если Master-Master синхронный — то переключение незаметно совсем, но производительность на запись ниже. У MySQL для этого есть Galera, возможно, есть что-то и для вашей любимой NoSQL базы.

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

Почему вы голословно утверждаете о худших алгоритах работы с диском???

Да, консистентность отдана в ведение приложения. Кроме того, для статистики в примере придётся создавать индексы. И их поддерживать придётся тоже самому приложению. Но это, согласно исследованиям, не скажеться ни на скорости работы (вроде как в «6 раз быстрее оракла») ни на скорости написания приложения(тоже «в несколько раз быстрее чем на других языках/технологиях»).

M/MUMPS, внезапно, поддерживает и транзакции и нормальную работу с LOCK. Соответственно мне достаточно решить во время написания кода, что делать в ситуации когда автор сохраняемого в базу коментария удалён.
Рядышком уже предлагали один из вариантов:
SELECT n.Category, n.Caption, n.Picture, n.Text, n.Author, u.avatar FROM news AS n JOIN users AS u ON n.author = u.id AND id = &NewsId

SELECT * FROM comments WHERE comments.newsId = &NewsId JOIN users ON users.id = comments.author ORDER BY comments.date

там разве что надо добавить выдачу аватарки из таблицы users. Где именно, по-вашему, я не прав? Вы экономите на походы в индекс в таблицу comments и на поход в индекс в таблицу votes. В users ходить в любом случае придётся. В news — тоже. Если таблицы не очень здоровые — индексы всосутся в память и работать будут быстро.

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

В случае того же MySQL запись о новости один раз укладывается в buffer pool, после этого уже не изменяется. Комментарии добавляются в другие пулы, но тоже не изменяются. Писать очень быстро, читать — не очень, зато есть продвинутая система кеширования и дефрагментации.

В случае хранения комментариев как куска самой новости у вас запись постоянно растёт в размере. Соответственно, вам надо будет либо перетаскивать её с места на место, либо преаллокейтить заранее сколько-то места (непонятно, сколько), либо хранить её кусками. в первом случае записывать совсем долго, зато быстро читать. В третьем случае читать долго (по сути — новость и комментарии хранятся отдельно), зато писать удобно. Второй случай — промежуточный, но требует эвристик. Как именно реализовано в GT.M — я не знаю. Вы знаете? Если да — расскажите, мне интересно.

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

«я не знаю. Вы знаете? Если да — расскажите, мне интересно.» — именно и есть определение голословного утверждения.

На самом деле консистентность там можно поддерживать и без транзакций — при помощи нормальных блокировок LOCK. А традиционное для РСУБД явное управление транзакциями было внесено в стандарт по «просьбам» клиентов.
Я в тексте написал про таблицу votes. Вы не читали? Или мне обязательно надо было дописать ещё 1 запрос и один джоин? Я же вроде сразу написал, что да, в случае SQL базы надо будет больше запросов. Вопрос в том, в сколько походов на диск они превратятся.

Пока что это вы обвиняете меня в том, что я не говорил. А именно: я не говорил, что GT.M хуже работает с диском, чем InnoDB. Я предположил 3 варианта, как это может быть сделано, указал их плюсы и минусы. Вы продолжаете настаивать на том, что я что-то голословно утверждал? Тогда прочитайте мой комментарий выше, про InnoDB и большинство NoSQL. Большинство != все. Судя по вашим ответам, как именно работает с диском GT.M вы тоже не знаете. Более того, именно вы в своём комментарии в верху этого тредика написали, что в SQL базе вероятность получить тормоза больше, чем в NoSQL.
А теперь представьте тоже самое для РСУБД, да ещё без денормализации.
Не могу понять, в чём разница. Ну, кроме того, что в РСУБД, обычно, форматирование вывода не запихивают.
Будет несколько запросов такого вида:
SELECT n.Category, n.Caption, n.Picture, n.Text, n.Author, u.avatar FROM news AS n JOIN users AS u ON n.author = u.id AND id = &NewsId

SELECT * FROM comments WHERE comments.newsId = &NewsId JOIN users ON users.id = comments.author ORDER BY comments.date

А потом вывод формируется в приложении из этих данных. Если канал приложение↔СУБД узок, то можно чуть-чуть сэкономить, запрашивая список данных пользователей отдельным от комментариев запросом.
Форматирование я сделал чтобы коменты в коде не писать — из самого кода понятно что выводится. Можно было и в JSON и в HTML и в XML запихать вывод.

Вы тоже не стали полностью пример повторять — поэтому всё стало примитивнее.

Приведите полный код для повтора вывода моего примера. Вместе с кодом приложения или хранимкой, тогда станет понятнее.

из самого кода понятно что выводится
Вы это серьёзно? Очевидно для людей, которые M[UMPS] впервые видят? (а иначе бы у вас не спрашивали)
Скрытый текст
Второй день смотрю, не могу понять, что значит
For  Do  Quit:comm=""
Судя по For — цикл. Потом сразу Do? До условия цикла? Бесконечно повторять? Но что тогда значит Quit после него с каким-то присваиванием — выход с пустым значением? «И сразу выход!» Условие выхода из цикла? Тогда почему второй же строчкой после идёт опять Quit? Теперь это безусловный выход? Тогда почему форматирование точками продолжается, как будто оно ещё идёт? По два раза каждый цикл проверять voter? Брр, раскопал доки — да, цикл без счётчика — for<пробел><пробел>do<пробел><пробел>quit:(условие выхода), но зачем каждый цикл условие выхода проверяется по два раза?

Код приложения чуть попозже напишу. Надо ещё решиться, на чём писать.
Синтаксис действительно непривычный. Но если учесть почти пятидесятилетний возраст языка — становится понятно, что всё было направлено на скорость интерпритации([байт]компилироваться он позже научился). Я кстати код брал из «книжного примера программы» википедии. А так как все команды имеют ещё и краткую форму можно писать «пример реальной программы» где уже что-то понять могут только мумпсеры.

В $order — получение очередного значение, если "" — значит кончились и выход.

Буду ждать. Надеюсь структура вывода будет такая-же.

Вообще было бы неплохо реально сравнить оба подхода на одном и том же примере. А в идеале ещё и на скорость работы проверить.
Ок, давайте обсудим. Во-первых, как я понял речь идет все таки о РСУБД, а не об SQL. SQL — всего лишь один из языков запросов. Во-вторых, не очень понятно, о каких задачах идет речь. Если вы говорите о визитках, интернет магазинах и корпоративных сайтах, то обычно самой сложной частью таких приложений является CMS. Таким образом, можно говорить о том, что большинство задач типичного веба требуют реализации CMS (либо взять готовую). Задача уже подразумевает некоторую предметную область включающую как минимум пользователей, роли и ресурсы. ИМХО, реляционные таблицы — вполне адекватный инструмент для такой задачи.
Нет, я говорю о веб-приложениях в целом. CMS — тоже веб-приложения. Их необходимость для сайтов-визиток и вообще тема «конструкторы vs конкретные системы» — тема отдельного холивара ;)

Речь идет не о РСУБД, а о реляционных базах данных как таковых, если уж быть точным. В контексте термина NoSQL, термин SQL вполне понятен, имхо.
Ну так ответьте тогда на вопрос, что такое «80% задач типичного веба»?
Это CRUD по атомарным сущностям:
1. Добавить сущность.
2. Отфильтровать список сущностей.
3. Обновить сущность.
4. Удалить сущность.
Ни разу в жизни не встречал коммерческий веб-проект функциональность которого ограничивалась бы только тем что вы написали. Есть у меня сомнения по поводу того, что 80% веб-приложений реализуют только голый crud и больше ничего.
Я вообще думал, что мы говорим о задачах СУБД в рамках веб-приложения, а не о задачах приложения.
Сгруппировать, отфильтровать, саггрегировать циферки, добавить данных из разных сущностей… ;)
Ну и если говорить о системах управления контентом, то есть такие документо-ориентированные БД, которые тоже входят в группу NoSQL.
Я не говорю о том, что для реализации CMS нельзя использовать документо-ориентированные базы, я защищаю реляционные базы в том смысле, что их использование мне кажется вполне оправданным на тех самых 80% проектов. Я бы скорее сказал, что документо-ориентированные базы — это в некотором смысле оверкилл для типичных задач. Их 100% удобно использовать там где имеешь дело с неструктурированными данными и нечеткой схемой, но в большинстве случаев, этого как раз и не требуется.
Посмотрите структуру базы данных какого-нибудь Drupal.
Смотрел неоднократно, что я там увидеть должен?
Большинство таблиц не несут самих данных, а нужны лишь для связи множества объектов друг с другом, причём зачастую эти связи реализованы не по правилам реляционных баз, но это уже не проблема самих баз, а лишь разработчиков. Видно же, что впихнули не туда свою разработку. В документной базе данных было бы гораздо легче разработать такого уровня CMS, что в недалёком будущем и произойдёт, надеюсь, когда разработчики научатся работать не только с «SQL базами данных».
Любая нормализованная схема будет содержать кучу связей если предметная область чуть чуть более чем тривиальна. И не важно, в каких терминах мы ее проектируем, документами или реляционными таблицами.
NoSQL поощряет денормализацию, и это кстати один из минусов, т.к. делаться она должна очень аккуратно, что не всегда происходит в реальности.
Некоторая денормализация — это не всегда плохо.
нормализация это метод исключения логических аномалий в реляционной модели данных. что тут делает NoSQL вообще — он, типа, поощряет в данных логическую противоречивость?)
Большинство таблиц не несут самих данных, а нужны лишь для связи множества объектов друг с другом
разве может быть как-то иначе?) реляционная модель это навороченная логика на самом деле. в ней выражаются логические связи между данными, а так же реализуются операции над ними.
Большинство CMS как-раз таки реализуют разнообразные костыли для поддержки нечетких схем поверх реляционных баз.
Мм… не совсем верно, конечно, гибкость в настройке требует очень глубокой нормализации, например для того, чтобы создавать новые типы данных ручками, но при эксплуатации обычно используется статичная реляционная модель. Никаких eav и прочих извращений, которые всем своим видом намекают на использование документов.
Причем тут нормализация?

Я говорю о диком оверхеде тупо по количеству сущностей, которые нужно поддерживать и количестве связей.
а оверхед это и есть следствие очень глубокой нормализации. а очень глубокая нормализация получается из требований к универсальности модели данных («нечеткости схем»), в купе с необходимостью обеспечивать, при всем при этом, их логическую непротиворечивость.
Считаю, что надежный рабочий инструмент должен быть избыточен.
Толщина гаечного ключа избыточна, но так как-то надежнее :)
… пока вам не приходится таскать на спине ящик с сотней гаечных ключей, из которых реально нужен только один — под конкретную гайку.
Странная аналогия, кому мешает mysql установленный на веб-сервере?
Он мешает не на веб-сервере, он мешает разработчику. Особенно, если эти «гаечные ключи» начинают использовать «потому что можно».
Он же памяти как сволочь жрет, на VPS-ках это действительно важно.
Брать полгига оперативки, когда все может сносно крутится на 128 — оверкилл.
Наверное потребление ОЗУ зависит от параметров конфигурации, как думаете?
Зависит. В дефолтной конфигурации mysqld занимает около 70 мегабайт RAM.
Меньше можно, да.

Я о том, что ставить mysqld на каждый веб-сервер, потому что он никому не мешает — слишком. Я не против SQL, но для большинства моих задач MySQL — оверкилл.
хм, вот сейчас глянул — на рабочем сервере занято всего 75mb оперативки из них 45 — mysqld. Ну многовато, да. Но учитывая что там БД весит 25мб и она вся естественно в памяти — не очень.

Думаете какой mongodb ел бы сильно меньше памяти?
Я не работал с NoSQL в привычном виде (т.е. Redis/Mongodb), я пользуюсь ZODB в данный момент.
Ничего не имею против SQL-баз, но мне просто глубоко неприятен сам MySQL, я постоянно с ним натыкался на какой-нибудь геморрой — неясные падения производительности, оверхед по памяти, нагрузка на диск, раньше были проблемы с кодировками, не знаю, как сейчас с этим. Postgres и SQLite мне больше нравятся по подходу.
Не знаю как сейчас, но пару-тройку лет назад postgre был заметно медленнее… А sqlite вообще не конкурент, оно совсем для других сфер применения ведь.
Насчет производительности — я не уверен на 100%, но MySQL сливает при выборке из разных таблиц по связям, Postgres сливает, если выборка из одной таблицы. По крайней мере, раньше было так.

Да, я знаю, что SQLite не конкурент. Но для маленькой базы я предпочту его, чем ставить что-то мощное.
Эм, а давно MySQL является составной частью ОС?
Как вы поддерживаете консистентность данных? Скажем, добавляется комментарий к посту и одновременно пост удаляется. Я не про конкретно пост+комментарии, а про любые 2 связанные сущности.
атомарный LOCK например.
UPD: я понял что вы не про механизм программирования спрашивали, а намекали на отсутствие изкоробочной-повсеместной поддержки сылочной целостности.
А если у вас сотни серверов по всему миру? Так просто LOCK вы уже не сделаете.
Но РСУБД такое просто не потянут. А вот NoSQL на такое можно запрограммировать. Правда одним LOCK уже явно не отделаться.
Ну тут собственно CAP теорема во всей красе. В вебе вроде как почти всегда можно пожертвовать связностью ради доступности. То есть позволить добавить комментарий к удалённому посту, это потом можно будет всегда починить. А вот РСУБД это всегда связность взамен доступности. Для банков это, безусловно, наиважнейшее свойство.

One size doens't fit all.

В couch вообще никакого лока не надо, оно само починится при синхронизации, time to relax :)
РСУБД это всегда связность взамен доступности


Внезапно! Кто мешает в РСУБД сохранить несогласованные данные и привести их в соответствие по тому же принципу, что в нереляционной системе? В то же время реляционная позволяет задействовать контроль целостности, там где нереляционная просто не обладает соответствующей функциональностью «by design».

«Само» — это те ещё «подводные грабли»
Если у вас равноправные датацентры, вы никуда не денетесь от большого трафика между ними и задержек, связанных с синхронизацией. Так что для поддержания консистентности можно просто использовать любое кластерное решение, поддерживающее распределённые блокировки, например, zookeeper.
Судите сами. Для исполнения каждого SQL запроса необходимо:
1) Распарсить SQL-запрос.
2) Проверить синтаксис
3) Проверить наличие соответствующих таблиц и полей, имена которых используются в запросе.
4) Представить запрос в виде, пригодном для оптимизации.
5) Провести оптимизацию
6) Преобразовать оптимизированный граф в последовательность команд для исполнения.
7) И собственно выполнить команды…

Большинство NoSQL баз обычно переходят сразу к пункту 7. Все оптимизации разработчик делает сам, исходя из задачи и здравого смысла…
Не знаю как вам, а мне очевидно.
П. 1-6 в современных СУРБД делаются один раз и кэшируются если что.
Вопрос в другом — нафига тащить за собой (и покупать за деньги) все те наслоения функциональности и легаси, которые понапихали в тот же оракл за эпоху двузвенок?
Любопытно… Как вы будете кешировать пп. 1-3?.. 0_о
Сами-то читали? Я эти разделы документации MуSQL в своё время раз по десять на дню читал…

Особенно query cache хорошо написано. 70% текста описывает в каких случаях кеш запросов не работает. Например, при каждом INSERT или UPDATE кеш сбрасывается… При использовании в SQL-запросе функций состояния типа timestamp() кеш игнорируется… В общем серьезное подспорье, без сомнения…

И всё равно парсить запрос придется…
Хорошая статья на эту тему — Query Execution Basics на примере MySQL. Не так негативно, как вы описали.
Большинство NoSQL баз обычно переходят сразу к пункту 7.

Не знаю как вам, а мне очевидно.

Не холивара ради, но вы исходники того же Mongo читали? Там тоже есть индексы, query cache, parser, query optimizer и еще много страшных слов :)
Читал, и более того использую mongodb на практике… Для того, чтобы декларативный SQL преобразовать в конкретный код, требуется куда больше затрат чем даже js-код MongoDB. Про прямые библиотечные вызовы я даже не говорю…
Для того, чтобы декларативный SQL преобразовать в конкретный код, требуется куда больше затрат чем даже js-код MongoDB.

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

Но mongodb — хоть и популярный но никак не представитель core NoSQL. Он скорее засланный казачок от NoSQL в стан реляционных баз данных и играет на их традиционной территории. И играет, надо сказать, неплохо…
Нет, не так. В вебе отдельные запросы редко когда бывают очень уж сложными и требующими большой производительности, но зато их очень много. И тогда экономически более выгодно становится делать много маленьких и дешевых серверов вместо одного мощного и дорогого. Это требует соответствующих подходов в разработке.
RDBMS на такую ситуацию не рассчитаны, а NoSQL-системы (которые здесь в основном обсуждают) как раз для этого и создавались. В этом весь смысл NoSQL, а вовсе не в избыточности RDBMS.
Что вам мешает натыкать много маленьких мускулов и перенести логику шардинга в DAL слоя приложения?
А зачем?
В смысле, при таком подходе от mysql ничего не останется, то есть не будет разницы между ним и, скажем, mongodb в плане функционала. Плюс, придется самому дополнительно пилить логику шардинга, которая уже реализована в mongo из коробки.
Ну я про то, что не SQL избыточен, его просто не получается использовать на таких задачах. Если бы был удобный способ использовать SQL в таких условиях — я был бы только за, но пока я не видел таких решений.
Быстрый доступ к данным (если все данные помещаются в оперативной памяти),

В случаях, когда данные начинают не помещаться в памяти, SQL, как правило, превосходит NoSQL.

С чего бы это? NoSQL-решения не используют файловых индексов?
Ситуации бывают разные, но готов предположить, что товарищи, которые занимались десять лет разработкой пылесоса для сухой уборки, сделают его лучше для сухой уборки, чем ребята, которые «позавчера» сделали ультрасос для сухой и влажной уборки и любых поверхностей.
Материала по этому вопросу очень много, вот просто с ходу:
mysqlha.blogspot.ru/2010/09/mysql-versus-mongodb-fetch-by-secondary.html
mysqlha.blogspot.ru/2010/09/mysql-versus-mongodb-update-performance.html
UFO just landed and posted this here
В тесте рассматривается Монго 1.7, актуальная версия — 2.2.
Думаю, что Монти в контексте имел конкретное NoSQL решение
В этом случае очень трудно превзойти SQL оптимизатор для комплексных задач, особенно выборки, которые автоматически генерируются на основе запросов пользователей (этого требует большинство веб-сайтов).


А вот этот тезис вообще очень и очень спорный. Он может быть верен для каких-нибудь универсальных корпоративных баз знаний, где действительно запросы могу генерироваться пользователями (хотя та еще спорная практика). Но вот в вебе запросы всегда одинаковые за исключением значений аргументов.
Нет, конечно. Ну, например, фильтры подбора товара в интернет-магазинах электроники или там в яндекс.маркете. Вот там хороший оптимизатор может очень ускорить выборку. Скажем, поиск по производителю «Гнусмас» возвращает 20000 строк, поиск по цвету «черный» скажем 30000 строк, а поиск по цвету «нежно-лиловый» возвращает 3 строки. В случае, если юзер ищет нежно-лиловый Гнусмас, планировщик запросов может показать себя во всех красе.
Это называется «фасетный поиск».

И MS SQL, например, под реальной нагрузкой на этой задаче радостно ложится поспать. Поэтому под него используют, например, тот же Sphinx.
Вы написали: «но вот в вебе запросы всегда одинаковые». Вам привели контр-пример. Вот вам еще один: всякие хитрые ACL для «подзамочных постов», закрытых разделов форумов и т.п. — там тоже вполне себе монструозные SQL-запросы в части WHERE. Писать всё это вручную на key-value storage — ад и содомия.
Про большую нагрузку, способную положить MS SQL, речь как-то не шла.
Вы привели пример с которым я сталкивался непосредственно и с которым планировщик не справился. При том, что все остальное вполне себе продолжает крутится на ms SQL server.

С ACL тоже сталкивался, в силу того что они всегда забираются блоком их вообще можно хранить в XML каком-нибудь, что и было прекрасно реализовано.

Приведите более конкретный пример, пожалуйста.
Эммм ACL в XML? Не, я про всякие социальные сайты. Ну, знаете там, «эту глубокомудрую запись могут видеть только мои друзья и друзья друзей». И вот вам нужно сгенерировать страницу юзера со всем самым новым, к чему он имеет доступ в соответствии с текущим социальным графом, учитывая репосты.
А насчет MSSQL — я не фанат этой системы, но вообще либо вы её плохо приготовили, либо у вас было слишком слабое железо для вашей нагрузки.
Я тоже про социальные сайты.
chainik,

Была статья на Хабре на похожую тему.
Помимо прочего там автором использовалась неполная и нечёткая предметная область, информация о которой дополняется в процессе использования системы (подобие EAV только для NoSQL).
Ссылка на реальный проект, указанная автором статьи немного устарела, здесь более новая (внизу страницы есть логотип Caché).
Кстати, с версии Caché 2012.2 можно BI использовать и над неструктурированными данными.

Я не слышал, чтобы какие-то современные NoSQL-системы имели встроенную поддержку SQL, не говоря уже о MDX над живыми данными.
Согласен. Даже более того, я считаю, это откровенное лукавство со стороны Видениуса.

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

И лишнее тому подтверждение, это интеграция MariaDB с NoSQL решениями. Это позиционируется чуть ли не как основная фишка MariaDB. Если преимущество NoSQL спорно и неочевидно, то зачем это Видениусу тогда?

NoSQL — это не мода, в hardcore IT нет понятия гламура. Это способ решения проблем, которые оказалось невозможным решить с помощью реляционных CУБД с вменяемыми затратами ресурсов.

Посмотрите на типичного представителя RDBMS в Big Data — Oracle. Всем, кто более-менее в теме баз данных уже очевидно, что это тупик и разводилово на бабло денежных мешков…

Гы, правда всем? Я вот не представляю, как бы мы обходилисись без Oracle при всей его монструозности.
А почему он стал вдруг тупиком? Что из коробки потянет таблицы на десятки терабайт с полноценной поддержкой транзакций и прочих ништяков?
Терабайты из коробки, ништяки? Вы просто не в теме… Сертифицированные специалисты по Oracle не зря свой хлеб получают, уж поверьте… И им их жизнь сладкой не кажется.
Тюнинг Oracle под конкретную схему и под конкретное железо — отдельная тема… И стоит это совершенно невменяемые деньги…
Комменты к топику только подтверждают слова, что повальное увлечение NoSQL лишь мода. Почти все ответы без аргументов. В кучу смешали все виды приложений от сайтов на коленках до энтерпрайза, все NoSQL решения. И только РСУБД для 90% отметившихся тождественно MySQL. Что за бред делать культ из инструментов и не смотреть по сторонам.

Чем заслужила немилость БД оракла? Или вы про NoSQL решение от них же (которое вероятно единственное сейчас с полной поддержкой ACID)? Цены да, кусаются. Только продукты от оракла направлены на крупные промышленные решения со сложной инфраструктурой и интеграцией. Ну не для сайтиков оно и не лезет в эту нишу.

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

Возьмите для моды напишите NoSQL CУБД, хотя бы сравнимую по производительности с MySQL. Потом поговорим про говнокод… С задачами для которых создавались NoSQL, реляционные базы очевидно не справились.

Про Оracle пусть расскажут те кто с ним реально работает. Например операторы сотовой связи из большой тройки. Пусть расскажут, как у них там всё гладко с Ораклом и сколько стоят контракты на поддержку… Обычный стартап себе такие деньги вряд ли сможет позволить…
Какая-то абстрактная чушь. Зачем мне писать СУБД? Вы хоть понимаете для чего нужны NoSQL и для чего реляционные базы?

И с ораклом по работе имею дело постоянно. И видел картину творящегося у одного из опсосов большой тройки. Все проблемы там из-за некачественной разработки отечественного девелопера, никак не из-за реляционных баз.
Чтобы вы поняли, что СУБД — это не бижутерия. Их «по моде» не пишут. Их вынуждены писать под реальные задачи, которые не получается решить доступными на тот момент средствами…

Речь вовсе не про создание новой БД. Речь про использование инструментов к месту. Вы зачем-то прокляли все реляционки, а оракл еще и клеймили. Возвели в ранг панацеи NoSQL. Аргументов конкретных при этом не привели. Сплошная демагогия.
Перечитайте еще раз, pls… Говорил о лукавстве Видениуса. И уж точно не проклинал и не клеймил, как вы пишите, RDBMS. Свои задачи RDBMS решают, и решают неплохо… И будут еще долго решать.
Классический Oracle — это НЕ BigData. В него можно положить сотни миллиардов записей в каждую табличку, сделать много таких табличек, делать join на них и всё будет работать. Но сотню терабайт данных туда никто не запихивает, и никаких map-reduce не запускает.

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

А разве должны быть проблемы?
100млрд записей по 32 байта вполне умещаются на один «честный» 4Тб HDD.

В своё время на Caché делал тесты на 500млн записей (сколько позволил мой HDD) с bitmap-индексами. Скорость была вполне приемлемой.

Если не секрет: зачем хранить 100млрд на одной машине, а не раскидать по нескольким?
Зачем покупать много машин и воротить логику шардирования, когда можно хранить всё на одной машине?
У NoSQL проблему обычно вызывает то, что потребление памяти линейно зависит от количества ключей.
Зачем покупать много машин и воротить логику шардирования, когда можно хранить всё на одной машине?
  1. одна мощная машина как правило сто́ит дороже нескольких попроще
  2. размазывание данных как правило приводит к увеличению скорости вследствие распараллелизации запроса
  3. надёжность (помните про яйца и корзину?)
  4. применительно к Caché логика шардирования задаётся администратором прозрачно для приложения
У NoSQL проблему обычно вызывает то, что потребление памяти линейно зависит от количества ключей.
В СУБД Caché сколько выделите памяти, столько и будет использовать.
Данные хранятся на диске довольно компактно, индексы тоже, особенно bitmap.
Ок, сколько машин и какой конфигурации необходимо для хранения 100 миллиардов строк/объектов, с парой индексов? Размер объекта пусть будет 200 байт.
Подсчитаем:
100000000000*200/1024/1024/1024/1024 ~ 19 Тб (без учёта индексов, так как их размер не указан)

Вы задаёте вопрос, не указав никаких параметров железа. Сервера ведь разные бывают и системы хранения тоже.

Кроме хранения данных Вам, наверное, потом понадобится и поиск по ним?
Здесь тоже непонятно: какие данные, какие запросы, какие максимально допустимые лимиты времени выполнения на конкретный запрос.
От этого и нужно отталкиваться.
Давайте я попробую узнать реальные цифры, потому что придуманные не особо интересны в контексте сравнения с реальным ораклом.
Читайте внимательней, pls. Не перевирайте мои слова… Oracle — это субд. А BigData — это большие объемы данных, и подходы к их обработке.
И что NoSQL это адекватная замена Oracle, я никогда не говорил. Я говорил о том. что есть ряд значимых задач, где реляционные базы перестали справляться со своей задачей, и именно поэтому появились NoSQL-решения…

NoSQL — это не мода, а назревшая потребность. Видениус неявно это признает., но пытается делать хорошую мину при плохой игре…
Цитата из вашего поста:
Посмотрите на типичного представителя RDBMS в Big Data — Oracle.

Или вы что под этим имели в виду?

BigData — это действительно подход к обработке и хранению, а именно — горизонтальное масштабирование, map-reduce. И для работы с такими задачами появились решения — Google Bigtable, Hadoop+HDFS+HBase. Но они никак не подходят для работы обычных сайтов, для них выдвигаются совершенно другие требования.

В то, что у обычного сайта есть Bigdata — простите, слабо верится. Ну какие нафиг большие данные у того же хабра?

И, кстати, прочитайте в интернете, что такое execution plan cache.
Я имел ввиду, что до NoSQL эпохи считалось непреложными фактом, что для хранения и обработки больших объемов нужен Оracle и майнфреймы. Конкурентами были IBM AS/400 c их DB2. И стоило это очень большие деньги…

Сейчас многие задачи BigData решаются NoSQL решениями на стандартных, я бы даже сказал, бюджетных серверах, за совершенно несравнимые деньги.

Нadoop используется в очень приличных поисковых движках cайтов solr и elasticsearch. Не bigdata, но в этом качестве он очень эффективен. Для полнотекстового поиска MySQL адекватно работает только с помощью sphinx.

Мне не надо читать по execution plan cache. CУБД это моя основная специальность… Хотя мне тут ниже уже дали пару ссылок про то как правильно писать запросы, чтобы в этот кэш попадать. Видимо полагают, что я должен ознакомить с этим пользователей, прежде чем они ведут поисковый запрос… ))
Вы правы, только вот стек Hadoop+HDFS+HBase — это совсем не конкурент для MySQL. Та же самая Mongo в абсолютном большинстве случаев не решает никаких проблем, которые невозможно решить с помощью MySQL.

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

MongoDB это не модно, это удобно… Вы похоже просто не знаете какие проблемы решает MongoDB.

MySQL в абсолютном большинстве случаев не решает никаких проблем, которые невозможно решить с помощью, программы написанной на С. Но все почему-то пользуются MySQL. Мода, наверное…
Вы сами написали слова MariaDB, NoSQL и BigData рядом.

Дальше. ваша цитата:
NoSQL — это не мода, в hardcore IT нет понятия гламура. Это способ решения проблем, которые оказалось невозможным решить с помощью реляционных CУБД с вменяемыми затратами ресурсов.

Пусть будет какой нибудь форум. Какие проблемы есть у MySQL и как эти проблемы решил Mongo? не надо будет думать про таблички?

Есть одна контора под Денвером, SolidFire называется, занимаются созданием аппаратных систем-хранилищ данных с SSD. Говорят, что очень любят пользователей MongoDB, потому что они в какой-то момент понимают, что на обычных дисках их база уже неработает. Можно ли это назвать вменяемой затратой ресурсов?
У MySQL есть проблемы с горизонтальным масштабированием. У Mongo таких проблем нет, т. к. она изначально на это рассчитана.
BigData я писал рядом со словом Oracle.

Форум?! 0_о Видимо тривиальней задачу вы сходу придумать не получилось, да? Достойный выбор задачи…

Возьмите лучше интернет-магазин для разнородных товаров. К тому моменту, когда вы закончите проектировать схему базы данных для MySQL, я c помощью mongodb запущу магазин в продакшн…
У MySQL нет никаких проблем в этой задаче. Просто Mongo для разработки в разы быстрее…

Говорят?! 0_о Вы случаем не из Одессы? Я думал это чисто одесский прикол:

— Знаешь, Шаляпин-то, оказывается так себе поёт…
— Ты что, ходил на концерт Шаляпина?
— Да ну… Я что дурак, зря деньги тратить. Мне Моня вчера напел…

В общем я закрываю эту тему. А то вы мне уже начали байки травить и приписывать то, что я не говорил…
Mongo иногда для разработки в разы быстрее. А ещё mongo иногда ломается в продакшене, когда делает перевыборы мастера под большой нагрузкой. И иногда при перевыборах мастера теряет данные. А интернет-магазинов с MySQL в качестве базы, на сколько я знаю, довольно много. Может быть, не так уж всё и плохо с разнородными товарами? Кстати, быстрее будет работать на mongo или на MySQL и почему?

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

Среди NoSQL есть не только простые key-value хранилища, а и такие продвинутые как MongoDB, в которой кроме обычных индексов есть и map/reduce, gridfs, причём хранить в документе можно и массив значений (и искать по нему), что позволяет ещё меньше связей в структуре данных городить. Вместо текстовых SQL запросов делаешь точно такие же, но через ассоциативные массивы, и не нужно городить костыли в виде ORM, да и в JavaScript консоли работать с данными не менее удобно, чем в SQL консоли, разве что только возможностей больше.

От SQL уже вполне можно начать избавляться даже в реляционных базах данных, или хотя бы предложить альтернативу ему, как дополнение, которое со временем станет основным инструментом.
> Если хранишь документ целиком, то и собирать его потом из множества кусков не потребуется.

Денормализация может очень даже аукнуться и усложнить поддержку. Забивать на схему не стоит даже несмотря на то, что ДОБД позволяют это делать.

> и не нужно городить костыли в виде ORM

Зато приходится городить костыли в виде ODM. Причем те ODM, которые я видел для mongo (например mongoose для node.js) гораздо более сырые и менее функциональные чем ORM для mysql, (doctrine2 например).
Всё когда-то было сырым и не функциональным, о чём даже говорит само название — doctrine2.
Может аукнуться, а может и не аукнуться. На то и голова разработчику. При должных «талантах» заставить тормозить можно любую базу данных.

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

Сейчас другая ситуация. Лишние join'ы в RDBMS это потеря времени, которое является критическим параметром при обработке big data. Особенно в вебе, где тормозной сайт- это потеря клиентов и, соответственно, доходов…
а чем не устраивает ненормализация в RDBMS, раз мы говорим о Big Data? Тот же MySQL может in-memory tables, а Oracle (оло-ло!) нет. Выйгрыш есть, если база помещается в ОЗУ, но какая же это тогда к черту Big Data?
Может быть несколько тысяч серверов, например, у каждого будет по куску данных, помещающемуся в оперативку — сколько там сейчас можно в недорогой сервер воткнуть памяти, 96Гб, 128Гб, больше?
да, такой вариант действительно кажется реалистичным.
только непонятно, насколько надежно всё это в плане распределенных транзакций.
А никто про согласованность не говорит, на ряде задач этим можно пожертвовать в угоду доступности и легкости масштабирования. Понятно, что где-нибудь в банковском секторе это, возможно, не будет работать, но есть много других проектов, с другими требованиями (особенно учитывая стоимость решения по сравнению с аналогичным на традиционной RDBMS).
Если ничего не путаю в описаниях — сам NoSQL отлично работает в банковском секторе вот www.fisglobal.com/products-technologyplatforms-gtm.
Profile deployed on GT.M supports tens of millions of accounts at hundreds of institutions around the world, ranging from de novo startups to top-tier global banks

Ну, если внимательно прочитать комментарий, то станет понятно, что в нем не утверждается, что NoSQL-решения абсолютно неприменимы в банковском секторе. Комментарий вообще про другое.
Так я и не писал что всё неверно. Я указал что каким-то образом NoSQL (и кажется есятки лет) работает в банковском секторе, значит есть варианты решения проблемы.
Банковский сектор большой и толстый, там на кучу технологий найдутся задачи :)
У меня складывает ощущение, что NoSQL чуть ли ни везде готовы продвинуть, и тут я соглашусь с главным героем статьи и считаю, что это далеко не всегда оправданно.
Именно, только и про SQL и про РСУБД тоже самое верно. Поймите меня правильно, NoSQL сейчас продвигается так же глупо и неверно как раньше продвигались РСУБД. Но это не делает эти технологии ни асболютно плохими, ни абсолютно хорошими.
приятно придти к консенсусу :)
Неустраивает SQL'ем. Это интерпретируемый язык программирования типа python и ruby, со всеми вытекающими отсюда последствиями связанными с производительностью…
В БД сильно оптимизированы эти вещи. Есть возможность сделать хранимые процедуры, тогда компиляция гарантированно идёт один раз. А каким образом NoSQL избавляет от парсинга, если ты ищешь запись с определенным атрибутом?
Да, в РСУБД выжимали водку из дохлого кота, как могли… В типичных NoSQL запрос к это вызов библиотечной функции со значениями полей в качестве параметров.

Запрос же к РСУБД это конкатенация строк для формирования строки SQL-запроса в приложении, который потом в базе будет обратно разбиваться, проверяться и т.д. и т.п…

В большинстве случаев это не проблема, но иногда…
Мне кажется это сомнительным плюсом(?), разбор запроса занимает мизерное время по сравнению с выполнением подавлящего большинства запросов. Сразу вспоминаются холивары по поводу print vs echo в PHP :) И имхо это уж точно не тянет на киллер-фичу.
И да пруф этого не требую ибо сейчас сам не готов предоставить ответный по RDBMS
парсинг, в общем, да — мизер. А вот оптимизатор, это уже не такая безобидная штука…

В свое время писал диплом по ациклическим графам и построению оптимальных цепочек join'ов, поэтому знаю о чем говорю…
Оптимизатор же не просто так появился в БД :)
И нужен он больше для толстым запросам, а не выборке из 2х таблиц.
У нас например с переходом с 10го на 11.2 Оракл многие оптимизации свелись к удалении хинтов :)
Меня больше в дискуссии интересует вопрос, чем лучше NoSQL по сравнению в денормализованной классической БД.
А то что запрос с десятком join'ов медленней просто выборки из хранилища в ОЗУ и так всем очевидно.

Какой конкретно NoSQL? Их много разных ;) Это не модель данных, а общее описание групп баз данных, которые «не реляционные».

В общем для большинства верно:
1. Schemaless для тех задач, где это важно.
2. Оптимизированность в первую очередь под доступность, а не под целостность.
3. Легковесность/дешевизна.
Очень напоминает memcached с небольшой самостоятельностью, а-ля, прочитать при старте из БД, то что будет раздавать.
Лишние join'ы в RDBMS это потеря времени, которое является критическим параметром при обработке big data


Это очень похоже на то, что «обработка» сводится к выборке по ключу заранее подготовленных данных под запросы с заранее известными характеристиками. В мире SQL это называется materialized views.

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

«лишние джойны» разумеется медленнее, чем запрос без джойнов. Вот только многие запросы с джойнами не имеют аналогов запросов без джойнов. И в мире БигДата вдруг становится очевидным, что бывает проще сделать джойн, чем перелопачивать огромный массив данных ради выполнения запроса может оказаться банально долго — значительно дольше, чем запрос с джойнами.
Ребята, почитайте историю развития СУБД.

Фиксированная структура таблицы нужна была для того, чтобы можно было точно вычислить в каком кластере на диске находится нужная запись. Это обеспечивало более-менее приемлемую скорость доступа к данным. И вся наука декомпозиции заключалась в сведении нефиксированной структуры к фиксированными таблицам и снижением избыточности базы данных, снижая тем самым стоимость хранения…
Заметьте, снижение избыточности привело и к увеличению целостности данных за счёт нормализации.
Тот же Кодд писал о том, нормализация есть просто попытка формализовать здравый смысл.
И да, нормализованные данные удобней обрабатывать.
А денормализовать можно всегда успеть.
Удобнее обрабатывать данные, которые удобно представлены. А нормализация…

Возмите структуру базы данных более-менее универсального интернет-магазина, позволяющего хранить разнородные товары в реляционной базе. Например, Spree, на рельсах.
Данные там нормализованы? Нормализованы… Даже более чем… Но назвать это хранение удобным для обработки и поиска, можно только в горячечном бреду или если не видел лучшего…
Я поэтому Кодда и приплёл. Здравый смысл должен рулить. А подобные магазины конечно универсальны, но за это, как вы правильно заметили, приходится платить производительностью.
Но сравнивать NoSQL с подобными монстрами, это уже крайность.
>>Если хранишь документ целиком, то и собирать его потом из множества кусков не потребуется.
как это реализуется для ссылочных данных? Например, если есть заказ покупателя, в нем табличная часть. В табличной части забита номенклатура. При изменении номенклатуры должны меняться наименования в заказе клиента
Вот тут как раз наоборот. Если по Бухгалтерским документам отгрузили «Шпунтик ШП-10» он и должен остаться им а не стать после например приведения наименований к единому виду «ШП010 Шпунтик».
И уж тем болнн это казается переименований Банков, Контрагентов и т.п.
А теперь вам надо построить отчет по продажам номенклатуры за квартал. И если одна позиция в разных документах будет фигурировать по-разному — вы будете вспоминать проектировщика вашего магазина добрыми-добрыми словами.

Так что в табличную часть заказа должен попадать именно уникальный идентификатор номенклатуры. А это уже связи и реляционная БД.
Выше уже писали, что сложные отчеты — это НЕ область применения NoSQL.
Сложные отчеты? Да это рядовая регулярная операция для любого интернет-магазина! Это практические реалии веб-разработки, тут даже и речи нет о каком бы то ни было BI.
А кто вам сказал, что уникальный идентификатор номенклатуры обязательно в заказ не попадает? Пусть попадает, да, это некоторая денормализация.

А теперь расскажите мне, что делать если товары в вашем интернет-магазине имеют неоднородный атрибутный состав?
Смотря, насколько неоднородный.
Можно заводить аналитики, можно разбить товары по типам и хранить их в разных таблицах, а можно просто использовать отдельную таблицу (таблицы) для атрибутов.
Ну, а можно и просто в текстовое/бинарное поле запихивать.
В разных таблицах хранить весело, особенно при добавлении нового типа.
Отдельная таблица с атрибутами. Ага. Будет огромная таблица не поддающаяся фильтрации
Текстовое(бинарное) поле. Опять же фильтрация, кроме того — это по сути и будет nosql.
Почему не поддающаяся фильтрации?
Тип продукта — связь с типом атрибутов (схема) — набор значений в разных либо одной таблицах.
Чем плохо бинарное поле, если нужно в БД по каким-то (надеюсь, объективным) причинам хранить это вид информации?
Ага, а теперь отмасштабируйте это горизонтально.
Партиции придумали трусы?
Будете делать джойны по партициям?
Речь о сферических джойнах в вакууме? Всё же зависит от сценариев использования.
Вам нужны все атрибуты сразу за всю жизнь БД (при партицировании по дате).
Мы вроде еще говорим про интернет-магазин и товары?
Имхо, партиционировать по датам — плохая идея.
Я имел ввиду более общую задачу хранения разных тиgов объектов с набором атрибутов. Принцип партицирование зависит опять-таки от сценария использования.
А для интернет магазина big data — это сколько типов товаров/товаров? И я так и не понял, чем здесь удобней NoSQL для случая, когда БД не влезает в ОЗУ.
Примерно сотня типов и 2кк товаров, например.

Удобнее тем, что можно сложить данные о товаре в одну запись и выбирать по партициям тем же map/reduce.
Таблица с полями а-ля num_val, str_val, date_val и индексом по product_id, опциональная таблица со связкой типа продукта и возможными атрибутами.
Выборка по product_att where product_id = 123. Чем это хуже NoSQL?
Это прекрасно ровно до тех пор пока вы не начинаете делать партиционирование и тот же фасетный поиск по этим партициям.

Пример:
Я хочу все товары, у которых есть атрибут «цвет» равный «красный».
Вы у себя подобные структуры партицируем по дате. Но у нас хранится несколько другая информация. Если я правильно понимаю специфику интернет магазина в данном контексте, то есть товар, который продавался и есть тот, что продается сейчас.
И мне кажется логичным хранить «под рукой» то, что нужен сейчас (возвращаясь к партицированию по дате). Фасетный поиск в данном случае — это исторический анализ?
И это частый сценарий?
Ох, проще показать чем объяснить ;)



Сценарий чуть ли не основной для любого большого каталога.
всё равно я никак не пойму, чем тут плох тот же MySQL?
ну много атрибутов и что? никак не могу уловить профит, а в скайпе апрува я так и не получил
поэтому я и упомянул чуть выше опциональную таблицу с типами атрибутов/привязкой к типу товара. По-моему, select * from product_att t where t.att_type_id = COLOR_TYPE_ID and t.str_val = 'red' при наличие банального индекса будет всяко быстрее full scan'a по нетипизированному NoSQL хранилищу. А без индекса будет ровно то же самое.
krylatij
Фасетная навигация иногда делается через теги, которые хранятся в массивах объектов — функционал которого вроде как нет в SQL, я думаю на это хотел указать retran.
К примеру, более понятный вариант — как на SQL выбрать все объекты в которых есть все 3 тега [«красный», «круглый», «большой»]
А как эти теги реализованы в NoSQL? Чудес не бывает.
Например массивом:
{ tags:['one', 'two', 'three'] }

Получить по 2-м тегам можно так:
db.docs.find({ tags:{ $all:['one', 'two'] } })


Под mysql вроде как нет вменяемого решения, поэтому используют sphinx или что-то другое.
Я не про синтаксис, а о реализации на уровне движка. Что волшебное делают создатели NoSQL решений, чего не могут сделать создатели классических БД?
WHERE t.str_val IN ('красный','круглый','большой')
Не выполняет условие выше.
select count(*) fieldcount,ItemId,GROUP_CONCAT(",",FieldValue) FROM catalog_fields WHERE FieldValue IN ('красный','круглый','большой') GROUP BY ItemId HAVING fieldcount>=3
Получает все Id товаров, у которых есть именно эти 3 свойства. Проверено, работает.
Для приближения к реальному запросу нужно ещё добавить сортировку товара что бы выдать первые N объектов на (первую) страницу.

Подобный запрос я пробовал на миллионе объектов, тогда mysql «уходил в спячку» — т.е. не решил задачу.
Подобный запрос я пробовал на миллионе объектов, тогда mysql «уходил в спячку» — т.е. не решил задачу.
Какой-то такой?
SELECT * FROM items JOIN
(SELECT COUNT(*) fieldcount, ItemId, GROUP_CONCAT(",",FieldValue)
 FROM catalog_fields
 WHERE FieldValue IN ('красный','круглый','большой')
 GROUP BY ItemId
 HAVING fieldcount>=3) AS ids
ON items.id = ids.ItemId
ORDER BY items.coolness
LIMIT n
Какой-то такой?

Да.
Видите сколько действий нужно сделать?
Фильтр, группировка, сложение в строку (возможно лишнее), опять фильтруем, потом джойним и сортируем, некоторые могут ускориться индексами.

Теперь сравните с вариантом для MongoDB:
db.docs.find({ tags:{ $all:['one', 'two'] } }).sort({ name:1 }).limit(n)

Запрос проще и понятней, выборка делается «одним проходом» по индексу и навскидку будет работать в сотни (а может и тысячи) раз быстрее чем вариант для MySQL.

А это только одна из фич, поэтому большая шумиха вокруг MongoDB и NoSQL, и маркетинг тут не причем хоть он и помогает в распространении.
А какого типа индекс строится по полям типа набора тегов?
Кстати, в SQL можно и ещё несколькими вариантами это сделать, и без группировок — например, вложенными подзапросами. Мне просто лень было самому писать. Отработают по индексам мгновенно, потому что все поля строго типизированные.
Я тоже пробовал разные варианты — все медленные (поднимал темы на форумах), давайте на Ваш «мгновенный» посмотрим.
Пардон, с «мгновенным» я погорячился, возможно — не проверял «на живом».
Можно делать через JOINы:
SELECT c1.itemId FROM catalog_fields AS c1
JOIN catalog_fields as c2
JOIN catalog_fields as c3
ON c1.fieldValue = 'красный'
AND c1.itemId = c2.itemId
AND c2.fieldValue = 'круглый'
AND c2.itemId = c3.itemId
AND c3.fieldValue = 'большой'

И через подзапросы:
SELECT itemId FROM catalog_fields
WHERE itemId IN
 (SELECT itemId FROM catalog_fields WHERE itemId IN
   (SELECT itemId FROM catalog_fields WHERE fieldValue = 'красный')
 AND fieldValue = 'круглый')
AND fieldValue = 'большой'
Выборка исключительно по индексируемым полям, так что должно быстро отработать.
Поля со списками тегов же не индексируются, я правильно понял отсутствие ответа на мой вопрос выше?
Поля со списками тегов же не индексируются, я правильно понял отсутствие ответа на мой вопрос выше?


Ответ я написал выше:
выборка делается «одним проходом» по индексу


Индексы можно создавать на любые поля, документы, суб-документы, так же можно делать составные индексы и ещё много разных фич с индексами. Например (на сколько я знаю) в mysql нет аналогов Sparse индексов, TTL индексов, Geo-индексов.
Ответ я написал выше:
Сразу после
некоторые могут ускориться индексами.
я его, видимо, как-то не так воспринял, пардон
функционал которого вроде как нет в SQL


Не буду за все RDBMS, но в том же Postgres есть составные типы, массивы и ассоциативные массивы (hstore), что позволяет гибко управлять структурой данных или вообще хранить часть данных без схемы. При этом есть операции над множествами для сложных запросов и они поддерживаются индексами. При этом постгрес движется в очень «вкусном» направлении — бессхемные данные получают возможность накладывать ограничения целостности.

как на SQL выбрать все объекты в которых есть все 3 тега [«красный», «круглый», «большой»]

Соответственно пример запроса:

SELECT 'красный=>1,круглый=>1,большой=>1,тяжёлый=>1'::hstore ?& ARRAY['красный','круглый','большой']

>>> true

Вы правы, но…
Во первых, Postgres неимоверно мощная вещь которая может вообще всё, и считается, вроде как, постреляционной.

А во вторых сам тип Array, типы XML и прочие хотя и применяются в РСУБД но не могут считаться допустимыми для реляционной моделиданных.
Возможно, спорить не буду — постгрес хороший гибрид. Интересно, как с подобными возможностями обстоят дела в SQL Server и Oracle — там не движутся в сторону компромиссов?
Если я правильно понимаю задачу, то нет особых проблем, если принять, что отчеты могут делаться не в БД. Можно сделать вьюху продаж позиций за месяц (год/месяц, id позиции, наименование, продано за месяц), остается только фильтровать по месяцам (выборка из вьюхи по диапазону ключей), и самому сделать свертку по id позиции. Несколько сложнее, конечно, чем в реляционных БД, но не критично.
Нет! ID товара будет один и он даст текущее название справочника.
А разве БД не придется для отображения текущего названия справочника использовать данные из другой таблицы, тем самым совершая действия, аналогичные выборке из двух таблиц в реляционных БД?
Проектируйте базу данных должным образом. Введите дополнительный номенклатурный код. Можете сделать отдельный номенклатурный справочник. Вариантов масса… Вне зависимости от типа применяемой СУБД, без мозгов разработчику не обойтись…
это оазве не реализуется в RDBMS с гораздо меньшим количеством побочных эффектов? в чём плюс-то? тот же MySQL можно использовать как NoSQL, а вот наоборот никак.
Ссылочные данные можно в виде ссылок и хранить, либо будет копия прямо в документе, и тогда нужно будет озаботиться об обновлении данных самому. Причём, как уже сказали выше, зачастую это не требуется, а наоборот, нужно хранить данные в неизменном виде, в каком они были в момент записи. Что в реляционных базах приводит к той же самой денормализации.

Чаще всего требуется доставать данные, чем модифицировать их, вот и грузят эти JOIN-ы процессоры почём зазря, сайт с 1000 пользователями еле ворочается на довольно мощном сервере.
К сожалению, код, обновляющий связанные сущности, пишут не идеальные программисты. И в итоге через год-полтора в базе проекта появляются всякие мистические сущности вроде заказов без клиента или пустых ссылок внутри документа.
Не требуется обновлять денормализированные данные только в случаях архивации, логов, и истории (заказов).
Сначала не было sql, была возможность хранить записи, создавать индексы и самим по ним программно проходить.
Потом появился sql. Теперь не нужно писать программу, чтобы собрать отчет.
Сейчас появились nosql базы. Для того, чтобы состряпать отчет нужно писать код.
… какой же будет следующий шаг? noSQL SQL? ))
Активное развитие SQL как языка программирования (и не надо говорить, что SQL-запросы — это не код, это вполне себе код, на языке, имеющем функциональную природу) было тем что во времена двухзвенных архитектур СУБД использовали еще и как сервера приложений.
я просто хотел дискуссию подвести к реализовавшейся спиральной модели эволюции:
[structured data] — [sql] — [no sql] — ?
[local apps] — [remote terminal apps] — [desktop apps] — [remote web apps] — ?
Некоторым шагом вперёд может стать бинарный протокол SQL.
Например вида c_SELECT.c_ALL.c_FROM.«tablename».c_WHERE.«Id».EQ.(int)5
где c_*** — константы языка SQL. Это означает снижение расходов на парсинг, анализ опечаток на уровне компиляции (неправильная SQL константа с опечаткой будет выявлена сразу), передача цифровых данных не ввиде строки, а именно в виде Int или Int[], отсутствие сериализации для чисел.
Как раз это делают новые HandlerSocket и Memcached interface в mysql5.6, но они заставляют учить новый синтаксис вместо привычного SQL. И вообще с изобретением HandlerSocket (который всё же б ыстрее memcached, но есть только в Percona) вопрос SQL/NoSQL вроде закрыт, к данным обращаться можно и так и так.
Мне кажется, проблема спора SQL vs NoSQL в желании людей найти серебряную пулю, которую можно просто поставить и просто с ней работать, по меньшей мере в их случае. Понятно, что для ненагруженного сайта/приложения важна скорее не производительность, а latency и удобство разработки. Но когда перестаёт хватать ресурсов выделенного под БД сервера, меняется проблематика: сразу становится важна ресурсоёмкость запросов к отдельным видам данных и удобство разбиения базы на несколько серверов (альтернатива — расширять сервер — заметно дороже, т.к. стоимость сильно растёт, непропорционально ресурсоёмкости). Очевидно, что для небольшого объёма часто меняющихся и читающихся данных NoSQL — хорошее и удобное решение, а для жирных данных, только малая часть из которых прямо сейчас читается приложением — удобнее SQL, из-за лучше проработанных файловых индексов и прочих нюансов работы с файлами.
Не, ну а что вы еще ожидали от Монти?
И мне кажется все эти скул — носкул просто возня. Большинство из тех, кто ругает носкул чаще всего даже не представляют, что это такое. Таким гражданам я просто посоветую взять и поюзать пресловутую монгу — она проста и стабильна. Есть конечно и те, кто ругают носкул вполне по обоснованным причинам, но дело в том, что не все проекты будут вырываться за рамки одного сервера.
Для всяких мелких проектов я сейчас начинаю отказываться от использования того же мускула по той лишь причине, что он мне не удобен на этапе разработки. Если хоть один из проектов будет иметь популярность, и окажется, что без РСУБД никак, то можно будет это переписать, благо же все MVC. А тратить время на инженеринг того, в чем я не силен мне не интересно. Мне интересно делать приложения, делать их быстро и не париться о технологическом аспекте хранения данных.
Поддерживаю, более 2-х лет назад перешел на MongoDB для web разработки, к более-менее большим проектам подключаю Sphinx по необходимости.
За это время у меня не было необходимости использовать SQL-базы.
Некоторые друзья попробовав MongoDB остались с ней.
А мне наоборот проще использовать mysql/postgres для мелких проектов т.к. я работаю с ними через ORM, я уже привык и мне это очень удобно делать + из коробки я получаю контроль целостности данных.

Монгу юзаю в парсерах сайтов, очень удобно работать с записями pymongo как со словарями.
Проблема в том что NoSQL/SQL сравнивают по исспользованию реляционной алгебры.
В NoSQL ссылочная целостность отдается на откуп уровню приложения в угоду маштабируемости и доступности. Те же самые атрибуты кортежи остаются. Никуда реляционная алгебра не денется, просто если у вас более одной реплики данных нужно учитывать вещи что иногда данные могут быть не синхронизированы и целосность вы обрабатываете на уровня приложения. Зато вы можете получить доступность данных на уровне 1 мс(Amazon Dynamo DB).
А далее опять же читать CAP -теорему. Потому что почему-то каждый DBA/DBD мне будет молится на реляционную алгебру, которая заметим NoSQL не заменяется и никуда не пропадает, но большинство матерых DBA/DBD считают в порядке вещей не знать элементарных вещей за бортом их любимого SQL сервера. CAP теорема и NoSQL решают задачу которую обычные RDBMS не могут и не берутся решать. Как обеспечить обработку и гарантированую доступность данных при больших нагрузках, когда даже самый большой сервер не способен вытянуть вся БД сам целиком.
Для ретроградов останутся гибридные решения, например Amazon Redshift, который уже за 2-3 года начнет серйозно подрывать бизнес Oracle, HP, IBM. Им уже сложнее будет тянуть с клиентов шестизначные ценники с ежегодной «инфляцией».
InnoDB — тоже в девичестве NoSQL — Оракл к ней даже соответствующий интерфейс по итогу прикрутил.
Вы абсолютно правы, корректнее противостояние под наименованием «SQL vs NoSQL» именовать как «Реляционные против Остальных»
Я не гуру баз данных, скажу лишь, что усвоил на совём опыте. RDBMS это не только SQL, NoSQL это не только отсутствие SQL. Оба типа баз данных это также хранилищие информации, эффективность использования которого можно настраивать на уровне конфигов, выделения памяти под всякие буферы. Если в mysql и postgres я представляю примерно, как выделить память под индексы, то в mongodb с которой я также работаю, я плохо понимаю как выделяется память и как этим управлять. Возможно это недостаток опыта. Для себя я открыл, что скорость работы mysql/postgres не сильно отличается от mongodb, если использовать эти базы, как например, key/value хранилище.

С шардингом не сталкивался, возможно тут у монги жирный плюс по-сравнению с mysql/postgres.
Mysql, на сколько я знаю, умеет автоматически партиционировать таблицы.
Вот все говорят, говорят об этом NoSQL, а где вообще можно посмотреть наглядную разницу между RDBMS и NoSQL?
Просто оставлю это здесь (там в конце свое слово говорит сооснователь Couchbase — J. Chris Anderson).
По-моему, сравнивать RDBMS и NoSQL — это как сравнивать теплое с мягким. Это разного класса СУБД, которые необходимо выбирать в зависимости от поставленной задачи.
ИМХО, что касается веба, то тут структура данных достаточно проста и при этом необходим очень быстрый доступ к данным. Если у вас хороший хайлоад, то всё равно придётся в MySQL жертвовать такими вещами как целостность данных (во многих случаях это совсем не критично) и приведением к нормальным формам. Вместо этого создавать всякие сводные таблицы итд. К тому же в MySQL кеш запросов достаточно «глупый» и гораздо эффективнее кешировать данные на уровне приложения в мемкешах.
И чем больше нагрузка, тем менее пригодной становиться MySQL… забудьте про частые сложные запросы и без мемкешей вам не жить (доступ к «горячим» данным должен быть только из памяти)

Всё это как-бы намекает на то, что MySQL не лучшее решение для веба и появляются другие решения.
Есть ли данная статья на английском?
Sign up to leave a comment.