Страницы

Поиск по вопросам

Показаны сообщения с ярлыком nosql. Показать все сообщения
Показаны сообщения с ярлыком nosql. Показать все сообщения

суббота, 4 апреля 2020 г.

Как сделать группировку в mongodb?

#mongodb #nosql

                    
Есть коллекция с документами вида:

{
    "_id" : ObjectId("56e17f2db292c9151a8b459b"),
    "title" : "test title",
    "category" : "test category",
    "pubDate" : "1457599100",
    "code" : "ZZZ"
},
{
    "_id" : ObjectId("56e17f2db292c9151a8b459b"),
    "title" : "test 2 title",
    "category" : "test 2 category",
    "pubDate" : "1457599200",
    "code" : "ZZZ"
}


Как сделать группировку, чтобы получить на выходе что-то типа этого:

{
  "ZZZ": {
    "items": {
      0:{
         "_id" : ObjectId("56e17f2db292c9151a8b459b"),
         "title" : "test title",
         "category" : "test category",
         "pubDate" : "1457599100"
      },
      1:{
         "_id" : ObjectId("56e17f2db292c9151a8b459b"),
         "title" : "test 2 title",
         "category" : "test 2 category",
         "pubDate" : "1457599100"
      }
    }
  }
}

    


Ответы

Ответ 1



Используйте Aggregation Framework и оператор $group: db.test.aggregate([ { $group: { _id: "$code", "items": { $push: { "_id": "$_id", "title": "$title", "category": "$category", "pubDate": "$pubDate" } } } } ]) Результат запроса: [ { "_id" : "ZZZ", "items" : [ { "_id" : ObjectId("56e17f2db292c9151a8b459b"), "title" : "test title", "category" : "test category", "pubDate" : "1457599100" }, { "_id" : ObjectId("56e17f2db292c9151a8a459b"), "title" : "test 2 title", "category" : "test 2 category", "pubDate" : "1457599200" } ] } ] Полученный результат слегка отличается от запрошенного, но, в целом, можно настроить его, поработав с $project.

воскресенье, 8 марта 2020 г.

Выбор БД для проекта с сложной структурой данных

#база_данных #django #nosql


Начал делать проект на Django. Имеются следующие данные в JSON (привожу часть структуры,
остальное повторяется):

[{"name": "Hydrogen", 
 "atomic_number": 1, 
 "symbol": "H", 
 "thermal": 
      {"absolute_boiling_point": { 
           "value": 234, 
           "unit": "K"}, 
       "heat_of_vaporization": {
           "value": {"p": 4, "M": 0.452, "n": 10},  
           "unit": "kJ/mol"}}}]


Для наглядности:



Видно, что структура довольно сложная и многократно вложенная.

Элемент обладает свойствами без группы (типа, Name, symbol, atomic_number, которых
около десяти и они являются общими для всех элементов) и группами свойств (групп имеется
несколько десятков, в каждую из которых входит также несколько десятков свойств).

Как видно значение свойств может быть представлено строкой, десятичным число и инженерной
записью (для которой используется три числа - мантисса, основание, степень)

Возникла проблема - я не могу описать эту структуру через реляционную БД проекта
(postgresql), не могу установить связи.

Подойдет мне реляционная БД? Или следует обратить внимание на noSQL решения? Правильные
я выбрал инструменты для реализации проекта? 

Создал модели для элемента 



class Element(models.Model):
    class Meta:
        verbose_name = 'Element'
        verbose_name_plural = 'Elements'

    name = models.CharField(verbose_name="Name", max_length=255, blank=True, null=True)
    symbol = models.CharField(verbose_name="Symbol", max_length=255, blank=True,
null=True)
    




Различных форм записи



class ScientificNotation(models.Model):
    class Meta:
        verbose_name = 'Scientific Notation'

    significand = models.FloatField(verbose_name="Significand", blank=True, null=True)
    base = models.IntegerField(verbose_name="Base", blank=True, null=True)
    exponent = models.IntegerField(verbose_name="Exponent", blank=True, null=True)
    unit = models.CharField(verbose_name="Unit", max_length=255, blank=True, null=True)






class DecimalNotation(models.Model):
    class Meta:
        verbose_name = 'Decimal Notation'

    value = models.FloatField(verbose_name="Value", blank=True, null=True)
    unit = models.CharField(verbose_name="Unit", max_length=255, blank=True, null=True)




Группы свойств. С этой моделью и возникает проблема. 



class ThermalProperties(models.Model):
    class Meta:
        verbose_name = 'Thermal properties'
        verbose_name_plural = 'Thermal properties'

    element = OneToOneField(Element)
    melting_point = ForeignKey(ScientificNotation)
    boiling_point = ForeignKey(ScientificNotation)
    heat_of_vaporization = ForeignKey(DecimalNotation)




Я не могу ссылаться на одну и ту же модель (в конкретном примере ScientificNotation)

 ERRORS:
 table.ThermalProperties.boiling_point: (fields.E304) Reverse accessor for 'ThermalProperties.boiling_point'
clashes with reverse accessor for 'ThermalProperties.melting_point'.
 HINT: Add or change a related_name argument to the definition for 'ThermalProperties.boiling_point'
or 'ThermalProperties.melting_point'.


И продублирую вопрос здесь, если кто-то дочитал. Подойдет мне реляционная БД? Правильные
я выбрал инструменты для реализации проекта? 
    


Ответы

Ответ 1



