Pull to refresh

Comments 134

Спасибо за перевод! Читал в оригинале, очень понравилось, написано доступным понятным языком.
UFO just landed and posted this here
Спасибо за перевод, вот только заключение слишком субьективно.
Так что подумайте дважды, прежде чем выбирать между забагованной NoSQL и цельной реляционной БД. Не поймите неправильно, некоторые NoSQL-базы очень хороши. Но они ещё далеки от совершенства и не могут помочь в решении специфических проблем, связанных с некоторыми приложениями.
Специфические проблемы? Некоторые приложения? Лучше в заключении было бы написать: «Всему свой инструмент». Для многих задач NoSQL решения подходят лучше реляционных БД.
NoSQL лучше подходит для очень немногих задач.
Это не делает NoSQL БД «забагованными». Слишком негативный посыл у автора оригинального поста в отношении NoSQL.
Причём, если в высказывании автора поменять местами RDBMS и NoSQL, получиться тоже совершенно истинное утверждение.

Так что подумайте дважды, прежде чем выбирать между забагованной реляционной БД и цельной NoSQL. Не поймите неправильно, некоторые реляционные базы очень хороши. Но они ещё далеки от совершенства и не могут помочь в решении специфических проблем, связанных с некоторыми приложениями.
Вы из всей статьи прочитали только один абзац?
Фраза, конечно, не имеет никакого смысла. Можно вообще любые два термина из мира ПО подставить и смысл не изменится, но статья совершенно не об этом.

Кстати, есть ли о NoSQL базах такие статьи?
Мне статья как раз очень понравилась, она комплексная и полная.
Поэтому резануло глаза заключение — как-будто кто-то другой прилепил.

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

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

Проблемы у любого продукта есть. Но в случае с современными NoSQL решениями все эти проблемы довольно быстро исправляются, они более динамичны. С одной стороны это хорошо, но с точки зрения стабильности может и нет. Мы вот используем RethinkDB для нашей ММО. За время разработки парни уже не одно обновление выкатили, что не может не радовать.

Или взять тот же Riak (он у нас как бэк энд для ежа используется). Если мне память не изменяет, то те же Riot'ы для Лиги используют ежа со всё тем же Риаком. И сие дело держит миллионы юзеров.
Нагрузки тут не при чем. Почти всегда нагрузки компенсируются вливанием бабла в железо и построением кешей. Независимо от СУБД.

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

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

Сложно будет убедить гугл, что им нужно увеличить количество серверов раз в десять (от 10 тыс. до 100 тыс) чтобы использовать православные СУБД вместо NoSql. Проблема СУБД с современными большими данными оказалось в том что данных в некоторых случаях что вливание бабла в железо уже не работает никак, или же напоминает попытки носить воду в решете.

А вот надежность хранения и согласованность данных — это нельзя компенсировать добавлением железа.

Не всегда это нужно

Мало того, что нету никакого контроля целостности на прикладном уровне, так еще и резервное копирование и восстановление не всегда работает как надо.

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

Не всегда это нужно

Это гораздо чаще нужно, чем не нужно. Хотя и апологеты NoSQL пытаются убеждать в обратном.

сильно зависит от Nosql

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

Кто сказал? Большие данные давно уже рядовой инструмент многих компаний, я часто сталкивался с данными, которые в SQL модель не влезут никак.

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

Нельзя, 1) big data это давно уже не экзотика, а они в SQL не ложаться. 2) нет смысла для сборка банальной статистики посещений сайта тратить миллионы долларов на супер навороченую СУБД, когда в noSql сделать это куда быстрее, дешевле и даже надежнее (так как она не упадет от нагрузки)

Это гораздо чаще нужно, чем не нужно.

Нет. Далеко не вся информация финансовая и сверх критичная. Ну, потеряется пара просмотров и кликов в статистике сайта в миллардах показах. Нужно для этого городить огород? Нет. Очень часто при потере небольшого куска данных у 0.0001% пользователей ничего ужасного не произойдет, скажем если у кого-то пользователя на форуме сообщение не дойдет до сервера, он нажмет назад и пошлет его ещё раз или перепишет его ещё раз, это не стоит того чтобы тратить десятки тысяч $ на сервера и базы данных.

P.S. Надо ещё понимать, что качество у разных СУБД тоже разное, между Oracle и MySql две большие разницы, несколько раз были случаи когда MySql весьма серьезно глючил вплоть до отказа базы данных (особенно когда работает на пределе производительности), а Oracle и ему подобные стоят столько что просто не по карману многим организациям.
P.P.S. В целом, на каждую задачу свой инструмент и идеализировать СУБД или noSql и применять их там где не нужно — тоже не разумно.
И как в NoSQL решает вопрос биг дата? Те же структуры в профиль только зачастую с худшими планировщиками и индексами. А отмапредьюсить данные можно на любой субд было бы желание.
я часто сталкивался с данными, которые в SQL модель не влезут никак.

Можно пример? Честно, ни разу с подобным не сталкивался, поэтому интересно, какие-такие данные не могут влезть в sql. Вроде как vk, fb, twi не жаловались публично.

когда в noSql сделать это куда быстрее, дешевле и даже надежнее (так как она не упадет от нагрузки)

Бред.

В целом, на каждую задачу свой инструмент и идеализировать СУБД или noSql и применять их там где не нужно — тоже не разумно.

Согласен. Но вот в чем проблема: чаще всего sql-базы покроют функционал nosql, а наоборот — очень редко и с потерей основных плюсов (скорость, например).
Вроде как vk, fb, twi не жаловались публично.

Что значит не жаловались? Fb использует касандру, линкедИн — волдерморта, гугл — свой аналог hadoop hbase, vb — свою собственную nosql базу данных, twitter — Hbase, pig, FlockDB и касандру. Как раз, использование только sql у гигантов практически не встречается, хотя в стеке для некоторых задач sql используется, но далеко не для всех.

Но вот в чем проблема: чаще всего sql-базы покроют функционал nosql, а наоборот — очень редко и с потерей основных плюсов (скорость, например).

Странная логика, если мне нужно key-value хранилищн, хранилище отдельных json докуменов или хранить сложные графы я возьму соотвествующие nosql базы данных. Sql может заменить, но за счет производительности, места и ресурсов, что зачастую окажется не допустимым для данной задачи.

Бред.

В чем? Nosql зачастую работает намного быстрее, например скорость in-memory key-value хранилища будет намного быстрее sql, если нужно хранить именно ключ-значение и надежность не критична, соотвественно ресурсов потребуется значительно меньше.

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

Ну, например разрезы по ключевым словам, рекламным компаниям, дням, страницам, показам всей статистики крупнейшей рекламной площадки мира. Это с чем работал я.

И как в NoSQL решает вопрос биг дата? Те же структуры в профиль только зачастую с худшими планировщиками и индексами. А отмапредьюсить данные можно на любой субд было бы желание.

HDFS Hadoop'a это тоже вполне NoSQL (и всякие обертки вроде Hiv'a), отмапредьюсить это уже только результат, который, конечно, уже может быть сохранен в СУБД. А сами биг дата нельзя просто взять сохранить и обработать в СУБД, иначе это не совсем биг дата.
Что значит не жаловались?

