Является ли использование баз данных NoSQL нецелесообразным для больших наборов данных, где вам нужно искать по содержимому?

51

Я изучаю базы данных NoSQL уже неделю.

Я действительно понимаю преимущества баз данных NoSQL и множество вариантов их использования.

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

Базы данных NoSQL (часто) являются хранилищами значений ключей.

Конечно, можно хранить все в хранилище значений ключей (путем кодирования данных в JSON, XML и т. Д.), Но проблема, которую я вижу, заключается в том, что вам нужно получить некоторый объем данных, который соответствует определенному критерию, во многих сценарии использования. В базе данных NoSQL у вас есть только один критерий, который вы можете эффективно искать - ключ. Реляционные базы данных оптимизированы для эффективного поиска любого значения в строке данных.

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

Пример:

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

В реляционной базе данных каждый пользователь хранится в виде строки в usersтаблице с идентификатором, именем, его страной и т. Д.

В базе данных NoSQL вы должны хранить каждого пользователя с его идентификатором в качестве ключа и всеми его данными (закодированными в JSON и т. Д.) В качестве значения.

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

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

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

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

Лео Линдхорст
источник
16
Это больше похоже на напыщенную речь, чем на вопрос. Похоже, вы хорошо понимаете преимущества и недостатки хранения ключ-значение по сравнению с реляционным. Так в чем же заключается вопрос?
JacquesB
16
Это совсем не напыщенная речь :) Базы данных NoSQL потрясающие, но я думаю, что реляционные базы данных не так плохи, как утверждают некоторые. Я просто хочу выяснить, если мой тезис, что базы данных NoSQL не лучший выбор, если речь идет о поиске в «datarows» ... или если я не правильно понял тему.
Лео Линдхорст
2
programmers.stackexchange.com/q/54373/17853
Гонки на легкость с Моникой
5
Но MongoDB - это веб-класс ! [предупреждение: включает в себя немного языка NSFW]
Джерри Коффин
5
@DevWurm: Вы не должны объединять хранилища значений ключей с NoSQL в целом. Например, googles BigTable считается базой данных NoSQL, но вы все равно можете искать и создавать индексы по нескольким полям. Хранилище значений ключей подходит, когда вы знаете, что вам нужно искать только в одном поле (ключ).
JacquesB

Ответы:

40

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

В базе данных NoSQL у вас есть только один критерий, который вы можете эффективно искать - ключ.

Это явно не правда.