Хороший вопрос, я даже рад пожертвовать час на написание ответа :) Как бы не громко звучал заголовок, но эта структура больше простая, чем сложная. Реляционная структура Почти любую структуру можно описать в реляционной базе данных, хоть она и будет достаточно жетской Прошу заметить, что в реляционных базах данных тоже есть патерны проектирования, и давайте попробуем сначала реализовать один из правильных патернов, называющихся Class Table Inheritance. Он гарантирует размещение разных элементов в разных таблицах, в которых они должны находится: element - структура для элементов name atomic_number symbol element_thermal - структура для параметров atomic_number type unit element_thermal_mol - структура для параметров mol/kg atomic_number p M n element_thermal_value - структура для обычных параметров atomic_number value Здесь в зависимости от unit'а требуется выбирать таблицу, которую нужно будет делать JOIN. Мы здесь используем подход разделения данных на таблицы, который полностью соответствует реляционной структуре и ее правилам, но с каждым новым типом и данными Вам придется добавлять новую таблицу и усложнять сохранения и бизнес логику. Ок. Попробуем подход Entity-Attributes-Values (EAV), его часто называют анти-паттерном проектирования из-за отсутствия контроля типа, контроля данных, размещения данных в одной таблице и т.д и вообще это выворачивание реляционной структуры наизнанку, но сам подход на небольших данных достаточно хорошо себя проявляет. element - структура для элементов name atomic_number symbol element_thermal - структура для параметров atomic_number type unit element_thermal_values - структура для всех параметров atomic_number parameter_type value По сути, здесь все свои значения параметров вы храните в element_thermal_values записывая в parameter_type название параметра (INT, P, M, N), после чего делайте JOIN этой таблицы и получаете все параметры и обрабатываете их, запрос на получение данных всегда один, но естественно контроль должен быть обеспечен на уровне кода. На маленьком проекте не будет разницы в том, что вы выберете, второй вариант просто проще, первый правильнее. Да по сути, можно вообще не создавать отдельную таблицу, а просто запихнуть данные в value в виде json, просто с ними нельзя будет работать и как-то выполнять запросы, поэтому этот подход не всегда правильный, хотя базы типа PostgreSQL позволяют производить какие-то операции на уровне JSON. NoSQL (Неструктурированные базы) Хотите использовать noSQL, используйте. Никто Вас в этом не ограничивает и ваша структура, в некоторой степени являющейся динамичной, будет подходить для MongoDB, когда вы будете использовать все прелести документ-ориентированного подхода. Сам ваш элемент выглядит как документ. Если у данных нет связей или их очень мало с другими данными, то в целом NoSQL (MongoDB) отличный выбор для вашей задачи и сможет упростить в некоторой степени работу с данными. В целом размер кода будет примерно одинаковый, т.к. обработчики на value при выводе или процессинге все равно придется писать. Вывод Я рекомендую Вам попробовать несколько подходов, начните с нового MongoDB, потом попробуйте грамотное наследование в реляционных таблицах, сравните плюсы и минусы тех или иных реализаций и посмотрите что подходит для вас, опыта меньше не станет. MongoDB заинтересует Вас тем, что это база данных по сути в которой данные хранятся в виде доступном приложению (JSON) и изменяемой структурой данных, которая тоже имеет плюсы и минусы, из плюсов конечно еще масштабируемость. Старый подход на SQL отлично решает вопросы построения систем, где нужна целостность данных, соблюдение ACID, тяжелые запросы на объединение с многими таблицами. В двух подходах есть минусы и плюсы, в своем случае, если бы я писал систему которая содержала периодическую таблицу и мне хотелось бы пощупать новые технологии, я бы взял MongoDB и познал бы Map-Reduce и т.д. Мы часто используем Mongo для данных, чью структуру тяжело предусмотреть, например логирование в виде истории действий пользователя с различными типами параметров, конечно было бы хорошо запихнуть это в MySQL, но желания создавать отдельную таблицу под определенные данные просто нет, а использование подхода EAV на большом объеме данных просто уничтожает всю производительность, в MongoDB же есть хорошая масштабируемость и изменяемая структура данных, поэтому плюсы перевешивают минусы.

Ответ 2



Подойдет мне реляционная БД? Да вполне подойдёт. У каждого элемента будет сотни свойств и десятки групп, в которые эти свойства вложены. (часть принадлежит самому элементу, часть группам свойств, которые в свою очередь принадлежат элементу) Ваша задача выглядит как задача про отношения. То есть, я считаю, что реляционная БД подойдёт лучше, чем нереляционная. Правильные я выбрал инструменты для реализации проекта? Всегда есть несколько способов решить одну и ту же задачу. Как видно значение свойств может быть представлено строкой, десятичным число и инженерной записью (для которой используется три числа - мантисса, основание, степень) Можно ещё решить задачу с помощью фреймворка для обобщённых связей в django Я не могу ссылаться на одну и ту же модель (в конкретном примере ScientificNotation) Ну естесственно не можете. ForeignKey определяет отношение один-ко-многим, между таблицами(объектами), а вы зачем-то попытались определить его два раза к одной таблице. Можно было, например, сделать дополнительную таблицу. Вариантов решения вашей задачи не один. У вас есть элемент, и способы его записи. Разные типы записей можно реализовать через классы. class Element(models.Model): class Meta: verbose_name = 'Element' verbose_name_plural = 'Elements' name = models.CharField(verbose_name="Name", max_length=255, blank=True, null=True) symbol = models.CharField(verbose_name="Symbol", max_length=255, blank=True, null=True) class DecimalNotationElement(Element): # Наследумеся от элемента! """ Наследуясь от Element, в Джанге, автоматически создаётся отношение один_к_одному. """ class Meta: verbose_name = 'Decimal Notation' value = models.FloatField(verbose_name="Value", blank=True, null=True) unit = models.CharField(verbose_name="Unit", max_length=255, blank=True, null=True) # Работать будет так: element = DecimalNotationElement.objects.create( name="lalala", symbol="S", value=num, unit="some unit" ) # То есть просто обращаемся к нужному полю, и уже не играет # роли что поля из разных классов. >>>element = DecimalNotationElement.objects.get(name="lalala") >>>element.name >>>'lalala' >>>element.unit >>>'some unit'

понедельник, 24 февраля 2020 г.

Когда выбирать реляционную БД, а когда не реляционную?

#mysql #база_данных #mysqli #nosql


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



подВопрос:
Как поступить: пока не заморачиваться над этим и потом, при необходимости, перенести
данные в не реляционную БД ИЛИ выбрать реляционную/не реляционную БД ?
    


Ответы

Ответ 1



Подумал о том, что при большом объёме записей БД будет долго обрабатывать запрос Планирование не может начинаться с "подумал", боттлнеки всегда бывают в иных местах. Реляционки спокойно работают с миллионами записей. поэтому надо её раскинуть на несколько серверов. но вычитал, что реляционные БД плохо масштабируются Тут у меня опять претензия в ту же степь. Вы не знаете, что именно вы вычитали. Они действительно плохо масштабируются из-за того, что (по крайней мере у большинства) есть только одна модель master-slaves, которая упирается в мастер по скорости записи (поправьте, если есть популярные движки с многочисленными мастерами). В любом случае в базе данных не должно быть тяжелых подсчетов - если вы считаете количество записей в БД, то это должно рассчитываться внутри БД и кэшироваться на уровне приложения, если вы рассчитываете аналитику, то тут БД уже ничего считать не должна. В общем, у меня большие сомнения, что вам нужна масштабируемая система. Что до нереляционок, то их нельзя выбрать просто потому что "лучше масштабируются" - их только основных типов четыре штуки под свои задачи (вряд ли вы будете использовать key-value или графовую БД). Что до масштабирования, то есть row-column (т.е. хранение данных практически как в SQL) Cassandra, которая шардит данные по узлам и имеет практически линейную масштабируемость, т.е. добавление сервера в кластер из N серверов обеспечивает практически 100 * (1 / N + 1) процентов прироста производительности. Если есть знание кассандры, то делать проект на чем-то другом я не вижу смысла (единственная претензия - отсутствие готовых утилит для миграций, но это, надеюсь, изменится), классические реляционки как концепция по факту уже умерли - они, конечно, останутся, но в узком применении, и ближайшие N лет их популярность будет снижаться.

Ответ 2



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

Ответ 3



Если хочешь всех удивить возьми nosql Если хочешь блеснуть знанием старины возьми сетевую БД Если хочешь получить благодарность с того света от бабушки Ады - возьми иерархическую БД Ну и наконец, если хочешь написать что-нибудь стоящее возьми реляционную БД