То, что наравне с nosql используют и рсубд. Key-value имеет свою нишу, с этим я согласен. Но заявлять что данные не влезут в sql — бред.

Sql может заменить, но за счет производительности, места и ресурсов, что зачастую окажется не допустимым для данной задачи.

Ну так я это и говорил — sql покроет потребности (пусть и за счет ресурсов), а вот nosql редко сможет полноценно заменить sql.

Nosql зачастую работает намного быстрее, например скорость in-memory key-value хранилища будет намного быстрее sql, если нужно хранить именно ключ-значение и надежность не критична, соотвественно ресурсов потребуется значительно меньше.

Если не секрет, откуда такие данные? SQL разучился работать в памяти, без диска? SQL разучился работать по primary? Можно ссылку на сравнения? Не троллинг, реально интересно. По нашим тестам (а мы протестировали с десяток), nosql выигрывает только на самых простых вариантах. Чуть сложнее выборка или сложные данные для вставки (затрагивающие, по итогу, 5-6 коллекций) — nosql становится явным аутсайдером.

Ну, например разрезы по ключевым словам, рекламным компаниям, дням, страницам, показам всей статистики крупнейшей рекламной площадки мира.

Эммм… Они не «влезли» в sql? Что это значит? Место? Скорость? Плохая архитектура?

А сами биг дата нельзя просто взять сохранить и обработать в СУБД, иначе это не совсем биг дата.

С фига-ли?! о_О
Ну так я это и говорил — sql покроет потребности (пусть и за счет ресурсов), а вот nosql редко сможет полноценно заменить sql.
Графовая БД легко заменяет реляционную, но не наоборот.
Графовая БД легко заменяет реляционную, но не наоборот.

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

ЗЫ. На любой РСУБД это делается элементарно.
В любой достаточно адекватной системе есть механизм бронирования. Например, как работает заказ билетов на поезд:
1. Юзер выбирает место, оно бронируется под него на 15 минут
2. Юзер втыкает минуту, выбирает еще одно место, оно бронируется под него на 15 минут
3. У юзера остается 14 минут, чтобы успеть оплатить оба билета (или 15 минут, чтобы успеть оплатить только второй билет)
4. После оплаты юзером билеты считаются купленными юзером.
5. По истечению времени билет возвращается в свободные билеты.

Это я к тому, что мир на самом деле сложный. Я только что привнес просто дополнительной сложности, извините.

Касательно вопроса — а как таки сделать уникальность привязки места к юзеру? Я только что пошел в документацию Neo4j (бд которую я в первый раз в глаза вижу) и нашел несколько способов это сделать, помимо очевидных костылей типа двухфазного коммита.
1. Юзер выбирает место, оно бронируется под него на 15 минут
2. Юзер втыкает минуту, выбирает еще одно место, оно бронируется под него на 15 минут

И у нас будут два пользователя, которые покупают места 14 и 15, а второй покупает места 15 и 14. Упс, дедлок. Или вы заставите одно из них ждать пока 15 минут другого закончатся?
Или откатить обоих, но они попытаются повторить ту же транзакцию в том же порядке.

Это я к тому, что мир на самом деле сложный. Я только что привнес просто дополнительной сложности, извините.
Да-да, вот только в РСУБД это делается одним unique constraint.

Вы не понимаете, что только что попытались изобрести механизм блокировок, который уже есть в любой РСУБД? При этом надо будет написать немало кода чтобы реализовать ваш сценарий.

Я только что пошел в документацию Neo4j
Ссылки в студию.
Или вы заставите одно из них ждать пока 15 минут другого закончатся?

Да, в этом смысл бронирования. В том, что другой юзер вообще не увидит забронированный билет. А юзер, который забронировал билет — будет видеть время, которое у него осталось для совершения оплаты билетов. Это UX-требование, это то как должна работать система уважающая пользователя

Вы не понимаете, что только что попытались изобрести механизм блокировок, который уже есть в любой РСУБД? При этом надо будет написать немало кода чтобы реализовать ваш сценарий.

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

Ссылки в студию.

neo4j.com/docs/stable/query-create-unique.html. Пойдет?
Все понятно. Когда не достигли желаемого сделали вид, что желали достигнутого.
Эм? Если ты хочешь исключить бронирование билета из процесса покупки, то ничего страшного не произойдет. Create Unique решит проблему одновременной покупки билета. Просто твоя система будет говном с точки зрения UX, но это же ничего страшного, да? Зато ты не будешь изобретать блокировки, которые уже релизованы в твоей РСУБД.

Не отмазывайтесь, отвечайте на вопрос, как вы будете обрабатывать ситуацию возможности открытия двумя разными юзера одной сущности на редактирование? Что вы будете делать, чтобы не изобретать блокировки и mvcc, кроме как положите на эту ситуацию?
Бронировать ведь тоже нужно атомарно, так что этот UX никак не влияет на то как мы работаем с базой данных.
Ну, да, бронировать тоже нужно атомарно. Просто прикол в том, что в итоге атомарность обеспечивается и приложением, и сервером базы данных. Получается некоторое дублирование.
UX на базу никак не завязан, так что кидаться такими заявлениями бессмысленно.

Если исключить требования уникальности, то будут проданы два билета на одно место и систему быстренько поменяют.

Не отмазывайтесь, отвечайте на вопрос, как вы будете обрабатывать ситуацию возможности открытия двумя разными юзера одной сущности на редактирование?
С точки зрения UX вообще нельзя ничего блокировать. Поэтому оптимистичная блокировка (легковесный аналог MVCC) + автомерж изменений при конфликтах. Но к тому что делается в базе не имеет никакого отношения.
Если исключить требования уникальности, то будут проданы два билета на одно место и систему быстренько поменяют

Не надо исключать требование уникальности, я говорил про исключение процесса бронирования.

С точки зрения UX вообще нельзя ничего блокировать. Поэтому оптимистичная блокировка (легковесный аналог MVCC) + автомерж изменений при конфликтах. Но к тому что делается в базе не имеет никакого отношения.

По-моему процесс мерджа подразумевает три источника данных: base, this, remote. А это значит, что вам нужно хранить историю изменений. А это дублирование механизмов, заложенных в бд, нет?.. Кроме того, автомердж без подтверждения юзера — плохое решение с точки зрения UX.
create class Theater
create class Person
create class Ticket

create property Ticket.theater link Theater
create property Ticket.person link Person
create property Ticket.place integer
create property Ticket.timeslot short

create index Ticket.unique on Ticket (
    theater , 
    person , 
    place , 
    timeslot
) unique

create property Theater.tickets linkset Ticket
create property Person.tickets linkset Ticket

insert into Theater content {}
insert into Person content {}

begin
    let theater = select from Theater limit 1
    let person = select from Person limit 1

    let ticket = insert into Ticket set
        theater = $theater,
        person = $person,
        place = 1,
        timeslot = 1

    update $theater add tickets = ticket
    update $person add tickets = ticket
end
create index Ticket.unique on Ticket ( theater , person , place , timeslot ) unique

Упс, транзакции появились.
Или блокировки, или MVCC, другого пока не придумали.