Например, MongoDB поддерживает индексы. (из https://docs.mongodb.org/v3.0/core/indexes-introduction/ )

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

Индексы - это специальные структуры данных [1], которые хранят небольшую часть набора данных в удобной для просмотра форме. В индексе хранится значение определенного поля или набора полей, упорядоченных по значению поля. Упорядочение записей индекса поддерживает эффективные совпадения и операции запросов на основе диапазона. Кроме того, MongoDB может возвращать отсортированные результаты, используя порядок в индексе.

Как и couchbase (от http://docs.couchbase.com/admin/admin/Views/views-intro.html )

Представления Couchbase позволяют индексировать и запрашивать данные.

Представление создает индекс данных в соответствии с определенным форматом и структурой. Представление состоит из определенных полей и информации, извлеченной из объектов в Couchbase.

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

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

Майкл Андерсон
источник
13
«... поскольку они обычно находятся за пределами таблицы, вам не нужно менять схемы таблиц для их поддержки». Это та же самая ситуация между некластеризованным индексом в базе данных SQL и индексом для базы данных noSQL, верно?
Йирка Ханика
Довольно солидный ответ. Я бы добавил, что NoSQL в некоторой степени основывается на идее, что если вы хотите работать быстрее, вы должны делать 90% ++ запросов по первичному ключу без объединения, и если вы хотите сделать что-то еще, вы находитесь в мир сканирования таблиц и вторичных индексов, которые всегда имеют ограничения по производительности и масштабированию. Когда вы выполняете поиск по индексу или создали группу, вы просто не находитесь в той области, где можно достичь скорости (за исключением небольших наборов данных в несколько миллионов строк). Если вы будете кодировать в стиле, где альтернативные поиски редки, вы получите очень надежную операционную систему.
Брайан Булковски
40

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

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

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

Чтобы использовать этот пример, в SQL запрос по стране выполняется так же медленно, как и сканирование NoSQL всех пользователей, если только вы явно не сказали SQL индексировать usersтаблицу по стране. NoSQL может сделать то же самое, когда вы создаете упорядоченную коллекцию ключей-значений, которая является индексом (так же, как это делает SQL), и ведете ее.

Различия? Механизмы SQL имели концепцию индексации встроенной таблицы. Это означает, что вам нужно выполнять меньше работы (все, что вам нужно было сделать, это добавить индекс в таблицу). Однако это также означает, что у вас было меньше контроля. В большинстве случаев такая потеря контроля является приемлемой в обмен на механизм SQL, выполняющий всю работу за вас. Однако в массивных наборах данных может потребоваться модель согласованности, отличная от типичной модели SQL ACID. Возможно, вы захотите использовать модель BASE, которая поддерживает возможную согласованность. Это может быть очень сложно в SQL, потому что движок SQL делает всю работу за вас, поэтому это должно быть сделано по правилам движка SQL. В NoSQL эти слои обычно открыты, что позволяет вам взломать их.

Корт Аммон
источник
2
В вашем примере вы утверждаете, что « SQL-запросы по странам так же медленны, как и NoSQL-сканирование всех пользователей ». У вас есть доказательства, подтверждающие это? NoSQL, описанный в этом вопросе, представляет собой пару ключ-значение, поэтому вам нужно будет отсканировать значение, чтобы узнать местоположение страны, а затем выполнить сравнение. SQL уже знает, где находятся эти данные, поэтому он может выбрать их непосредственно с диска (пропуская ненужные данные), а затем проверить значение. Если страна является внешним ключом, это быстрое целочисленное сравнение. Конечно, это всегда будет быстрее, так как вы меньше тянете с диска, а проверка происходит быстрее.
Trisped
1
@Trisped Трудно представить доказательства, потому что NoSQL - это подход, а не продукт (то же самое для SQL). Тем не менее, стоит отметить, что BigTable, реализация NoSQL, имеет концепцию столбцов, как и таблицы SQL. Это концепция столбцов, которая позволяет пропускать данные, зная, где искать, что может быть применено к любой реализации.
Cort Ammon
16

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

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

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

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

JacquesB
источник
2
«NoSQL - это довольно расплывчатый термин, поскольку он в основном охватывает все системы баз данных, которые не являются реляционными». - Это не правда. Он охватывает все системы баз данных, которые не являются базами данных SQL. Существуют реляционные базы данных, которые не используют SQL, такие как Rel и Tutorial D (базы данных, разработанные для более точного следования реляционной модели без «смягчения», которое делает SQL). Есть гиперреляционные базы данных. Действительно, NoSQL означает «не только SQL», что означает «не предполагать автоматически SQL, выбирайте правильную модель базы данных, которая соответствует структуре вашей даты… которая вполне может быть SQL».
Йорг Миттаг,
@ JörgWMittag По вашему определению, если я выберу MySQL, потому что это лучшая БД, соответствующая моим данным, то это правильное решение NoSQL.
1
@ JörgWMittag: Официальное определение термина NoSQL отсутствует, но обычно оно относится к нереляционным системам баз данных. «Not Only Sql» -backronym - действительно более свежий реткон, чтобы противодействовать неизбежной обратной реакции. Но в общем случае NoSQL используется для описания таких систем, как MongoDb, Bigtable и т. Д., А не для учебника D (который даже не является базой данных).
JacquesB
2
@ JörgWMittag NoSQL изначально означал «не SQL» или «нереляционный». «Не только SQL» будет NOSQL, так как это аббревиатура вместо комбинации слова «Нет» и аббревиатуры «SQL». Он стал популярным в противовес общепринятой практике помещения всего в базу данных (как указано в статье в Википедии). Как вы прокомментировали, поле сейчас немного сложнее.
Trisped
Полностью согласен. Кажется, что основными шаблонами NoSQL являются хранилище документов с ключом (например, Redis) (например, Mongo) и график (например, Neo4J). Я хотел бы, чтобы люди отказались от NoSQL и использовали один из этих терминов.
paj28
10

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

Эти цели часто противоречат друг другу. Многие пользователи Твиттера следят за людьми со всего мира. Должна ли база данных твиттера быть географически оптимизирована для чтения твитов или написания твитов?

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

Карл Билефельдт
источник
Чтение 10 ТБ в оперативную память занимает некоторое время @Daniel ... Несколько часов было бы довольно хорошим результатом. Это сделало бы восстановление после катастрофы относительно катастрофическим.
Бен
1
Я бы сказал, что Big Data - это одна из областей, где базы данных NoSQL вступают в игру, но это только одна из них. Есть также много других причин, по которым база данных NoSQL может лучше подходить для решения проблемы. Если у вас есть графы данных, имеет смысл использовать базу данных графов, если у вас есть данные XML, имеет смысл использовать базу данных XML. Не только большие данные, но и модель данных являются важными критериями при выборе подходящей базы данных (и, разумеется, во многих случаях SQL-базы данных являются правильным выбором, в зависимости от проблемы)
dirkk
5
Это не верно. В течение многих лет подход к программированию был стандартным в крупномасштабных базах данных, и некоторые базы данных поддерживают кластеры с прозрачным обменом данными (Oracle RAC). Как вы думаете, все банки работают? И при правильной настройке вы РЕКОМЕНДУЕТЕ восстанавливать резервные копии - это остается реальным сценарием «сгорел 2 центра обработки данных». И да, однажды мы работали с базой данных 30 ТБ - у нас не было проблем.
TomTom
Да, реляционные базы данных выполняют прозрачную передачу и кластеризацию данных, но это очень утечка абстракции, если вы заботитесь об оптимизации производительности.
Карл Билефельдт
5

Базы данных NoSQL имеют очень мало общего с « No SQL».

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

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

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

Например:

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

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

Следовательно.....

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

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

Поскольку базы данных «NoSQL» не скрывают эти проблемы, они могут стать лучшим вариантом при масштабировании системы. Но помните, что Stackoverflow по-прежнему использует реляционную базу данных для хранения всех своих данных с ограниченным использованием NoSQL на уровне кэширования - поэтому вы должны быть ОЧЕНЬ большими, прежде чем вы будете вынуждены использовать NoSQL для хранения ваших данных.

Ян
источник
Этот последний кусочек очень интересен - есть ли у вас ссылка на какой-нибудь мета-сайт SO, чтобы заинтересованные читатели могли перейти к SO (не) использованию NoSQL? Спасибо!
kcrisman
@kcrisman см highscalability.com/stack-overflow-architecture для exmaple
Ian
2

Реляционные базы данных оптимизированы для эффективного поиска любого значения в базе данных.

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

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

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

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

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

NikoNyrh
источник
-2

Я использую couchdb уже два года. В основном он используется для управления контентом и настройки.

Для иерархических отношений гораздо проще управлять, когда вы можете их визуализировать. Для данных в основном для чтения проще отредактировать JSON, чем во многих случаях написать инструкцию UPDATE. На самом деле программисту не нужно редактировать JSON. И SQL дает вам строки и столбцы, которые затем необходимо отобразить в какую-то структуру объекта.

Вы также получаете повышение производительности, потому что вы не объединяете 10-20 таблиц по сложным запросам. Представления Couchdb очень быстрые, потому что JavaScript, на котором они основаны, не выполняются во время запроса.

Большинство программистов понимают Javascript, и большинство программистов время от времени борются с SQL.

В Couchdb представление может рассматриваться как абстракция документа JSON. Как структура данных представления зависит от вас (вы не ограничены исходной иерархией).

Я бы не стал использовать Couchdb для данных с высокой степенью транзакций, но для полустатических данных со структурой типа взрыва частей работать НАМНОГО проще, чем с SQL.

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

Джефф Лоури
источник