четверг, 13 февраля 2020 г.

Разработка высоконагруженного API [закрыт]

#php #sql #api #nosql


        
             
                
                    
                        
                            Закрыт. На этот вопрос невозможно дать объективный ответ.
Ответы на него в данный момент не принимаются.
                            
                        
                    
                
                            
                                
                
                        
                            
                        
                    
                        
                            Хотите улучшить этот вопрос? Переформулируйте вопрос,
чтобы на него можно было дать ответ, основанный на фактах и цитатах, отредактировав его.
                        
                        Закрыт 3 года назад.
                                                                                
           
                
        
Здравствуйте.

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

Какие технологии лучше всего использовать при разработке высоконагруженного API-сервиса?
Допустимо ли использование "PHP" в качестве основного языка, или здесь непременно должен
иметь место "NodeJS"/"Ruby"? Если да - то почему? Каковы минусы и плюсы SQL- и NoSQL-СУБД
применительно к планируемой нагрузке? Какие средства кэширования редкообновляемой информации
лучше всего использовать?

Заранее благодарю за ответы.
    


Ответы

Ответ 1



Допустимо ли использование "PHP" в качестве основного языка, или здесь непременно должен иметь место "NodeJS"/"Ruby" Это все платформы одного порядка. С чуть большими возможностями у последних двух, но задаваться нужно вопросом выбора между "интерпретируемым языком общего назначения" и java-scala, c# и какими-то менее мейнстримовыми, о которых я не вспомнил. Упомянутые интерпретируемые (так уж повелось) более толерантны к ошибкам, временами сложнее в дебаге и проще в обновлении и непосредственно написании, упомянутые компилируемые нетерпимы к ошибкам, но имеют как желаемый прирост скорости, так и зачастую более интересный API. Какие технологии лучше всего использовать при разработке высоконагруженного API-сервиса? Те, которые отвечают вашим требованиям. Написать API, которое вытаскивает данные тысячу раз в секунду - не проблема, проблема - решить реальную бизнес-задачу. Пока неизвестно, что там, можно только гадать, где реально нужно стелить соломы, а так какая-нибудь связка php-mysql-redis спокойно сможет выдерживать эти пресловутые тысячи запросов и масштабироваться без кряхтения. В случае, если у вас начинается более интересная игра, начинают требоваться распределенные блокировки, сиюсекундное обновление кеша на всех хостах, параллельное перемалывание задачи на всех хостах без известности о том, сколько этих хостов и вообще прямой коммуникации между ними - тут начинается беда, которую надо разгребать конкретными решениями. Самая большая проблема, которая стоит перед разработкой этого сервиса - это shared-nothing архитектура, которая не предполагает закрепление за отдельным узлом какого-либо состояния, состояние хранится в базе данных. На первый взгляд кажется, что это условие и так выполняется, на практике все начинает выползать: при загрузке файла прогресс загрузки этого файла должен быть виден на всех узлах разом, кэширующий слой должен быть соединен воедино, чтобы все клиенты кэша видели одно и то же, простая блокировка ресурса превращается в целое приключение. Этому сложно научиться, не набив себе шишек, поэтому чем раньше вы присутпите к написанию на чем угодно и выкладке на несколько узлов, тем раньше прочувствуете эту проблему. Каковы минусы и плюсы SQL- и NoSQL-СУБД применительно к планируемой нагрузке? Как я уже написал, у SQL нет плюсов. По сравнению с NoSQL-решениями есть такая штука, как джойн, но от него отказались вполне сознательно, и он чаще вредит, чем помогает. Принципиальная разница для поставленной задачи в масштабировании: практически любое NoSQL-решение предлагает возможность горизонтального расширения из коробки, в то время как SQL этого не умеет. Перед тем, как вообще бросаться в выбор базы данных, надо понять, что от нее требуется. Кроме стандартного жестко стркутурированного типа SQL-совместимых баз данных есть четыре основных типов баз данных NoSQL: key-value (грубо говоря, доступ исключительно по первичному ключу без возможности осуществлять выборки), row-column (очень похоже на SQL, но, конечно, совершенно иная вещь под капотом), документоориентированные (т.е. без жестко заданной структуры) и графовые (предназначенные для работы со сложными связями). У вас, судя по всему, выбор стоит между документоориентированной и row-column БД: тут нельзя сказать что-то конкретное, и выбор остается за вами. Могу только сказать, что из row-column предпочтение обычно отдается Cassandra, а в документоориентированных любят монгу, но я слышал про нее довольно печальные отзывы (и в текущем проекте по ряду причин выбрали rethinkdb). Кроме всего это стоит помнить (и изучать) тот факт, что вся система теперь превращается в распределенную, и теперь у нее есть все любимые проблемы распределенных систем, в том числе разрыв сети и несинхронное обновление данных на разных узлах. Тут можно много сказать про проблемы производительности, про возможные подводные камни, но на самом деле все упирается банально в то, насколько хорошо ваша платформа масштабируется, и можете ли вы выкатить новый сервак в течение дня, потому что даже самый идеальный бэкенд имеет пропускной предел. Единственное, про что еще хотелось бы сказать - это то, что переход на распределенные системы, как правило, требует еще и смены парадигмы pull-on-demand на push-on-change.

Ответ 2