Или есть магические способы обеспечения уникальности?
Да, там есть и транзакции, и блокировки, и mvcc, а что?
То что в этой базе используются те же алгоритмы, что и в РСУБД. Тогда чем графовая лучше? и почему они может заменить реляционную, а наоборот нет? Я вижу в лучшем случае паритет, а при детальном рассмотрении окажется куча подводных камней в графовой базе.
> То что в этой базе используются те же алгоритмы, что и в РСУБД.
Я вам больше скажу — эти алгоритмы используются далеко не только в базах данных.

> Тогда чем графовая лучше?
Тем, что хранит прямые ссылки на связанные записи, что позволяет получать их за константное время, не делая джойнов и не держа кучу индексов для их ускорения.

> и почему они может заменить реляционную, а наоборот нет?
Потому, что работа с графами и даже с деревьями в рсубд — это треш и угар. Тысячи статей по рсубд повествуют нам о таблицах смежностей, материализованных путях, вложенных множествах. Только вот в гсудб это всё не нужно. А таблицы с отношениями — это всего-лишь частный случай графа.

> Я вижу в лучшем случае паритет, а при детальном рассмотрении окажется куча подводных камней в графовой базе.
Попробуйте, будет интересно про них почитать :-)
Я вам больше скажу — эти алгоритмы используются далеко не только в базах данных.
И в чем же тогда преимущества?

Тем, что хранит прямые ссылки на связанные записи, что позволяет получать их за константное время, не делая джойнов и не держа кучу индексов для их ускорения.
Не очень понимаю как это делается.
Вот у нас есть узел графа, сохраненный на диске. «Прямая ссылка» ссылка на него — смещение в файле данных.
Мы в этот узел добавляем ссылки на другие узлы и место для хранения узла у нас кончается, надо узел переместить куданить. Смещение поменялось. Что происходит с прямыми ссылками на этот узел?

Или все хранится тупо в памяти? Тогда чем это лучше inmemory и хеш-индексов? Они тоже O(1).

Потому, что работа с графами и даже с деревьями в рсубд — это треш и угар.
С деревьями как раз проблем нет. Ordpath давно изобрели. Лет 7 назад точно. С графами — да, под них не оптимизируется. Но на практике я целый один раз за 10 лет делал транзитивное замыкание в РСУБД.
И в чем же тогда преимущества?
В архитектуре, а не алгоритмах.

Что происходит с прямыми ссылками на этот узел
Я не вдавался в подробности. Скорее всего там связный список просто.

Или все хранится тупо в памяти?
Можно и в памяти хранить.

Тогда чем это лучше хеш-индексов? Они тоже O(1).
Да хотя бы даже тем, что это не один индекс на всю таблицу, в много маленьких в каждом linkset-свойстве.

С деревьями как раз проблем нет. Ordpath давно изобрели. Лет 7 назад точно.
Это и есть «материализованный путь». С селектами по нему проблем и правда нет. А вот переносы поддеревьев требуют изменения всех вложенных узлов.

Но на практике я целый один раз за 10 лет делал транзитивное замыкание в РСУБД.
Конечно, ведь в рсудб с этим всё сложно и приходится придумывать костыли типа ordpath и компании :-)
В архитектуре, а не алгоритмах.

Это слишком непонятно, чтобы использовать как аргумент.

Я не вдавался в подробности. Скорее всего там связный список просто.

Что является ссылкой если данные хранятся на диске?

Можно и в памяти хранить.

Тогда чем оно лучше inmemory с хеш-индексами?

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

Это и есть «материализованный путь». С селектами по нему проблем и правда нет. А вот переносы поддеревьев требуют изменения всех вложенных узлов.
И что? Это проблема? Мы-то знаем, что записи редки и пользователи готовы ждать когда жмут кнопку «сохранить».

Конечно, ведь в рсудб с этим всё сложно и приходится придумывать костыли типа ordpath и компании
Не-а, просто не было такой проблемы, для которой требовалось бы транзитивное замыкание в базе.
Хотел было коммент написать по пунктам, но там столько… Везде полу-правда. Реально надо просто брать запросы и делать забеги.
То, что наравне с nosql используют и рсубд. Key-value имеет свою нишу, с этим я согласен. Но заявлять что данные не влезут в sql — бред.

Есть в мире СУБД способная вместить весь поисковый индекс гугла? В любой реально крупной компании рано или поздно появялется свой «поисковый индекс гугла» из-за которого не получается везде использовать sql, в том числе и потому что данные не «влезут» (да и просто никто разумный не будет пихать в СУБД например все видео ютуба, только чтобы везде использовать СУБД).

Эммм… Они не «влезли» в sql? Что это значит? Место? Скорость?

В первую очередь место, они тупо влазили только на Hadoop кластер с оберткой Hiv'a, возможно что-то вроде многосерверного Oracl'а сумел их прожевать, но цена такого решения была бы астрономической. Да и не нужно это было.

По нашим тестам (а мы протестировали с десяток), nosql выигрывает только на самых простых вариантах. Чуть сложнее выборка или сложные данные для вставки (затрагивающие, по итогу, 5-6 коллекций) — nosql становится явным аутсайдером.

Что именно с чем тестировали? Открытый nosql c открытыми СУБД? Или откртый nosql с чем-то вроде Oracla? И что за странное условие сложных выборок или сложных данных с 5-6 коллекциями? Key-value хорошы именно когда запись и выборка всегда простешие один ключ — одно значение. Документные базы данных хороши когда надо писать сложные документы без связей целиком. Ни в том ни в другом случае, ни сложных выборок, ни вставок в 5-6 коллекций быть не должно по определению (по крайне мере в качестве основного сценария). Скорее всего вы пытались использовать nosql для реляционных данных, а это явно неправильно.
Ради интереса вот вам несколько задач для использование nosql — хранение сессий пользователей сайта в памяти используя key-value и таблицу СУБД или сохранение и получение (целиком) гигантской анкеты с различными количеством различных полей и данных с сайта как один документ монги или как несколько десятков таблиц в СУБД. Вы уверены что для этих задач СУБД покажет лучшую производительность?
Естественно, если вы попытаетесь в key-value или монгу сохранять явные реляционные таблицы со сложными связями с друг другом ничего хорошего из этого не выйдет, не для того они нужны.
С фига-ли?! о_О

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

Есть в мире СУБД способная вместить весь поисковый индекс гугла?

Почему нет? В чем проблема-то? В создании кластера? В создании правильной архитектуры? Где вы увидели ограничение на количество данных в «SQL»? 1 млрд. записей — это много или мало? А 1 трлн?

в том числе и потому что данные не «влезут»

Сейчас мы скатимся к тому, что разработчики данных компаний криворукие…

В первую очередь место, они тупо влазили только на Hadoop кластер с оберткой Hiv'a

Эмм… Т.е. место все-таки было. Но в sql данные не залезли, а в nosql залезли… Плюс, говоря про hadoop упоминаете кластер, а для sql кластер нельзя было использовать? Какая-то не стыковка, если честно.

Что именно с чем тестировали?

Различные nosql с mysql. Было желание еще с pg потестировать, но все nosql проиграли по скорости/месту mysql-у и pg даже не трогали.

Под проигрышем по скорости я подразумеваю различные тесты на чтение и запись данных. Как простых, так и чуть сложных. По чтению почти все nosql выигрывали у mysql. По записи — проигрывали практически все.

По поводу места — разброс сильный. Для сравнения, одна из самых популярных nosql mongodb на одних и тех-же данных занимает х3 места, по сравнению с mysql.

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

Честно говоря — я минут 15 сидел и пытался представить приложение, которое использует только kye-value или только документ-ориентированое без связей. Не смог. Подскажете?

хранение сессий пользователей сайта в памяти используя key-value и таблицу СУБД

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

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

Тут вы меня снова в ступор загнали… Ну ок, предположим есть какая-то супер-гигантская анкета в миллиард полей. Почему она в одном документе монги, а в рсубд размазана на «несколько десятков таблиц» оставим в стороне. Но даже в таких условиях я не вижу никаких проблем использовать субд.

Вы уверены что для этих задач СУБД покажет лучшую производительность?

Нет, не уверен. А вы уверены в обратном? Например, в примере с сессиями я уверен что рсубд будет не хуже, а скорее и лучше, за счет связей с реальными данными.

Из самого определения больших данных.

Не нашел по ссылкам указания на то, что из-за размера данных их нельзя сохранить в slq. Скажите, big data — это какой размер? Сколько записей/(мега/гига/тера)байтов данных?
Проблема РСУБД не столько в объёме данных, сколько в объёме индексов, скорость которых сильно деградирует с ростом числа записей и связей между ними. А индексов этих нужно много, ибо без них джойны будут катастрофически неэффективными. Другая серьёзная проблема — жёсткая схема, требующая единовременно перелопачивать всю базу при её изменении, что очень долго при большом числе данных.
Странная у вас логика. Если мы используем NoSQL, то все выборки у нас по ключу и достаем мы только блобы. А когда речь заходит про РСУБД, то появляются джоины. и сложные запросы. Откуда?
Почему нельзя просто в те же блобы записать json в РСУБД?
Если мы используем NoSQL, то все выборки у нас по ключу и достаем мы только блобы.
Это key-value базы данных. NoSQL ими не ограничивается.

А когда речь заходит про РСУБД, то появляются джоины. и сложные запросы.
Появляется реляционная алгебра.

Почему нельзя просто в те же блобы записать json в РСУБД?
Можно, и получим обычное key-value хранилище :-)
Можно, и получим обычное key-value хранилище :-)

Вот именно. Так почему бы и не воспользоваться РСУБД в этом случае?
А зачем, если специализированное key-value хранилище можно сделать более производительным? :-)
Например, чтобы использовать одно, унифицированное средство хранения данных, а не два разношерстных. Да и какова разница в производительности? Я без сарказма — на самом деле интересно. Вон, многие пишут, что производительнее. Есть реальные примеры, с числами?
«А зачем использовать универсальное средство, если всё-равно его реляционными штучками не пользуешься?» — поэтому и запилили специализированные СУБД без того, чем не пользовались.

Да чисел разных в интернетах полно. Вот, например: github.com/benstopford/awesome-db-benchmarks
www.techempower.com/benchmarks
поэтому и запилили специализированные СУБД без того, чем не пользовались.

А если уже пользуешься, зачем второй движок? РСУБД повсеместны.

Замечательно, спасибо за ссылки.
В случае первой единственный тест, который подходит для сравнения — это сравнение MySQL и MongoDB.
static.ph.ed.ac.uk/dissertations/hpc-msc/2012-2013/RDBMS%20vs%20NoSQL%20-%20Performance%20and%20Scaling%20Comparison.pdf

В принципе, документ отражает, что во всех тестах «победитель» зависит от конфигурации и в большинстве испробованных конфигураций это MySQL(для выборки, см. графики 4.1 и далее). Кроме последнего теста со сложным вложенным запросом, где безусловным победителем с серьезным отрывом выходит MongoDB. Ценой, как отмечено, денормализации, в отличие от РСУБД, которая была нормализована. Но это совсем не простой key-value — про простой случай см. выше.
Для вставок и др. операций результаты другие, т.е. однозначного «NoSQL быстрее» или наоборот, нет.
Специализированные могут быть быстрее за счёт специализации. Например Redis по бенчмаркам гораздо быстрее MongoDB (хотя, скорее всего ценой надёжности).
Почему нет? В чем проблема-то? В создании кластера? В создании правильной архитектуры? Где вы увидели ограничение на количество данных в «SQL»?

Пруф существования кластера СУБД способного хранить сотни петабайт данных и отвечать на полмиллиарда произвольных запросов в день. Или хотя бы пруф теоретические доказательства возможности и практичности такого кластера СУБД.

1 млрд. записей — это много или мало? А 1 трлн?

Мало, размер поискового индекса гугла десятки и сотни трлн. записей.

Скажите, big data — это какой размер?

От десятка терабайт до сотен петабайт.

Честно говоря — я минут 15 сидел и пытался представить приложение, которое использует только kye-value или только документ-ориентированое без связей. Не смог. Подскажете?

1) Легко, действия пользователя с рекламой на сайте (гугл аналитикс и яндекс директ и ему подобные сервисы). Увидел пользователь объявление — ушел запрос к key-value с его данными, кликнул на объявление — ушел второй запрос к key-value, закрыл рекламу — третий запрос. Потеря небольшого кол-ва данных не сильно важна, городить sql нет смысла, так как запросы именно что единичные (и не связанные с остальным сайтом, который вообще может быть не нашим, как в случае гугла аналитика).
2) с документ-ориентированое без связей — любые посты на сайте без комментариев, доски объявлений, каталоги, новостные порталы, любые сайты с преимущественно статическим контентом. Без связей не значит что в документе не будет url'ов, значит что идти по этим связям чтобы получить инфу не нужно. К тому же, никто не мешает совмещать sql и nosql на одном сайте.

Сейчас мы скатимся к тому, что разработчики данных компаний криворукие…

Ну это вы обвиняете что гугл, твитер и прочие гиганты не понимают что могли бы прекрасно жить с одними СУБД, зачем-то затеяли игры с нестабильным nosql.
vintage:

И первое, и второе утверждения абсолютно верны. Но тут нужна некая оговорка: при не правильной архитектуре. Например, fb когда-то заявляли (ссылку не дам, просто отложилось в памяти), что юзают sql, но без джойнов. Такой подход вполне имеет право на жизнь, верно? Причем, решая проблему первого вашего утверждения.

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

vedenin1980:

Пруф существования кластера СУБД способного хранить сотни петабайт данных и отвечать на полмиллиарда произвольных запросов в день. Или хотя бы пруф теоретические доказательства возможности и практичности такого кластера СУБД.

Пруфа нет. А существует пруф, который доказывает невозможность подобного?

Мало, размер поискового индекса гугла десятки и сотни трлн. записей.

Ух-ты… Big data — это только гугл? Не знал). Это раз. Два — откуда такая информация? Три — где пруф, что «десятки и сотни трлн. записей» — это big data? Четыре — где пруф, что такое количество записей нельзя сохранить в sql? Ну и пять — какие именно записи? Что-то мне подсказывает, что та же монга не переварит подобное количество, особенно если делать выборки с or/and в перемешку.

От десятка терабайт до сотен петабайт.