Вы можете разработать такой сервис на любой технологии, в том числе с использованием PHP. Поставив рядом несколько серверов, вы можете практически бесконечно масштабировать операции чтения за счет репликации (как на уровне СУБД, так и на уровне NoSQL-решений). Проблемы начинаются, когда у вас очень много одновременных соединений, даже если вы можете под каждый из них выделить отдельный поток-запрос. Просто их так много, что процессор переключаясь между ними начинает терять слишком много времени. Так как вы работаете для мобильных приложений, у вас может быть очень не важная связь с клиентом, а значит много медленных клиентов. Чем страшен медленный клиент для классического сервера? Пусть у вас сервер может держать 1000 одновременных запросов, подключаются к вам 500 клиентов с EDGE и начинают в течение 10 минут ждать ответа. И вот у вас уже сервер обслуживает не 1000, а 500 одновременных запросов. Так как 500 повисли в ожидании ответа от клиентов. Оставшиеся соединения начинают не справляться, отдавать запросы медленнее, и вот у вас сервер может обслуживать только 250 запросов. А через некоторое время и вообще грохается. Это может не так актуально для Web, где клиенты в массе пошустрее, но в мобильной разработке это более частое явление – покрытие везде разное, связь от него зависит здорово. Когда говорят о NodeJS или серверах Ruby – там ничего волшебного нет, просто сервера более новые и проектировались немного по-другому. Вместо того, чтобы ждать каждое соединение отдельным запросом организуется один поток, который опрашивает соединения в неблокирующем режиме. Пришел ответ от клиента – он его обрабатывает, нет - пошел к следующему соединению. Этим убивается два зайца. Вы не переключаетесь между потоками/процессами (экономите время), вы решаете проблему медленных клиентов – у вас поток не ждет, он постоянно работает. Проблема только чтобы у вас сервер-сторона не тормозила, так как опрашивающий поток один. Это Event Driven архитектура, можно найти решения и для PHP. Просто в случае NodeJS или Ruby они идут чуть не из коробки, в случае PHP придется поискать решение. Однако, какой бы вы язык не выбрали, разобраться с этим важно. Event Driven архитектура позволяет вам задействовать WebSocket-ы, постоянные соединения от клиентов – вы можете позволить их сколько угодно, так как соединение в ожидающем режиме почти не расходует никаких ресурсов (ни памяти, ни процессора). И вот мы плавно подходим к тому, как вы будете писать. Даже если вы не используете EventDriven-решения, а поставили рядом много классических fork-серверов, реплицировали данные на уровне базы данных, у вас все равно остается проблема с записью, так как она не масштабируется репликацией. Вам нужно очень быстро писать, чтобы клиент не ждал ответа от сервера, не держал соединение, а шел по своим делам. Чем быстрее вы будете их обслуживать – тем вам будет проще. Писать непосредственно в базу данных – не вариант. Классические СУБД очень медленные и неторопливые, норовят все в транзакциях выполнять, а это тоже накладные расходы. Есть два пути – быстрое NoSQL-решение полностью распложенное в оперативной памяти (redis, MongoDB). Быстро записали в память, отпустили клиента, в фоне разбираемся, записываем. Очереди – позакидали все в очередь, в фоне не спеша события из очереди обрабатываются. Было бы здорово, если часть информации преобразовывалась, агрегировалась непосредственно в оперативной памяти и лишь потом поступала в медленную базу данных "оптом". Чем хороши современные NoSQL-решения – они почти все написаны с учетом неблокирующих соединений и могут держать тысячи одновременных соединений. Чем плохи – это не классическая СУБД, там сложно организовывать связи и ассоциации, вообще нужно работать немного по другому. В них плохо с транзакциями. Однако, они расположены в оперативной памяти и отлично кластеризуются. Принимать в них данные одно удовольствие – это не сурогат из 100 таблиц с последующим слиянием в СУБД, чтобы писать данные было проще, и не геморройная кольцевая архитектура в репликации. В общем на практике обычно используется все, что вы упомянули, можно часть написать на PHP, с WebSocket-ами вам возможно будет удобнее работать через NodeJS-сервер, очереди и PubSub-решения возможно будет проще организовать через Redis или RabbitMQ, "сырые" данные положить в то же Reids или MongoDB, а в качестве долговременного резервируемого хранилища использовать классическую СУБД (хотя можно вообще без классической СУБД обойтись). Если вы доведете свое API до заявленных нагрузок, вам скорее всего придется попробовать если не все, то почти все :)

пятница, 24 января 2020 г.

MongoDB - тормоз вставки после 5000000 записей

#java #база_данных #mongodb #nosql #mongodb_query


Всем привет. В общем проблема такая: Проект на JAVA и есть NoSQL DB - MongoDB, необходимо
работать примерно с 1000000000 записей. Вставка, в пустую таблицу, 5000000 записей,
происходит за 13-15 мин, но после вставки 5000000 дальнейший процесс вставки начинает
тормозить и чуть ли не в геометрической прогрессии и ОЗУ начинает пожирать немерено.
Приоритетной задачей этой БД является поиск (скорость поиска на 10000000 - удовлетворяющая)  

Вопрос: 


Почему так происходит?  
Как это исправить?


Возможные варианты решения:


Каждые 5000000 записей - создавать новую таблицу?
Оптимизация индексов? (у меня поиск по id)
Оптимизация конфига MongoDB?
Оптимизация системы?
Замена БД?


Заранее благодарен за ответ!
    


Ответы

Ответ 1



У меня был похожий случай когда я работал с SQLite. Приходилось перейти на MySQL. Но для миллиарда записей по моему вам надо будет перейти уже на BigTable. Например, на Hadoop, HBase или Cassandra. Насчет Cassandra если честно не уверен, потому что Facebook сам перешел от Cassandra на HBase хотя сами разработали ее. bigtableбаза-данных

воскресенье, 12 января 2020 г.

Выбор модели данных для часто меняющихся требований по форматам

#sql #база_данных #nosql


Задача состоит в том, чтобы формировать пользовательские данные в XML виде. XSD схема
для этих файлов часто меняется, заказчик выпускает новые форматы (меняются типы, иерархия
и т.д.)

Какую модель бд лучше использовать в данном случае: классическую реляционную, или
документарную (NoSQL)?
    


Ответы

Ответ 1



Не совсем ответ, скорее размышления. У нас сейчас аналогичная задача. Приходят на обработку финансовые документы в виде XML, форматов много, периодически выходят новые версии. Хранить как-то надо. У нас Oracle+Java, так что выбора в пользу No SQL особо не было:) На пути к сохранению идёт два преобразования: XML -> Java объект(JaxB) -> Java объект в нашем внутреннем формате, который ложится в РСУБД. Есть некоторый абстрактный класс А, который содержит в себе общие поля для всех документов(дата, инициатор, счета и прочее) Для разных типов документов создаются наследники А (В1 В2 В3), и для их хранения создаются таблицы, которые содержат поля из А и дополнительно поля из В1 В2 В3. Средствами наследования различаем типы документов. В чем плюс? Можно строить составные индексы по полям как из класса А так и из В. Различия версий одного типа документа (если появляются новые поля итп) дополняются хвостами (ссылки из B на объекты классов B11 B12 B13), которые имеют связь с В1 один к одному в случае с таблицами. Т.е. для новой версии мы не меняем структуру данных, а добавляем новые сущности, при том что бОльшая часть алгоритмов продолжает успешно работать с любыми версиями без изменений. У нас всё несколько строго ещё и из-за того, что Java объекты хранятся в IMDG(хранение ВСЕХ данных в оперативной памяти грида), и в будущем планируется отказ от Oracle как от персистентного хранилища в пользу No SQL. Т.е. РСУБД уйдёт, а структура хранения Java-объектов в IMDG останется. Я говорил не столько о выборе между РСУБД и No SQL, а о борьбе с меняющимися форматами данных и их хранении. Надеюсь сказал что-то полезное.:)

четверг, 2 января 2020 г.

В каких случаях NoSQL базы явно лучше Relational Databases?

#база_данных #java #nosql #sql


Вопрос простой.
В каких случаях разработчик должен смотреть на нереляционные базы?
Java, Web.    


Ответы

Ответ 1



Есть мнение, что разработчик должен смотреть на структуру данных, которые он хочет хранить. И потом, исходя из этого, уже выбирать где это будет удобнее хранить. Если все сведется к тому, что данные легко и очевидно ложатся на key-value — вот и случай, когда реляционные БД не будут нужны (будут избыточны). Например, если все что надо держать в БД — текущие прогнозы погоды по городам или сессию со списком-историей последних просмотренных, ходящим по видеохостингу пользователем, клипов, то что-то типа memcached или Redis будет вероятно близко к оптимальному решению. Обратный подход (есть БД, нужно запихать в нее определенных данные) имеет смысл если речь идет о уже имеющейся инфраструктуре. Там неудобства разработки компенсируются неудобством введения и обслуживания новых элементов (еще одной БД) в уже имеющуюся инфраструктуру.