Пруф? А то мне тут некоторые товарищи доказывали, что big data — это от 1М записей)))). Без уточнения структуры записей, размера и пр. характеристик.

Легко, действия пользователя с рекламой на сайте (гугл аналитикс и яндекс директ и ему подобные сервисы).

Не, не подходит. Точнее — только частично подходит (увидел и закрыл). Клик — уже не прокатывает. Необходимо списать деньги с рекламодателя, сохранить статистику по данному виду рекламы, источнику, самому пользователю. Да, это можно разбить в несколько заходов, часть выполнить в фоне, эмулировать транзакционность и пр. Но по сути, это попытка реализовать реляционность на базе nosql. Если добавим сюда отслеживание какую рекламу уже смотрел пользователь (чтобы не выводить повторно), какую рекламу рекомендовать или запретить — вообще печально получается…

с документ-ориентированое без связей — любые посты на сайте без комментариев, доски объявлений, каталоги, новостные порталы, любые сайты с преимущественно статическим контентом.

Отличной пример для big data! Вопрос — где в данном примере плюс nosql перед sql?

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

Так, стоп. Где это я заявлял подобное? Можно пруф? Вроде как говорил, что «наравне с nosql используют и рсубд» (http://habrahabr.ru/company/mailru/blog/266811/?reply_to=8575515#comment_8574575). Зачем вы мне приписываете свои неверные выводы?
В том-то и дело, что без джойнов реляционная СУБД фактически превращается в документную СУБД типа монги, только с жёсткой схемой.

Может опишите правильную архитектуру, где схема никогда не меняется или где продолжительный alter table является плюсом, а не минусом?
Продолжительный alter table бывает только в mysql. Все взрослые движки умеют делать metadata-only operation добавления колонки.
Добавление колонки — наиболее простой вид изменения схемы :-)
А какие операции есть, которые потребуют длительных операций в РСУБД и не потребуют таковых в NoSQL?
Чтобы не останавливать базу на время миграции, обновляют сначала приложение, чтобы оно работало с разными форматами данных, потом запускают в фоне процесс миграции, а по его окончании выпиливают из приложения поддержку старого формата. Какое-то время в одной и той же коллекции можно наблюдать документы в разных форматах.
В sql делают наоборот. Обновляют схему, скрывая изменения за view, а потом обновляют код. И никаких разных форматов.
1. Обновление схемы в общем случае — долгий процесс.
2. Миграция в общем случае — это изменение схемы плюс трансформация данных. Для второго в любом случае нужен программный код.
Как тут поможет «скрытие изменений за view» — ума не приложу.
Скрытие изменений за view поможет так, что приложение не узнает об изменении схемы. Это для того, чтобы ничего не останавливать на время миграции.
Понял о чём вы, но это половинчатое решение. Ведь само изменение схемы (например, меняем int на bigint) на большом числе записей может быть очень долгим в РСУБД.
Пруф существования кластера СУБД способного хранить сотни петабайт данных и отвечать на полмиллиарда произвольных запросов в день. Или хотя бы пруф теоретические доказательства возможности и практичности такого кластера СУБД.

А разве есть пруфы того же самого для NoSQL? Особенно за пределами гугла и fb.

Я вот работаю с несколькими банками, там процессинг в Oracle. Порядка 100 трлн операций.
Это бигдата?
Есть хоть один пример аналога на NoSQL?
Мало, размер поискового индекса гугла десятки и сотни трлн. записей.

Поисковый индекс и РСУБД — совершенно разные вещи. В индексе нет операций конкурентного обновления, то есть он для пользователя read-only. Это означает, что можно индекс раскидать по любому количеству серверов и добавлять быстродействие путем вливания дополнительного бабла в серваки.

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

Так-так, я тут вижу слово «кеш», а ниже вижу слова «целостность» и «согласованность». Это вгоняет меня в какой-то диссонанс. Не, я понимаю как можно юзать кеш и обеспечивать целостность и согласованность, но все же ). Кстати, а кеш — это sql или nosql?

Мало того, что нету никакого контроля целостности на прикладном уровне, так еще и резервное копирование и восстановление не всегда работает как надо.

Контроль целостности? Как много я могу проконтролировать на уровне sql-сервера? Или вот еще вопрос: почему в интернетах рекомендуют выпиливать reference constraints при работе с большим объемом данных?
Ну и еще. В большинстве систем количество чтений больше количества записей, значит имеет смысл делать денормализованную бд, а то рано или поздно упрешься в то, что подгрузка данных занимает долгое время. Чем мне пожертвовать, перфомансом или честной реляционностью и честнейшей гарантированной sqlем согласованностью?

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

Также NoSQL редко встречается в задачах с конкурентным доступом к данным

Странно, а я то думал, что key-value store (а они тоже вполне себе NoSQL решения) с атомарными операциями и compare&swap операциями обеспечивают хорошую производительность и согласованность данных. Алсо, честные быстрые конкуррентные транзакции в SQL — это очень и очень тяжко. Я не буду убеждать вас, что транзакционность не нужна. Да, она в 50% случаев нафиг не нужна, в 40% случаев её делают неправильно и просто не замечают проблем, а в 10% случаях она реально нужна. Но просто транзакционность можно делать по разному, не только через автоматически расставленные sql сервом локи и кривой недопиленный mvcc.
Так-так, я тут вижу слово «кеш», а ниже вижу слова «целостность» и «согласованность». Это вгоняет меня в какой-то диссонанс. Не, я понимаю как можно юзать кеш и обеспечивать целостность и согласованность, но все же ). Кстати, а кеш — это sql или nosql?

Начну с конца — так будет понятнее. Кеш — не хранилище. Поэтому не имеет смысла говорить о SQL или NoSQL. У него нет задачи долговременного хранения данных. Хотя инструменты типа Redis могут сохранять состояние кеши от этого хранилищами не становятся. Задача у любого кеша — сделать данные «ближе» к потребителю.

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

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

Как много я могу проконтролировать на уровне sql-сервера?

Во взрослых движках — сколь угодно много.

Или вот еще вопрос: почему в интернетах рекомендуют выпиливать reference constraints при работе с большим объемом данных?
Это довольно странный совет, который скорее вреден, чем полезен. Я знаю только один сценарий когда отключение контроля целостности оправдано — загрузка большого объема данных. Но почти во всех базах можно просто отключить временно проверки и не удалять внешние ключи.

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

Идеи про денормализованность — совершенно бредовые для OLTP.

Для начала в каждой серьезной системе должен быть кеш для запросов, которые редко меняются. Это сразу снимает 90% вопросов быстродействия.

Далее в каждой серьезной БД есть материализованные представления, которые позволяют не нарушать целостность и поддерживать «денормализацию». Это снимет еще 90% из оставшихся.

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

Это снимет 90% вопросов из оставшихся. Но в большинстве систем это уже перебор, обычно на втором шаге можно остановиться.

Я вам расскажу краткую историю откуда денормализация взялась.
Когда у нас возникает OLAP задача — то есть анализ большого объема данных с вычислением агрегатных функций, то возникает проблема с так-называемыми snowflake джоинами. Когда центральная таблица фактов джоинится с кучей таблиц измерений, а те в свою очередь джоинятся с другими таблицами. Оказалось, что эффективного алгоритма оптимизации таких джоинов нет и статистика не помогает. Поэтому рекомендуется денормализовывать таблицы в хранилищах для OLAP, чтобы быстрее работали такие запросы.

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

В OLTP я такое видел крайне редко и решается обычно через кеши и материализованные представления.

а я то думал, что key-value store (а они тоже вполне себе NoSQL решения) с атомарными операциями и compare&swap операциями обеспечивают хорошую производительность и согласованность данных

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

Вообще для key-value идеальное решение — файлы на диске. Ключ — имя, value — содержимое. Работает быстрее и надежнее любой базы.

Да, она в 50% случаев нафиг не нужна, в 40% случаев её делают неправильно и просто не замечают проблем, а в 10% случаях она реально нужна.
Проблема в том, что на старте проекта крайне сложно сказать где не нужна будет транзакционность. При этом во взрослых движках можно отключить и механизмы конкуренции, и сделать delayed durability, и inmemory storage задействовать. А в nosql нельзя «включить» транзакционность, если её не было. Поэтому при прочих равных лучше выбирать SQL-базу и добавить кеш для скорости, чем писать тонну кода, чтобы хоть какое-то подобие согласованности поддерживать в nosql. За исключением некоторых специфических сценариев.
Диссонанс у вас от того, что вы не понимаете задач кеша и хранилища, тем более что некоторые решения для кеширования позиционируются как NoSQL базы данных.

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

Во взрослых движках — сколь угодно много.

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

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

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

Далее в каждой серьезной БД есть материализованные представления, которые позволяют не нарушать целостность и поддерживать «денормализацию»

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

Идеи про денормализованность — совершенно бредовые для OLTP.

Это значит что в вашей практике не было необходимости делать денормализацию бд или вы готовы подкрепить подобные заявления чем-то?

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

Прикалываетесь или как? Реляционная субд построена на идее индексов (да, можно сделать таблицу без кластерного индекса, я знаю). Индекс — это (key) — (included fields + primary key of value), т.е. key — value. Реляционная субд — это key-value, какие-то гарантии транзакционности и атомарности, а также query language, который не заставляет пересылать данные туда-сюда для того чтобы сделать joinы. Вопрос в том, насколько эффективнее реляционная субд по сравнению с мануальной обработкой всего этого.

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

Ну тут я тоже могу сослаться на взрослые движки, которые позволяют добавить в спискок конкуррентно. Пространство nosql решений весьма обширное.

Вообще для key-value идеальное решение — файлы на диске. Ключ — имя, value — содержимое. Работает быстрее и надежнее любой базы.

Чушь.

Проблема в том, что на старте проекта крайне сложно сказать где не нужна будет транзакционность

Вы этой фразой переводите реляционные БД в область инструментов для прототипирования, нет?

При этом во взрослых движках можно отключить и механизмы конкуренции

Пруфы плиз. Меня интересует полное отключение writer-writer locking. Какие взрослые движки это умеют? Вообще у меня скаладывается впечатление, что ни один из нас не видит полноценно картину.

Поэтому при прочих равных лучше выбирать SQL-базу и добавить кеш для скорости, чем писать тонну кода, чтобы хоть какое-то подобие согласованности поддерживать в nosql

А когда проседает и выборка, и вставка, что делать? Тонны кода — это весьма громогласное утверждение, если вы пишете объемную систему.

За исключением некоторых специфических сценариев.

Вопрос в том, насколько часто у вас проявляются специфичные сценарии. А вообще, если был груб, то извините, моя злость на реляционные БД сопряжена попытками получить приемлемую производительность там, где было бы разумнее заюзать key-value хранилища вместо «детского» движка )
Не-не, диссонанс у меня из-за того, что данные в кеше будут или грязными, или устаревшими.

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

Покажите мне взрослые движки, пожалуйста.

SQL Server, Oracle, DB2 и к ним приближается Postgres.

Ну да, я про этот сценарий и говорю.

И как часто встречается такая проблема в OLTP? На моем опыте — один из ста.

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

А еще можно триггеры хуячить, чо бы и нет. Вообще минимум ограничений. Только производительность при вставке/апдейте проседает, потому что механизмы универсальные и неидеальные.
А денормализация бесплатная чтоли?

Это значит что в вашей практике не было необходимости делать денормализацию бд или вы готовы подкрепить подобные заявления чем-то?

Конечно могу. Я неоднократно оптимизировал приложения путем убирания ручной денормализации.

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

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

Меня интересует полное отключение writer-writer locking. Какие взрослые движки это умеют?
Oracle, SQL Server они умеют read commited snapshot. Фактически не навешивает блокировки при записи. Насчет DB2 не уверен.

А когда проседает и выборка, и вставка, что делать?
Миллион рецептов в зависимости от субд. В SQL Server есть partition switching.

Вопрос в том, насколько часто у вас проявляются специфичные сценарии.
Крайне редко, именно поэтому сценарии специфические.
Это лишь означает, что вы не умеете работать с кешем. Если вы сбрасываете кеши вовремя, то не будет ни грязных, ни устаревших данных.

Блять, ты вообще читаешь что ты пишешь? Ты говоришь о трудностях обеспечения согласованности и целостности nosql бд и при этом говоришь о легкости обеспечения согласованности двух независимых хранилищ. Как это?

SQL Server

Тоже мне. серьезный взрослый движок.

И как часто встречается такая проблема в OLTP? На моем опыте — один из ста.

На твоем опыте.

Если речь идет об оптимизации джоинов, то почти нет.

И как у SQL Serverа с материализованными вьюхами, содержащими left joinы? А никак, нельзя такие. И множество функций юзать тоже нельзя в материализованных вьюхах.

Конечно могу. Я неоднократно оптимизировал приложения путем убирания ручной денормализации.

Господи, да никто не спорит, что денормализированная бд может слоупочить. И никто не спорит, что неправильный дизайн тоже может слоупочить. Но я просил пруфы, что денормализация это вредный совет в 100% случаев. Меньше не надо, а то по совокупности моих претензий может выйти что юзать не sql решение.

Oracle, SQL Server они умеют read commited snapshot. Фактически не навешивает блокировки при записи. Насчет DB2 не уверен

SQL Server снепшоты умеет через tempdb. Я хотел снять нагрузку с бд удалив writer-writer lock, мне предлагают юзать tempdb, который тоже вполне себе нагружает бд. Это не то, что я хочу от бд. Я хочу чтобы она позволила мне вставить несколько тысяч записей конкурентно, тратя ресурсы только на реорганизацию индексов. Это плата за умность реляционных бд — они не дают тебе сделать того, в чем ты уверен. А я уверен, что никто не будет трогать мои новые записи до того, как я завершу их вставку, поэтому мне лок на них не нужен.

В SQL Server есть partition switching

У SQL Server 2008 лимит на количество партиций был в тысячу. Сейчас вроде повыше, но все равно константа. Что как бы позволяет плясать, но не очень сильно и хорошо.

Названия в студию. А еще крайне желательно описание как они это делают