Ответ 2



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

вторник, 17 декабря 2019 г.

Выбор key-value storage

#cpp #nosql


Необходимо обеспечить доступ к набору данных вида (key, value) где key - числовой
идентификатор, а value - динамический массив. На С++ я описал бы структуру так:
typedef struct {
    int id;
    int time;
    double value;
} item;

typedef std::unordered_map > my_storage;

Но, к сожалению датасет не помещается в оперативную память. Поэтому нужно выбрать
какое-то хранилище данных. Задача имеет следующие особенности:

Длина динамических массивов распределена экспоненциально (половина массивов вообще
состоят из одного элемента).
Хранилище заполняется постепенно: данные вида std::pair поступают
отсортированные по полю item.time и добавляются в конец соответствующего динамического
массива.
Хранилище должно обеспечивать операции двух видов: чтение целого массива по ключу
и добавление одного элемента в конец соответствующего ему массива
Вероятность обращения к конкретному массиву зависит от поля item.time последнего
элемента массива (тоже экспоненциально). Так как каждый массив отсортирован по возрастанию
item.time, можно сказать, что вероятность обращения зависит от времени последнего обращения
к нему.

Я нагуглил несколько вариантов таких хранилищ: LevelDB, Berkeley DB, Kyoto Cabinet...
Даже бенчмарк нашел: 
Требования к базе такие:

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

Данных будет где-то 50-200 Gb (это если слепить в один массив все структуры типа item).
Ну, собственно, прошу помочь тех, кто  работал с перечисленными выше БД. Или, может,
что-нибудь другое предложите?
UPD:
Забыл добавить, что задание скорее учебное, поэтому ни транзакции, ни конкурентный
доступ с большого числа клиентов, ни постоянная синхронизация не нужны.
Нашел еще решение: HDF5. Позиционируется как раз, как хранилище для научных данных.
Кто работал с ним, можете прокомментировать?
Еще хотел спросить у знающих людей, какие FS + mount options использовать, чтобы
избежать ненужного журналирования?    


Ответы

Ответ 1



Я бы использовал LevelDB, но со сложным ключом (основной идентификатор + номер в массиве или time), чтобы значением был только один элемент, а не массив. Поскольку в LevelDB данные отсортированы по ключу, то можно пробежаться по следующим/предыдущим ключам и получить весь массив.

Ответ 2



То, что Вы превели, в качестве примера - не предназначенно для этого, как минимум, будет очень медленно. Для таких объемов, скорее что-то на https://ru.wikipedia.org/wiki/Hadoop с https://ru.wikipedia.org/wiki/Apache_Cassandra.

пятница, 13 декабря 2019 г.

Go для масштабного веб-проекта

#golang #nosql #sql


Здравствуйте. Хоть у меня вопрос по го, вкратце расскажу свой путь разработчика.
Да, и еще, чтобы быть полностью откровенным упомяну: мне 16 лет. Программированием
я заинтересовался в 9 лет, и с тех пор не могу оторваться. Дело в том, что я не из
той "школоты", которые клипают один за одним сайты на вордпрессе, или пишут 88код на
php + html. Я прошел такой путь: pascal(месяца три, помог мне с основами программирования)
-> html, css, php -> c(три года назад) -> c++(спустя два месяца после начала обучения
си решил, что целесообразнее будет учить плюсы) -> java (после того, как постиг основы
ооп; в джаве после того, как через месяцев 7 захотелось познакомиться с EE, сразу перехотелось
вообще учить дальше; оно было очень громоздкое) -> php -> python (плюс немного Django)
-> php(с питоном дела шли еще не очень хорошо, а понадобилось написать систему тестирования
на тысячи две с половиной строк кода для школы) -> RoR(фреймворк потрясающий, но перестал
его рассматривать так как: проблемы с производительностью, он популярен сейчас, а такое
не будет продолжаться вечно, а мне еще учится) -> Play framework + Scala(все шло очень
хорошо, еще один веб проект, пока не дошло до углубления в скалу; хоть язык мне и понравился,
но: он слишком сложный - это раз, в нем слишком много возможностей, приходится выбирать,
не знаешь какая лучше; проблемы с concurrency по сравнению с го) -> и вот, наконец,
го. Он мне сразу понравился. 
И вот, после двух с половиной месяцев изучения го у меня вопрос: я хочу написать
масштабный веб проект. я буду его писать не в одиночку, но за бэкенд буду отвечать
только я. Во всяком случае, на первых порах. Проект совершенно новый, аналогов ему
нету. Не буду раскрывать идею, скажу только что будут частые запросы базы данных. Информация,
во всяком случае поначалу, будет только текстовая, и немного картинок. Но будет много
запросов к базе данных. Я бы мог написать его на пхп намного быстрее чем на го, но
я хочу не просто написать сайт, я хочу построить именно масштабный веб проект, будто
его будут использовать миллионы людей (хотя так вряд ли произойдет; но зато будет опыт).
Хочу разделить веб приложения на 4 слоя, ну там фронт энд, application logic , back
end, datastorage. Вопрос: могу ли я использовать как серверный язык для такого предназначения
Golang? Даст ли он мне прекрасную производительность, и не будет ли проблем с отсутствием
библиотек или возможностей языка, что приведет к невозможности продолжения написания
проекта?
Какие советы можете дать мне по строению высоконагруженого сервиса? 
И, какую лучше использовать бд: Sql или nosql. В курсе что на хэшход использовали
postgresql, но мало ли. Есть очень неплохие драйвера и для nosql, к примеру Mgo , и
для редиса видел.
Мне очень важно знать ваше мнение.    


Ответы

Ответ 1



могу ли я использовать как серверный язык для такого предназначения Golang? Еще как можете, Go для этого предназначен. Даст ли он мне прекрасную производительность Это только от вас зависит, как напишите так и "поплывет". не будет ли проблем с отсутствием библиотек или возможностей языка Даже затрудняюсь предположить, что-же такое вам может понадобится чего нельзя реализовать в Go? Но вот небольшая подборочка, вполне возможно вам что-то из этого пригодится. https://github.com/bolknote/go-gd https://github.com/go-sql-driver/mysql https://code.google.com/p/go-charset/ https://github.com/andelf/go-curl

Ответ 2