Вы знаете, тут меня подловили. Я понадеялся на redis, у которого есть стандартная возможность добавлять в список, но там ничего не сказано по поводу того, насколько хорошо обрабатывается конкурентность (так что можно только надеяться на то, что там все ок). Понадеялся на другие key-value stores — так там стандартное решение это юзать key ranges (а это подходит под эти цели, но концепт немного другой). Ну или обычно это не спефика для решений, которые должны быстро работать и шардиться. Так что сорри, тут обманул.

Крайне редко, именно поэтому сценарии специфические.

Они для вас специфические. Вам не кажется, что специфические для вас сценарии в других проектах могут происходить чаще? Или хуже того, что с развитием сложности проектов специфичные решения станут все более и более частыми?
Блять, ты вообще читаешь что ты пишешь? Ты говоришь о трудностях обеспечения согласованности и целостности nosql бд и при этом говоришь о легкости обеспечения согласованности двух независимых хранилищ. Как это?
Повторяю:
Механизм обеспечения целостности кеша — сброс и пересбор из хранилища. Сброс кеша сложная задача, но решаемая.
Механизм обеспечения целостности в хранилище — транзакции и проверки. Это тоже сложная задача, но тоже решаемая.
Почти все NoSQL базы занимают промежуточное положение. Они вроде как хранилища, но без транзакционности, с другой стороны кеш, но без возможности сброса.,

Тоже мне. серьезный взрослый движок.

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

Но я просил пруфы, что денормализация это вредный совет в 100% случаев.
Какие пруфы вам нужны?
Вам очевидно, что денормализация требует больше ресурсов при записи?
Вам очевидно, что денормализация требует больше кода?
Вам очевидно, что денормализация — не гарантия более быстрых запросов?
Надеюсь вы из этого сможете сделать вывод.

Если не очевидно, тогда можно не продолжать.

SQL Server снепшоты умеет через tempdb
И что? Это вовсе не означает что будет реальная запись на диск. Вы в курсе как buffer pool работает?

У SQL Server 2008 лимит на количество партиций был в тысячу. Сейчас вроде повыше, но все равно константа. Что как бы позволяет плясать, но не очень сильно и хорошо.
Про partition merge в курсе?

Вы знаете, тут меня подловили. Я понадеялся на redis, у которого есть стандартная возможность добавлять в список, но там ничего не сказано по поводу того, насколько хорошо обрабатывается конкурентность (так что можно только надеяться на то, что там все ок).
В редисе добавление в список лочит список. Спасает только то, что это все в памяти. Но в том же SQL Server inmemory можно добиться того же эффекта без лока на всю inmem таблицу.

Вам не кажется, что специфические для вас сценарии в других проектах могут происходить чаще?
Понимаете в чем фишка. Большая часть программистов, которая работает с базами, делает учетные системы в том или ином виде. А для них сценарии, где пригодны NoSQL базы, ну крайне специфические.
Механизм обеспечения целостности кеша — сброс и пересбор из хранилища. Сброс кеша сложная задача, но решаемая.
Механизм обеспечения целостности в хранилище — транзакции и проверки. Это тоже сложная задача, но тоже решаемая.

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

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

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

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

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

А что если этого достаточно для реализации транзакционности руками?
А что если этого достаточно для реализации транзакционности руками?

Проблема в том, что сегодня может быть достаточно, а завтра требования поменяются и станет не достаточно и что тогда делать?
И что? Это вовсе не означает что будет реальная запись на диск. Вы в курсе как buffer pool работает?

Мм, т.е. вы таки хотите сказать что in-memory MVCC быстрее чем запись вообще без локов на свежезаписанные записи?
При добавление записей в inmemory с MVCC не возникает никаких локов. Только атомарные операции.
Есть таблица, она должна быть не in-memory и персистентной. В неё нужно вставлять много записей временами. MVCC — это дополнительный оверхед на ресурсы, не IO диска, так память. Локи это тоже дополнительный оверхед на ресурсы. Без локов, без mvcc, руками — невозможно в SQL Server, но даст отсутствие лишнего оверхеда. Я об этом говорю, о избавлении от оверхеда вообще
Я говорю о том же самом. inmemory таблицы тоже пишутся на диск. Но для них не пишутся индексы. Поэтому можно иметь быстрые выборки с помощью хеш-индексов (O(1)) и не иметь оверхеда блокировок при добавлении записей. Еще раз — mvcc для inmemory не использует блокировки вообще.

А еще можно включить delayed durability чтобы не ждать записи на диск.
Понимаете в чем фишка. Большая часть программистов, которая работает с базами, делает учетные системы в том или ином виде. А для них сценарии, где пригодны NoSQL базы, ну крайне специфические.

У меня фишка прикольнее. Я долго не мог осознать как писать решения на чистых key-value storах. Для меня это было на грани «вы че ебанутые, а как транзакции, а как же атомарность, я че руками должен это делать все?». Потом со временем в голову начало приходить, что я могу последовательно переписывая многие вещи отказаться от многих кейсов использования sql. При этом получить профит. Хотя это и трудно моментами продумать. Но я понимаю о чем вы говорите.
А денормализация бесплатная чтоли?

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

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

Отчего же? Key-value — очень запросто реализуется, файлы — тоже.
Реализуется, но засчет времени отклика, производительности сервера, затрат на место на диске. Чудес не бывает, in-memory key-value хранилище будет работать быстрее (и с меньшими затратами ресурсов), чем СУБД которой нужно сначала SQL запрос распарсить, потом индексы перестроить и дождаться честной записи на жесткой диск. Тоже самое с записью/чтением цельного json документа монго и join'ами по десятку баз СУБД, чтобы записать те же данные.
1. Есть реляционные СУБД и не реляционные.
2. Реляционные тоже могут быть in-memory.
2. Могут, только задачи парсинга sql запросов и перестройки индекса это же не отменяет. К тому же key-value не требуется поддержка всех возможностей sql запросов и они могут оптимизировать свою работу за счет хорошо оптимизированых хэш-таблиц с доступом O(1), в то время как СУБД обычно использует бинарное дерево c его O(log n).
Могут, только задачи парсинга sql запросов и перестройки индекса это же не отменяет.

Запрос парсится ровно один раз.

К тому же key-value не требуется поддержка всех возможностей sql запросов и они могут оптимизировать свою работу за счет хорошо оптимизированых хэш-таблиц с доступом O(1), в то время как СУБД обычно использует бинарное дерево c его O(log n).

Вы в курсе, что взрослые движки РСУБД имеют inmemory движки с хеш-индексам, по сути хеш-таблицами в памяти?
А для чтения данных с диска пока что ничего быстрее b+-деревьев не придумали. Даже Mongodb использует древообразные индексы.
Запрос парсится ровно один раз.

Ага, и сразу же превращается в бинарный код, готовый для исполнения. Как давно взрослые и серьезные движки такому научились и насколько хорошо они это делают?
Не бинарный код, а план запроса. Хотя Native Stored Proc в SQL Server позволяет процедуры скомпилировать в бинарный код.

Все РСУБД научились кешировать планы примерно 15 лет назад.
Про то, что есть кеширование планов не знает только ленивый. Native Stored Proc работает только с memory таблицами.
Это вы утверждаете, что запрос парсится каждый раз.
Нет, я не утверждаю такого. Я просто хотел сказать, что распарсить запрос — это не вся работа по оптимизации, которая может быть проделана
Вам процитировать ваше сообщение?