Гм. Странные у Вас выводы. Scala - довольно прост, вообще говоря. RoR - не тормозной, вообще говоря, на нем довольно большие сайты работают. Вы напрасно там быстро прыгаете. Считается, что для того, чтобы понять какой-то инструмент программирования (язык, фреймворк и пр.) как следует - нужно на нем попрограммировать 2 года. Ну при большом таланте - год-полтора. А не три месяца. Но это ваше личное дело, не буду осуждать. Вы видимо, ищите "серебряную пулю"? Волшебный инструмент, который круче других на голову? Таких нет, иначе все другие программисты давно на него бы перешли. Если проект большой, то я предложил бы базироваться на развитом web-фреймворке, не сковывающем особо программиста, например на Pyramid ( http://docs.pylonsproject.org/en/latest/docs/pyramid.html ). Фреймворк поддержит Вас и сэкономит кучу времени. Если речь идет о частых запросах к базе данных, то скорость работы от самого языка программирования бэкэнда не зависит. Если Вы поступите по умному, напишете типичную задачку из своего проекта в виде отдельного теста и проведете замер, то поймете, что процентов 95 (к примеру, может больше, может меньше, но - значительно) времени занимает работа самой базы данных, лежащая за пределами вашего бэкэнда и, следовательно, за пределами языка программирования. По сути скорость зависит от того, как именно Вы работаете с базой данных, как оптимизирована ваша программа под базу данных. Даже простейший банальный кэш на уровне бэкэнда поможет поднять производительность, скорее всего. Более того, даже выбор правильной базы данных под особенности ваших данных позволит поднять производительность до небес. Я бы отсоветовал Вам Go. К нему не так много серьезных фреймворков пока, не так много документации. А его особенности проявляют себя большим плюсом в том случае, если у Вас сложные алгоритмы на стороне бэкэнда, а не работа с базой данных. С Го многое придется писать самому, придумывать самому. Это очень сложно и получить неэффективную систему будет очень просто. Гораздо эффективнее воспользоваться готовыми инструментами, уже имеющимися для других языков. Эти инструменты придется изучить изнутри, полазить в исходном коде, это будет очень полезно для повышения вашей квалификации. Да и время сэкономит. Го-ланг - дает слишком много свободы, и с ним Вы получите ту же проблему, о которой писали выше: "в нем слишком много возможностей, приходится выбирать, не знаешь какая лучше". Кроме того, Ваш выбор усугубится тем, что готовых развитых и отлаженных библиотек и фреймворков - мало. Любому, кто даст конкретный ответ на это, можете плюнуть прямо в глаза: "Какие советы можете дать мне по строению высоконагруженого сервиса? И, какую лучше использовать бд: Sql или nosql. В курсе что на хэшход использовали postgresql, но мало ли. Есть очень неплохие драйвера и для nosql, к примеру Mgo , и для редиса видел." Ибо правильный ответ очень сильно зависит от конкретной архитектуры данных и от конкретной архитектуры системы. Правильные ответы могут быть в каждом конкретном случае очень противоположенные. Для того, чтобы более-менее правильно выбрать базу данных следует проанализировать что там за данные. Что чаще происходит - запись или чтение, в каких масштабах, простые или сложные структуры хранятся, мешают ли пользователи друг другу (один пишет то же, что в это время может читать другой), простые или сложные критерии выборок и куча еще много чего. В общем случае самым лучшим решением для снятия нагрузки с сервера является развитый механизм кэширования и статических (заранее сгенерированных) страниц. Но ни язык программирования ни база данных Вам в этом не поможет. Это только алгоритмы, которые Вы должны придумать самостоятельно под вашу конкретную ситуацию.

Ответ 3



Golang - годная вещь для разработки под web. Всё, что в других языках (веб сервера, печеньки, роутинг, и т.п.) реализовано в виде фреймворков и библиотек, в Golang есть из коробки. Язык очень простой, код получается предельно чистым и понятным. Могу порекомендовать Revel framework (в скором времени ожидается релиз), хотя и предполагаю, что ТС предпочтёт свой велосипед. Тем не менее. Revel - вещь годная. Не будет необходимости заниматься архитектурой базовых вещей (есть, по крайней мере, VC от MVC -- модель нужно притаскивать свою), есть возможность писать модульно, переопределять своими модулями (aka фильтрами) default логику базовых компонентов, да и быстрее на порядок и приятнее, чем свой велосипед (ибо позволяет сконцентрироваться на непосредственно решении задачи, нежели шашечках). А кроме того, нужно посетить баг трекер проекта, глянуть на количество issues (открытых и закрытых), людей принимающих участие в разработке (бессменный Rob & co). Колоссальное количество ресурсов, совместных усилий, общих размышлений и обсуждений. К чему я клоню? Работа одного над тем же самым будет выглядеть убогим подобием. В виде модуля в master ветке с недавних пор лежит компонент для работы с БД, поддерживаются: sqlite, mysql и postgres. В качестве ORM (хотя это не совсем ORM в классическом понимании) можно использовать gorp. Или его форк -- modl. Для примера использования первого - см. проект booking в репозитории revel, директория examples. Для любителей MongoDB г-н Jeff написал модуль для интеграции Revel с этой БД, называется (неожиданно) -- revmgo. Как образец использования могу порекомендовать приложение bloggo от этого же автора на github'е. Использовать можно что угодно, зависит от задач. Я в процессе реализации своего сервиса на Revel пришёл в выводу, что MongoDB - это, наверное, круто (так, по крайней мере, было, когда приходилось работать с Node.js), однако, Postgres решает поставленную задачу проще. Приложение было переписано. Узким горлышком в веб проектах, как правило, является БД. Однако, на этапе, когда имеется лишь идея проекта, производительность абсолютно не важна. В случае успешного проекта, к этому можно всегда вернуться, решить проблему. Кроме того, Revel включает, например, стандартный модуль кеширования: его можно использовать для временного хранения информации, которую долго доставать из базы при каждом запросе (по умолчанию для хранения используется RAM, однако, для этого легко может быть преспособлен кластер memcached или redis; возможность предусмотрена из коробки). Итак, проблемы с отсутствием библиотек - маловероятны. Язык статически типизируемый, компилируемый. Производительность ожидается высокой, потребление памяти - небольшим. На простроении высоконагруженного сервиса в вакууме фокусироваться не нужно. Лучше сервис, который просто работает, чем тот, который работает на несколько милисекунд быстрее, но только в теории ибо его ещё нет.

Ответ 4



Golang для вашего проекта подойдет отлично. Как раз для подобного и разрабатывался. Лучше использовать MognoDb, есть отличный драйвер для Go - mgo.

Ответ 5



Если есть опасения что не хватит библиотек, то уверяю, их уйма. Регистрируйся на github и bitbucket и вперёд, при поиске выбирай язык GO и на любой вопрос будут разработки и либы :) У нас в проекте в осномном mysql использовался, я сам знаю 5 библиотек под него. Сейчас потребовался потгрес, с ходу нашлось три библиотеки. Даже apache cassandra, казалось бы экзотика, но либа уже написана и прекрасно работает...

среда, 11 декабря 2019 г.

База данных для статистических данных

#база_данных #nosql #highload #статистика #big_data


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


id источника
значение
дата/время


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


Какая база данных лучше всего вписывается в эту задачу и почему?
Подойдут ли облачные NOSQL хранилища (Google, Amazon, Azure), или дешевле поднять
свой сервер с БД из ответа №1?

    


Ответы

Ответ 1



ИМХО. NoSQL - не подойдут от слова "вааще". Они заточены по совсем другой, более "вариабельный" тип данных. При вашей простой структуре вам нужна именно реляционная база данных, так как данные из большого количества источников - то что то серверное: MSSQL, MySQL, Oracl - скорее всего любая из них справится.

Ответ 2



Если у вас данных ОЧЕНЬ много (сотни гигабайт-терабайты/день), то посмотрите на Hadoop, там можно хранить много и считать быстро. Если же данных меньше - то стоит использовать PostgreSQL, Oracle, MS SQL. NoSQL - это не о том, он скорее о слабо структурированных данных, так что в вашем случае это просто не нужно.

вторник, 28 мая 2019 г.

Выбор БД для проекта с сложной структурой данных

Начал делать проект на Django. Имеются следующие данные в JSON (привожу часть структуры, остальное повторяется):
[{"name": "Hydrogen", "atomic_number": 1, "symbol": "H", "thermal": {"absolute_boiling_point": { "value": 234, "unit": "K"}, "heat_of_vaporization": { "value": {"p": 4, "M": 0.452, "n": 10}, "unit": "kJ/mol"}}}]
Для наглядности:

Видно, что структура довольно сложная и многократно вложенная.
Элемент обладает свойствами без группы (типа, Name, symbol, atomic_number, которых около десяти и они являются общими для всех элементов) и группами свойств (групп имеется несколько десятков, в каждую из которых входит также несколько десятков свойств).
Как видно значение свойств может быть представлено строкой, десятичным число и инженерной записью (для которой используется три числа - мантисса, основание, степень)
Возникла проблема - я не могу описать эту структуру через реляционную БД проекта (postgresql), не могу установить связи.
Подойдет мне реляционная БД? Или следует обратить внимание на noSQL решения? Правильные я выбрал инструменты для реализации проекта?
Создал модели для элемента
class Element(models.Model): class Meta: verbose_name = 'Element' verbose_name_plural = 'Elements' name = models.CharField(verbose_name="Name", max_length=255, blank=True, null=True) symbol = models.CharField(verbose_name="Symbol", max_length=255, blank=True, null=True)
Различных форм записи
class ScientificNotation(models.Model): class Meta: verbose_name = 'Scientific Notation' significand = models.FloatField(verbose_name="Significand", blank=True, null=True) base = models.IntegerField(verbose_name="Base", blank=True, null=True) exponent = models.IntegerField(verbose_name="Exponent", blank=True, null=True) unit = models.CharField(verbose_name="Unit", max_length=255, blank=True, null=True)
class DecimalNotation(models.Model): class Meta: verbose_name = 'Decimal Notation' value = models.FloatField(verbose_name="Value", blank=True, null=True) unit = models.CharField(verbose_name="Unit", max_length=255, blank=True, null=True)
Группы свойств. С этой моделью и возникает проблема.
class ThermalProperties(models.Model): class Meta: verbose_name = 'Thermal properties' verbose_name_plural = 'Thermal properties' element = OneToOneField(Element) melting_point = ForeignKey(ScientificNotation) boiling_point = ForeignKey(ScientificNotation) heat_of_vaporization = ForeignKey(DecimalNotation)
Я не могу ссылаться на одну и ту же модель (в конкретном примере ScientificNotation)
ERRORS: table.ThermalProperties.boiling_point: (fields.E304) Reverse accessor for 'ThermalProperties.boiling_point' clashes with reverse accessor for 'ThermalProperties.melting_point'. HINT: Add or change a related_name argument to the definition for 'ThermalProperties.boiling_point' or 'ThermalProperties.melting_point'.
И продублирую вопрос здесь, если кто-то дочитал. Подойдет мне реляционная БД? Правильные я выбрал инструменты для реализации проекта?


Ответ

Хороший вопрос, я даже рад пожертвовать час на написание ответа :)
Как бы не громко звучал заголовок, но эта структура больше простая, чем сложная.
Реляционная структура
Почти любую структуру можно описать в реляционной базе данных, хоть она и будет достаточно жетской
Прошу заметить, что в реляционных базах данных тоже есть патерны проектирования, и давайте попробуем сначала реализовать один из правильных патернов, называющихся Class Table Inheritance. Он гарантирует размещение разных элементов в разных таблицах, в которых они должны находится:
element - структура для элементов
name atomic_number symbol element_thermal - структура для параметров
atomic_number type unit element_thermal_mol - структура для параметров mol/kg
atomic_number p M n element_thermal_value - структура для обычных параметров
atomic_number value
Здесь в зависимости от unit'а требуется выбирать таблицу, которую нужно будет делать JOIN. Мы здесь используем подход разделения данных на таблицы, который полностью соответствует реляционной структуре и ее правилам, но с каждым новым типом и данными Вам придется добавлять новую таблицу и усложнять сохранения и бизнес логику.
Ок. Попробуем подход Entity-Attributes-Values (EAV), его часто называют анти-паттерном проектирования из-за отсутствия контроля типа, контроля данных, размещения данных в одной таблице и т.д и вообще это выворачивание реляционной структуры наизнанку, но сам подход на небольших данных достаточно хорошо себя проявляет.
element - структура для элементов
name atomic_number symbol element_thermal - структура для параметров
atomic_number type unit element_thermal_values - структура для всех параметров
atomic_number parameter_type value
По сути, здесь все свои значения параметров вы храните в element_thermal_values записывая в parameter_type название параметра (INT, P, M, N), после чего делайте JOIN этой таблицы и получаете все параметры и обрабатываете их, запрос на получение данных всегда один, но естественно контроль должен быть обеспечен на уровне кода.
На маленьком проекте не будет разницы в том, что вы выберете, второй вариант просто проще, первый правильнее.
Да по сути, можно вообще не создавать отдельную таблицу, а просто запихнуть данные в value в виде json, просто с ними нельзя будет работать и как-то выполнять запросы, поэтому этот подход не всегда правильный, хотя базы типа PostgreSQL позволяют производить какие-то операции на уровне JSON.
NoSQL (Неструктурированные базы)
Хотите использовать noSQL, используйте. Никто Вас в этом не ограничивает и ваша структура, в некоторой степени являющейся динамичной, будет подходить для MongoDB, когда вы будете использовать все прелести документ-ориентированного подхода. Сам ваш элемент выглядит как документ.
Если у данных нет связей или их очень мало с другими данными, то в целом NoSQL (MongoDB) отличный выбор для вашей задачи и сможет упростить в некоторой степени работу с данными.
В целом размер кода будет примерно одинаковый, т.к. обработчики на value при выводе или процессинге все равно придется писать.
Вывод
Я рекомендую Вам попробовать несколько подходов, начните с нового MongoDB, потом попробуйте грамотное наследование в реляционных таблицах, сравните плюсы и минусы тех или иных реализаций и посмотрите что подходит для вас, опыта меньше не станет.
MongoDB заинтересует Вас тем, что это база данных по сути в которой данные хранятся в виде доступном приложению (JSON) и изменяемой структурой данных, которая тоже имеет плюсы и минусы, из плюсов конечно еще масштабируемость.
Старый подход на SQL отлично решает вопросы построения систем, где нужна целостность данных, соблюдение ACID, тяжелые запросы на объединение с многими таблицами.
В двух подходах есть минусы и плюсы, в своем случае, если бы я писал систему которая содержала периодическую таблицу и мне хотелось бы пощупать новые технологии, я бы взял MongoDB и познал бы Map-Reduce и т.д.

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