Если запрос есть в кеше, то больше никаких операций не происходит. По хешу достается план и запускается выполнение.
Запрос парсится ровно один раз

Если мы пошлем миллион запросов «insert database1.table1 value (valueN);» в разных сессиях, где valueN — каждый раз новое значение, то сколько раз будут парситься запросы? Один или миллион?
Не говоря уже о том что кроме парсинга запроса, СУБД поднимет список всех баз, потом список всех таблиц, потом список прав данного пользователя на эту таблицу, то есть ещё до того как вообще-то что-то сделать СУБД уже выполнила три запроса к трем таблицам.
Миллион.
Но в здравом уме никто так не пишет, все используют параметры.

Кроме того для примитивных запросов есть автопараметризация. Там конечно выполняется парсинг, но построение плана не происходит.
Так мы о in-memory или о НЕ реляционных дисковых? Если говорить о дисковых, то надо сравнивать дисковые key-value с дисковыми СУБД. Если вы делаете простой запрос, такой же, как для ke-value, т.е. "дай мне значение из колонки Х где колонка У = N", это такой примитив, про «парсинг» которого смешно говорить. Самые большие затраты — на ввод-вывод, а не парсинг чего-либо в памяти.
Индексы перестроить? В вашем key-value нет индекса? Ваш key-value не пишет на диск?
Потому что реляционная бд это универсальное решение, которое предназначено хоть как-то работать со всем чего от неё ожидают. Это цена универсальности.
Key-value хранилище заточенно под определенные задачи. Любое заточенное решение по определению потенциально должно работать лучше чем универсальное решение. За конкретными бенчмарками можно сходить в гугл.
Но вообще, если я вас не убедил, то ответьте на такой интересный вопрос: зачем на рынке появляются отдельные key-value хранилища когда уже 40 лет есть замечательные и восхитительные реляционные БД. И уж тем более, зачем люди меняют замечательные и восхитительные реляционные БД на унылые key-value хранилища, они чо упоротые?
За конкретными бенчмарками можно сходить в гугл.

Так вот это и хочется выяснить, задавая вопрос о том, зачем они нужны. А с гуглом я и сам поговорить умею. Зачем тогда тут общаться? Можно не выкладывать статьи и не обсуждать их. Зачем? Ведь каждый может в гугле ввести запрос и найти информацию.
Все-таки надеешься, что человек сможет ответить по существу, например «у нас используется для xyz операций (с конкретикой) — оказалось, что работает в n раз быстрее и ест меньше ресурсов при хранении».

Общих-то рассуждений можно выдать много, только это теория.
Все это прекрасно делается в любой взрослой СУБД.
А зачем в таком случае отдельная СУБД? Файловая система с такой задачей не лучше справится? Находить файл по ключу. Я не троллю, я серьезно не видел серьезных сравнений и потому спрашиваю.
а) файловые системы не любят когда файлов слишком много. Базовый совет по огранизации file storage на основе файловой системы — взять guid или хеш и его части использовать как вложенные поддиректории.
б) много мелких файлов — гарантия фрагментации
в) файловая система медленная, поверх неё нужна еще in-memory прослойка. Тупо mapить такое количество файлов не выйдет — их слишком много и они мелкие. Не говоря уже о том, что часть данных не будет помещаться в ОЗУ.
г) key-value хранилища бывают разные, некоторые с поддержкой транзакций

Бенч увы не приведу, это только общие рассуждения.
Просто есть сильное подозрение, что 1-й будет неверен уже при сравнении с каким-нибудь рейзером, а второй и третий познаются в сравнении, так как и у файловых систем кэш есть, и у NoSQL СУБД фрагментация.
NTFS использует то же B-Tree для индексирования имен файлов, емнип.
Алгоритму с О(1) для этого потребуется 1 операция.
ну вот это крайне неверно. O(1) может легко потребовать 10^6 операций, например. и поэтому при маленьких существуют случаи когда O(1) работает медленнее O(n^2)
Тут на самом деле у автора вряд ли стояла цель разобрать полностью всю «Big-Oh notation». Конечно, сравнение верно только начиная с некоторого n, но давайте представим, что тут вместо общего случая тут рассмотрен просто один из примеров, причем учебный, целью которого является лишь поверхностно коснуться «Big-Oh notation» без сильного погружения в математику.

Для вводной статьи это ОК, кто захочет большего, тот найдет.
ИМХО.
ну это понятно ) просто я за четкость формулировок. в этой фразе явная дезинформация, которая у кого-то может отложиться в памяти. Можно было сделать один абзац про O(1) и этого бы хватило
Не могу уйти не сказав спасибо, настолько хорошо написано, и вернусь еще не раз…
PS гипнотизер перед «Или же просто можете дать ссылку на эту статью» так просто или помогает?
Он не перед «дать ссылку», а после «вместо того, чтобы плюнуть и уйти, вы можете ответить:»
В постскриптуме ИМХО. Мне понравилось… необычно… притягивает и почему то хочется порекомендовать еще кому-нибудь. Как будто усиливает позитив от и без этого хорошей статьи.
Отличный пример того, какой должна быть статья. Все материалы, которые отличны от темы статьи, вкратце разобраны. Для тех, кто хочет больше, есть ссылки. В итоге статья читается на одном дыхании без необходимости поиска отдельных сущностей.
Огромное спасибо за перевод.
Сегодня многие разработчики не особо задумываются о временнόй сложности алгоритмов… и они правы!

нет. Мне больше нечего сказать.
Это длительный спор, но правы как одни, так и другие.
Печально, что современному разработчику, пользующемуся, на минуточку, реляционной базой данных, вот так вот на пальцах приходится разъяснять про алгоритмическую сложность сортировки слиянием. Это почти что макака с гранатой, что и подтверждается практикой. Вроде бы и пользуются базой данных, да не очень. Выходит сплошной mongodb-is-web-scale.com.
Зависит от задачи. Обывателю-разработчику действительно о ней задумываться не обязательно.
Очень полезная статья. Компактно представлены тезисы, которые можно прочитать из 700-страничных книг по БД.
Спасибо!
Спасибо автору за перевод. Буду рекомендовать всем знакомым, желающим познать реляционные базы данных.
Никого не смущает, что O(n^2) не похожа на параболу на графике?
Там же логарифмическая шкала.
на y = log(x2) = 2∙log(x)
тоже не похоже
Да, не заметил. В таких осях действительно интересно сравнивать сложность.
Кажется мне, что места куда попадают элементы с одинаковым хешом называются корзинами, а не блоками.
Привет! Здесь опечатка?
Для каждой из N строк внешней зависимости нужно считать М строк внешней зависимости.
Обозначается временнáя сложность как «О» (читается как «О большое»).

Эту фразу можно понять так, будто «О большое» создано исключительно для этого обозначения. Но на самом деле в понятие «О большое» не заложены ни временная сложность, ни сложность как таковая. Это широко используемое математическое обозначение (wiki).
Отличная статья
Опечаточка "Для объединения с TYPE_PERSON будет использоваться индекс по колонке PERSON AGE"
Sign up to leave a comment.