воскресенье, 12 мая 2019 г.

Когда выбирать реляционную БД, а когда не реляционную?

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

подВопрос: Как поступить: пока не заморачиваться над этим и потом, при необходимости, перенести данные в не реляционную БД ИЛИ выбрать реляционную/не реляционную БД ?


Ответ

Подумал о том, что при большом объёме записей БД будет долго обрабатывать запрос
Планирование не может начинаться с "подумал", боттлнеки всегда бывают в иных местах. Реляционки спокойно работают с миллионами записей.
поэтому надо её раскинуть на несколько серверов. но вычитал, что реляционные БД плохо масштабируются
Тут у меня опять претензия в ту же степь. Вы не знаете, что именно вы вычитали. Они действительно плохо масштабируются из-за того, что (по крайней мере у большинства) есть только одна модель master-slaves, которая упирается в мастер по скорости записи (поправьте, если есть популярные движки с многочисленными мастерами). В любом случае в базе данных не должно быть тяжелых подсчетов - если вы считаете количество записей в БД, то это должно рассчитываться внутри БД и кэшироваться на уровне приложения, если вы рассчитываете аналитику, то тут БД уже ничего считать не должна.
В общем, у меня большие сомнения, что вам нужна масштабируемая система. Что до нереляционок, то их нельзя выбрать просто потому что "лучше масштабируются" - их только основных типов четыре штуки под свои задачи (вряд ли вы будете использовать key-value или графовую БД). Что до масштабирования, то есть row-column (т.е. хранение данных практически как в SQL) Cassandra, которая шардит данные по узлам и имеет практически линейную масштабируемость, т.е. добавление сервера в кластер из N серверов обеспечивает практически 100 * (1 / N + 1) процентов прироста производительности. Если есть знание кассандры, то делать проект на чем-то другом я не вижу смысла (единственная претензия - отсутствие готовых утилит для миграций, но это, надеюсь, изменится), классические реляционки как концепция по факту уже умерли - они, конечно, останутся, но в узком применении, и ближайшие N лет их популярность будет снижаться.

понедельник, 14 января 2019 г.

В каких случаях NoSQL базы явно лучше Relational Databases?

Вопрос простой. В каких случаях разработчик должен смотреть на нереляционные базы? Java, Web.


Ответ

Есть мнение, что разработчик должен смотреть на структуру данных, которые он хочет хранить. И потом, исходя из этого, уже выбирать где это будет удобнее хранить. Если все сведется к тому, что данные легко и очевидно ложатся на key-value — вот и случай, когда реляционные БД не будут нужны (будут избыточны). Например, если все что надо держать в БД — текущие прогнозы погоды по городам или сессию со списком-историей последних просмотренных, ходящим по видеохостингу пользователем, клипов, то что-то типа memcached или Redis будет вероятно близко к оптимальному решению. Обратный подход (есть БД, нужно запихать в нее определенных данные) имеет смысл если речь идет о уже имеющейся инфраструктуре. Там неудобства разработки компенсируются неудобством введения и обслуживания новых элементов (еще одной БД) в уже имеющуюся инфраструктуру.

среда, 31 октября 2018 г.

Go для масштабного веб-проекта

Здравствуйте. Хоть у меня вопрос по го, вкратце расскажу свой путь разработчика. Да, и еще, чтобы быть полностью откровенным упомяну: мне 16 лет. Программированием я заинтересовался в 9 лет, и с тех пор не могу оторваться. Дело в том, что я не из той "школоты", которые клипают один за одним сайты на вордпрессе, или пишут 88код на php + html. Я прошел такой путь: pascal(месяца три, помог мне с основами программирования) -> html, css, php -> c(три года назад) -> c++(спустя два месяца после начала обучения си решил, что целесообразнее будет учить плюсы) -> java (после того, как постиг основы ооп; в джаве после того, как через месяцев 7 захотелось познакомиться с EE, сразу перехотелось вообще учить дальше; оно было очень громоздкое) -> php -> python (плюс немного Django) -> php(с питоном дела шли еще не очень хорошо, а понадобилось написать систему тестирования на тысячи две с половиной строк кода для школы) -> RoR(фреймворк потрясающий, но перестал его рассматривать так как: проблемы с производительностью, он популярен сейчас, а такое не будет продолжаться вечно, а мне еще учится) -> Play framework + Scala(все шло очень хорошо, еще один веб проект, пока не дошло до углубления в скалу; хоть язык мне и понравился, но: он слишком сложный - это раз, в нем слишком много возможностей, приходится выбирать, не знаешь какая лучше; проблемы с concurrency по сравнению с го) -> и вот, наконец, го. Он мне сразу понравился. И вот, после двух с половиной месяцев изучения го у меня вопрос: я хочу написать масштабный веб проект. я буду его писать не в одиночку, но за бэкенд буду отвечать только я. Во всяком случае, на первых порах. Проект совершенно новый, аналогов ему нету. Не буду раскрывать идею, скажу только что будут частые запросы базы данных. Информация, во всяком случае поначалу, будет только текстовая, и немного картинок. Но будет много запросов к базе данных. Я бы мог написать его на пхп намного быстрее чем на го, но я хочу не просто написать сайт, я хочу построить именно масштабный веб проект, будто его будут использовать миллионы людей (хотя так вряд ли произойдет; но зато будет опыт). Хочу разделить веб приложения на 4 слоя, ну там фронт энд, application logic , back end, datastorage. Вопрос: могу ли я использовать как серверный язык для такого предназначения Golang? Даст ли он мне прекрасную производительность, и не будет ли проблем с отсутствием библиотек или возможностей языка, что приведет к невозможности продолжения написания проекта? Какие советы можете дать мне по строению высоконагруженого сервиса? И, какую лучше использовать бд: Sql или nosql. В курсе что на хэшход использовали postgresql, но мало ли. Есть очень неплохие драйвера и для nosql, к примеру Mgo , и для редиса видел. Мне очень важно знать ваше мнение.


Ответ

могу ли я использовать как серверный язык для такого предназначения Golang? Еще как можете, Go для этого предназначен. Даст ли он мне прекрасную производительность Это только от вас зависит, как напишите так и "поплывет". не будет ли проблем с отсутствием библиотек или возможностей языка Даже затрудняюсь предположить, что-же такое вам может понадобится чего нельзя реализовать в Go? Но вот небольшая подборочка, вполне возможно вам что-то из этого пригодится. https://github.com/bolknote/go-gd https://github.com/go-sql-driver/mysql https://code.google.com/p/go-charset/ https://github.com/andelf/go-curl