Сучасна диджитал-освіта для дітей — безоплатне заняття в GoITeens ×
Mazda CX 5
×

УкроСУБД

Підписуйтеся на Telegram-канал «DOU #tech», щоб не пропустити нові технічні статті

Взять все и поделить

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

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

Пока не буду рассказывать что такое Trie, гугль (ну или бубен :) ) в помощь, сейчас мы возьмем лопату и начнем копать фундамент. Первое что нужно понимать, это путь от Key\Value базы данных до документоориентированой Json базы данных ооочень короткий, как не странно. Достаточно нарезать Json на ключи, где ключ это путь к аттрибуту и листьями будут номера документов и вуаля. Отискать все документы по атрибуту будет равно взятие ключа из Key\Value, а это ну ооочень быстро.

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

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

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

Гараж

Теперь оторвемся от теории поисковых алгоритмов и попробуем собрать ядро нашей базы данных. Под капотом у нас расположатся два черезвычайно эффективных высокооборотистых двигателя. Каждый из которых обрабатывает до 10 млн запросов в секунду на 128ми битных ключах. Между прочим это почти в двое быстрее чем в попсовых хештаблицах из меинстримовых фреймворков, или в пять раз быстрее чем реализации бинарных деревьев. Эти два Trie движка зеркалируют друг друга, они как Инь и Янь в нашей красивой и стройной мат модели. Первый позволяет эффективно искать разные документы по всевозможным аттрибутам, второй движок делает экстракт документов по заданому шаблону. Все просто и эффективно. И, небольшой бонус. Каждый добавленный джисон документ в базу индексируется по всем полям. В этом кстате нет ничего удивительного, именно так ведут себя полнотекстовые субд.

Есть подружки

База данных была бы скучна и кодинг был бы мало эффективным, если бы не было к ней ОРМки. В коде мы работаем с бизнесс обьектами и желательно все эти обьекты автоматом конвертить в джисоны, джисоны в ключи, ключи в кей\велью. Потому пришлось по ходу дела запилить и ОРМку под .NET. Вообщем сервер на Си, к нему конектится дот нет клиент. В целом у меня есть несколько небольших бенчмарков на разные задачи, пару иллюстративных задач вроде «Как написать веб форум в 50 строк кода за час», но всё это пожалуй даст мало впечетления. Поэтому я решил просто скопировать этот черновик из рабочего проекта, чтобы просто оценить примерно синтаксис.

namespace DniproClient
{
        public class User
        {
            public string FirstName { get; set; }
            public string LastName { get; set; }

            public string Status { get; set; }
        }

        public static void Test14(DniproDB db)
        {
            User u1 = new User()
            {
                FirstName = "Заяц",
                LastName = "Зайцев",
                Status = "Offline"
            };

            //save doc
            uint docId = db.AddDoc(u1);

            //load doc
            User u2 = db.GetDoc<user>(docId);

            //sometime later ....
            //status was changed in the db
            db.UpdPartDoc("{'Status':'Online'}", docId);

            //sometime later ....
            //update only status in the document
            //do not recreate object, do not reload FirstName and LastName !
            db.LoadPartDoc<user>(u2, "{'Status':$}", docId);

        }
    }
}

Иподром

Да инмемори. Да отложеная запись на диск (500мс).
Но сеть в замерах участвовала и ОРМ присудствует.
Короче как Вы поняли речь пойдет дальше о штангельциркуле :) Куда уж без него. Набросал четыре бенча

forum.pikosec.com/viewforum.php?f=7

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

Что в планах

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

👍ПодобаєтьсяСподобалось0
До обраногоВ обраному0
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Как успехи?

C сентября думаю движняк начнется.
Это лето все отпуска да отпуска.

Уххх ... наконец собрал высокоэффективное транзакционное ядро для Днипро.
Сейчас поддерживается три наиболее ходовых типов транзакций.
Read Commited, Repeatable Read и Snapshot. В целом реализация получилась очень сбалансированной, присест по производительности в районе 15-30% может и меньше.
Спасибо No Lock примитивам с С++ 11 =)

Из интересного. Блокировочник с элементами версионности. Каждая транзакция формирует свой скоп изменяемых данных и с ней работает.При коммите пишущая транзакция сливает данные в основное хранилище. Соответственно база может работать с «длинными» транзакциями повисшими в интерактиве. Блокировки дискретны и на уровне одного атрибута документа (!). (насколько помню в томже MS SQL блокировки на уровне строки, что хуже).

ACID — да да и еще раз да =) Он уже есть, даже в самой своей тяжелой вариации Isolation и уровня транзакции Snapshot.

По скорости, наиболее удачные запросы — все читатели, вплоть до 6 млн запросов в секунду в многопоточном режиме. Если есть писатели — до 2 млн запросов в секунду. Но какбы еще ничего не мерял особо, тут нужны особые и сложные тесты писать, где будут участвовать сразу несколько параллельных транзакций.

Сможете на нее Swingbench натянуть?

Он же вроде как под Оракл ?
Думаю АПИ может не совпасть...

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

Join, как много в этом слове !
В реляционных базах на нем построено практически всё, что доставляет определенные неудобства, если писать квери код каждый день. В Монго джоинов нет совсем, мол братушки, лепите всё в один документ, вы же в документоорированой базе.
И только в рiдной СУБД джоин принимает идеальный форм-фактор.
Пример — у вас есть документ описываюищий сотрудника. И есть документ описывающий модель автомобиля. Делаем джоин и десериализируем в едином обьекте как параметры сотрудника так и его автомобиля.

         class Employee
        {
            public string name;   //имя сотрудника
            public string engine; //обьем мотора его автомобиля
        };

        private void button2_Click(object sender, EventArgs e)
        {
            //документ описывающий параметры сотрудника
            db.AddDoc("{'type':'employee', 'name':'Mykola', 'carModel':'zaz'}"); 

            //документ описывающий параметры автомобиля
            db.AddDoc("{'type':'car', 'model':'zaz', 'country':'ua', 'engine':'1.2'}");

            //1. получаем документ где описаны параметры сотрудника
            //2. джоиним к сотруднику параметры его автомобиля
            //3. десериализируем в обьект Имя сотрудника + Обьем двигателя его автомобиля
            Employee[] ems = db.GetWhere("{'type':'employee', 'name':'Mykola'}"). 
                                Join("{'carModel':$}", "{'type':'car', 'model':$}"). 
                                Select<Employee>("{'name':$}{'engine':$}"); 

В Монго джоинов нет совсем, мол братушки, лепите всё в один документ, вы же в документоорированой базе.
Давайте я за вас погуглю

хм... треба перечитати, що вони додали в останніх версіях)))

Хм, действительно пропустил в новой версии. Спасибо. Синтаксис конечно доставляет. Как full right inner джоин написать (в примере похоже только left), как заджоинить три таблицы.

Как будет работать Join если я захочу посмотреть всех сотрудников в автомобилях которых двигатель объемом 1.6 ?
Я имею ввиду описание на низком уровне а не запрос.

Если на низком.
Первый запрос ключа получить список айдишников доков 1.6 объем. Дальше зависит от того сколько таких авто найдено. Допустим 10 моделей. Значит еще 10 запросов ключей уже сотрудников при джоине. Дальше зависит сколько в полей в селекте на вывод и сколько найдено сотрудников. Допустим выводим имя фамилия и тысяча сотрудников. Значит еще 2 тыс запросов. Условно один запрос кей велью 100 наносекунд. Есть еще другие расходы, но это дольше писать

Первый запрос ключа получить список айдишников доков 1.6 объем.
ок. как физически получаются ключи всех документов у которых атрибут engine:1.6?

На входе ключ
{Engine:1.6}
На выходе коллекция айдишников доков где такой ключ. Все просто

Магия?
меня интересует физически что будет делать программа когда ей на вход дадут это условие

{Engine:1.6}
заодно любопытно было бы узнать физическую организацию хранения документов, в каком виде информация храниться на диске.
Магия?
меня интересует физически что будет делать программа когда ей на вход дадут это условие
{Engine:1.6}

Так я же написал, эта строка уйдет сначала на парсер джисона. Если приглядется, то в строке 9 байт символов + парсер выровняет по границе 32 бита, получится 12 байт. Вот эти 12 байт и есть наш ключ. А велью это просто массив 4х байтных чисел — айдишников документов. Всё в полных деталях я не могу рассказать, поскольку вопрос очень обширный. Он также звучит как «Расскажите как на низком уровне работает движок Оракла» =)

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

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

В патрiотичних базах вроде Днiпро, весь документ сам по себе хранится в индексе.
Ну собственно хранить данные в индексе не ново,
docs.oracle.com/...v.920/a96590/adg07iot.htm
хотя я себе слабо представляю как это можно сделать для документа (последовательности байт) учитывая, то, что поиск нужно делать только по части этой последовательности.
А потом меньшее джоинить к большему.
Правильно, HASH JOIN
В твоем озвученом примере тру стори, начать джоин с таблицы автомобили, ибо она по замыслу самая меньшая.
Это мы знаем что она по замыслу самая меньшая, а оптимизатор должен это как-то определить
А джоин да, он работает примерно как в реляционных, единственое пока мои шаловливые ручки не добрались до оптимизатора запросов, потому как напишешь так и будет выполнятся

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

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

Ну собственно хранить данные в индексе не ново,
docs.oracle.com/...v.920/a96590/adg07iot.htm
хотя я себе слабо представляю как это можно сделать для документа (последовательности байт) учитывая, то, что поиск нужно делать только по части этой последовательности.

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

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

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

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

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

Как будет работать Join если я захочу посмотреть всех сотрудников в автомобилях которых двигатель объемом 1.6

Ну и сам запрос, посчитать всех сотрудников кто ездит на машине с двигателем обьема 1.6

uint count = db.GetWhere("{'type':'car', 'engine':'1.6'}").  
                         Join("{'type':'car', 'model':$}", "{'type':'employee', 'carModel':$}").Count();

В смысле операции update и delete данная СУБД не поддерживает?
Ибо аналог update table car set model ’chevy’ where model like ’zaz’ развалит вам все как карточный домик. Не говоря уже о delete.
Ну ок.

Поддерживает конечно, причем в такомже интуитивно понятном формфакторе синтаксиса.

db.GetWhere("{'type':'car', 'model':'zaz'}").Update("{'model':'chevy'}");

Такой запрос, обновит все документы с моделью zaz на chevy.

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

db.GetWhere("{'type':'car', 'model':'zaz'}").Drop("{'type':$, 'model':$, 'engine':$}");

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

Ну и чтобы два раза не бегать, как заинсертить новые атрибуты в документ.
Был у нас док

{'type':'car', 'model':'zaz', 'engine':'1.2'}

Нужно добавить джва атрибута

{'type':'car', 'model':'zaz', 'engine':'1.2', 'bodyType':'hatchback', 'price':'7000'}

И запрос на это дело

db.GetWhere("{'type':'car', 'model':'zaz'}").Insert("{'bodyType':'hatchback', 'price':'7000'}");

Сразу оговорюсь, что не смотря на то что в запросе может быть два и более подзапроса (GetWhere, Update, Insert, Select и тд), применяется подобие ленивых вычислений. Реквест на сервер и респонс от сервера будет один, а не несколько. Что экономит трафик и улучшает быстродействие.

а если еще написать украинский СМЗ (структурована мова запитів), чтобы она выглядела как-то
ВИБРАТИ * З %таблиця_назва% ДЕ %поле_1 = значення_1

Чтож, продолжим мастер класс, по поводу синтаксиса.

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

db.AddDoc(new {name = "dictionary",
                           colors = new object[] { new {eng = "red", ua="червоний"},
                                                   new {eng = "blue", ua="синiй"},
                                                   new {eng = "green", ua="зелений"}}});

db.GetWhereElems("{'colors':[{'eng':'green'}]}").Print("{'colors':[{'ua':$}]}");

Выведет на консоль строчку

{'colors':[{'ua':'зелений'}]}

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

Ну а смысл этого атракциона без сервера? Как раз мясо и интересно а не C# мыло

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

А я не хотел бы чтобы код попадался на глаза конкурентам

вот сейчас стало смешно по-настоящему

Что, планы поломались ? Ну бывает ...
Держи кубышек на ночь
booben.com/...b+1&s=online&a=search&p=1

Ну тогда все, расходимся
зачем ты тогду тут сопли разводил?

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

читал эту тему.
потому что злободневна. вообще. и в частности в моих текущих проектах.
и. учитывая что Вы один из топ 10 на доу с к которым я облажался. ну, с своими маркерами.

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

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

Интересно девки пляшут

пока результат его работы нельзя пощупать руками — это все бессмясленное балабольство в духе городских сумашедших

Я же выложил исходники клиента на гитхаб и открыл облачный сервер, хост booben.com, порт 4477. Там уже даже всё настроено, качаешь и запускаешь. Примеров использования тоже вдоволь набросал.

без малейшего понятия какая офигенная пропасть отделаяет его наколенный прототип от решения которое можно использовать....

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

ну еще вариант в докер имидж бинарник завернуть к стати
если прям на столько сыро пока
просто база это очень очень много работы
самому малореально потянуть до мало мальски пригодного уровня :-|
так что варианта у тебя 2
1- искать денги и делать это фул тайм
2 — опенсорсить все с самого начала

1- искать денги и делать это фул тайм

Ну если кто готов поддержать, то dnipro[сбк]pikosec.com =)

2 — опенсорсить все с самого начала

Тут нужно еще подумать. Впринципе если не считать key\value движков (в которые вложено море труда),
остальная часть сервера не содержит какой либо особой Rocket Science. Если будут желающие поконтрибутить, то конечно выложу.

Но если ты уверен что НЕ особенный — то точно прав

Это неправильно. Правильно немного другое: ты, конечно, особенный. Но:

demotivation.me/...20090722/gha04trzqdo9.jpg

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

Мне на самом деле нравится позиция топикстартера — он старается, и при этом он не сильно надоедает :)
А дальше — жизнь покажет. Главное — чтобы не использовались методы типа навязать всем законодательно.

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

MVC + Dnipro = цена вопроса 40-50 строк кода (не считая дизайна html) и час работы
booben.com/DniproForum

Раджу подивитись на datomic www.datomic.com/videos.html. Open source імплементація їхньої архітектури мала б великий успіх

Open source імплементація їхньої архітектури мала б великий успіх

Так пускай имплементируют и выкладывают в опенсорц.

Вони вже :) І просять за це гроші (мають право).
Я просто бачу, що ви вирішуєте проблему «як запхнути JSON та потім щось у ньому знайти», а там цієї проблеми немає, бо усі дані зберігаються у датомах (EAVT), з якими можна працювати хоч у relational style, хоч document like style

бо усі дані зберігаються у датомах (EAVT)

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

У меня же решение в стиле “выжать все соки из древнего камня” и “заменить 10 серверов 1м”. И при этом еще умудрится напедалить в разы меньше кода, по крайней мере для классических задач в веб и вин разработке :)

У меня же решение ... «заменить 10 серверов 1м».

Наблюдая круги на воде, «от широко известной личности в узких кругах»
maxim.livejournal.com/468313.html
и
maxim.livejournal.com/468658.html

и памятуя что доучанин «кулхацер» сразился как-то год-два тому с Максимом по поводу оракл двухфазной транзакции в кластере, и Максим привел свой код...

я — на твоей стороне :) «Покажи свой код!» катит в обычных, примитивных случаях. Или — в каноническом повторении. да, «главное» — на собеседовании!

Хотя ох, претензий у меня и к емсишной документум, и к монге есть.

Крепись, Booben Com
«Кто лезет на рожон — должен терпеть боль» © из романа «Фабрика офицеров»

Побудоражу еще чуток воображение.
У вас есть классическая задача. Написать, для упрощения двухзвенное, приложение. Приложение предельно простое. Вин форма, на ней десять разнообразных контролов. Контролы сохраняются в базу, но есть типичный для десктопа джентельменский набор функциональности.

1. Все контролы должни сохранятся в базу и читаться из базы.
2. Все лейбы к контролам локализируются на 5 языков.
3. На форме есть кнопка, сбросить все контролы в значения по умолчанию.
4. На форме есть пермишены, разные пользователи имеют право видеть\редактировать разные контролы.
5. Все пункты выше настраиваются через базу данных (приложение перекомпилировать не нужно).

Вопрос — сколько на ваших средствах разработки займет времени и какой будет обьем кода для такой задачи ?
Ну и сразу ответ — на документалке, чтобы обеспечить надизайненой форме всю функциональность из 5 пунктов понадобится .... 10-15 строк кода.

Лень дизайнить форму на 10 контролов, но пару набросков чтобы проникнутся, так сказать идеей

Первая строчка накатывает на форму локализацию из базы.

db.GetWhere("{'formName':'Form1', 'docType':'localization', 'lang':'ua'}").Select<Form1>(this, "{'lbFirstName':{'Text':$}, 'lbLastName':{'Text':$}}");

Вторая строчка накатывает на форму валидацию контролов из базы.

     db.GetWhere("{'formName':'Form1', 'docType':'validation'}").Select<Form1>(this, "{'tbFirstName':{'MaxLength':$}, {'tbLastName':{'MaxLength':$}}");

Третья строчка собственно читает сами данные из базы.

     db.GetWhere("{'formName':'Form1', 'userName':'Заец Зайцев'}").Select<Form1>(this, "{'tbFirstName':{'Text':$}, {'tbLastName':{'Text':$}}");

Накатываем джисон с пермишенами на форму.

db.GetWhere("{'formName':'Form1', 'docType':'Permissions','userName':'Заец Зайцев'}").Select<Form1>(this, "{'tbFirstName':{'Enabled':$,'Visible':$}, {'tbLastName':{'Enabled':$,'Visible':$}}");

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

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

Ок, код метода db.GetWhere() в студию.

Так там же в опенсорц клиент опубликован.
Можно и продебажить ...

github.com/.../tree/master/DniproClient

Если код ничего не подсказал, могу так, на пальцах рассказать. Центральная идея ОРМ заключается в том, что благодаря Json сериализатору можно сохранять любой обьект из .NET в базу и также его от туда читать. Благодаря тому что Json сериализатор самописный, там встроена особая фича. Он умеет не весь обьект сериализировать\десериализировать, а только его часть по заданому Джисон шаблону. Причем за основу может взять уже готовый созданный обьект. Вот тут есть фокус — в качестве обьекта можно подсунуть сам обьет Form. Таким образом форма напрямую сериализируется в базу и десериализируется из базы в пару строчек кода, а в самом документе мы просто указываем какие проперти и контролы будут сохраняться и читаться из базы.

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

ага
ок

то есть вот вы читаете выражение «object-RELATIONAL mapping» — и вас ничего вообще не смущает?

Object-relational mapping (ORM, O/RM, and O/R mapping) in computer science is a programming technique for converting data between incompatible type systems in object-oriented programming languages.

А что должно тут смущать ?

все, все — уже ничего

ЗЫ а вы знаете, что сверхценные идеи считаются в психиатрии болезненным состоянием, расстройством психики?

Это не сверхценная, а просто ценная и не идея, а уже готовая реализация.

Для документоорієнтованих СКБД є ODM (Object Document Mapper).
Це так, щоб нікого ніщо не бентежило ;-)

кэп!

но речь ведь вообще не об этом

Коментар порушує правила спільноти і видалений модераторами.

Коментар порушує правила спільноти і видалений модераторами.

Коментар порушує правила спільноти і видалений модераторами.

Так Господа, там ниже просили меня про фидбек и поюзать.
Решил часть проекта выложить в опенсорц.
github.com/.../tree/master/DniproClient

Это по сути ОРМ клиент под .NET который конектится и коммуницирует с базой данных.
Всё в достаточно сыром виде, всё дорабатывается и разрабатывалось на скорую руку (может кто захочет чего законтребутить, то пишите). Из интересных вещей, содержит в себе самописный прокси сериализатор\десериализатор в Json. (раньше использовал стандартный, потом по разным причинам пришлось отказаться ). Его фишка — он умеет частями сериализировать\десириализировать бизнесс обьекты в базу\с базы ну и поддерживает специфику синтаксиса.

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

DniproDB db = new DniproDB("booben.com", 4477);

db.AddDoc("{'site':'dou', 'message':'Hello World !'}");

db.GetWhere("{'site':'dou'}").Print("{'message':$}");

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

ORM там будет если дальше развивать этот же пример

Вместо джисона можно подставить обьект анонимного класса.

db.AddDoc(new {site = "dou", message = "Hellow World !"});

Или обьект обычного класса

MySite obj = new MySite();
obj.site = "dou";
obj.message = "Hello World !";
db.AddDoc<MySite>(obj);

И потом также легко и просто вытянуть готовые обьекты из базы.

MySite[] objs = db.GetAll().Select<MySite>();

Общий стект абстракций такой. Бизнесс обьект => Джисон => Key\Value
С чем удобно, с тем и работаем.

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

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

Например, такой код

MySite obj;
...
db.AddDoc(obj, "{'message':$}"));

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

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

github.com/...er/DniproClient/Change.cs

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

Коментар порушує правила спільноти і видалений модераторами.

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

Типа такого?
habrahabr.ru/post/231213

сейчас я так понимаю мэйнстрим натягивание совы на глобус.

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

Немного странные рассуждения. Поисковый индекс гугла пожалуй крупнейшая система хранения и обработки данных :) Используется ли для этого реляционное хранилище?

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

Какие индексы и какую статистику по-вашему гугл хранит в реляционной БД?
Что вы подразумеваете под поисковым контентом?

нет

бд гибридная, фактически, колонкоориентированая, но с переподвывертом, см. BigTable

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

Dremel is a scalable, interactive ad-hoc query system for analysis of read-only nested data.
На описание реляционной СУБД не очень похоже ИМХО. Она по функционалу ближе к Pig и Hive.

послушайте, товарищ

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

заранее спасибо

Почитайте мою статью и не холиварте
blog.pikosec.com/?p=95

Основное хранилище это NoSQL, это критично.
В переферии может быть все что угодно другое, это не критично.

вы безапелляционно и безостановочно несете чушь — вот что критично

именно поэтому у вас нет шансов, несмотря на изначально неплохую идею

вы же тупо упоротый, вы никого не слышите и все время общаетесь сами с собой

Ой-ой, сколько пафоса и ртфм’а :)))) Уважаемый, я вам не грубил и не понимаю откуда взялось столько высокомерия в мой адрес :))))

Объясните, пожалуйста, без «переподвыподвертов», вы о какой такой реляционной базе толкуете? BigTable? Dremel? Их сочетании?

BigTable — по-сути распределенный многомерный мэп.
Dremel — да, он имеет свое распределенное хранилище, в отличие от Pig и Hive. Но в чем его реляционность? Вы увидели словосочетание nested relations и тут же причислили его к лику реляционных СУБД?

С реляционной СУБД промахнулся. Извиняюсь.

Коментар порушує правила спільноти і видалений модераторами.

в своем роде — да

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

Не морочьте людям голову. Что там от реляционных баз осталось интересно ?
Обычные реляции чтоли ? Так они и в обычных noSql базах есть. В их хранилище нет нормальных форм, нет констреинтов в привычном понимании, ddl комманд и тп, что есть в привычных реляционных базах. Глупо предполагать, что вам там дадут на многопетабайтной базе засандалить какой нибудь ALTER TABLE ... ADD COLUMN ... или с бухты барахты добавить индекс на колонку (внезапно забыли, ага), на которой сотни миллиардов записей. Хранилище заточено под предметную область и каждый байт просчитан и упакован как надо. Забудьте про РДБМС.

Коментар порушує правила спільноти і видалений модераторами.

Хранилище заточено под предметную область и каждый байт просчитан и упакован как надо. Забудьте про РДБМС.
Поэтому я вас и склонял к идее поиска нишевой задачи, на которой можно будет порвать классические Р -СУБД. Никто не будет озадачиваться использованием нестандартной СУБД для допустим условно классической задачи складского учета, или ведения какого то реестра однотипных операций например покупка/продажа валюты в обменном пункте. Зачем?!? — нет большого объема, нет требований к скорости вставки/чтения, нет апдейтов данных внутри еирархии с подсчетом итогов. Для таких задач пойдет проверенное решение, тем более данные сами выгладят как таблицы.
Другое дело задачи с уникальными требованиями — где много данных, где много апдейтов, где много проверок, где нужны быстрые произвольные выборки/запросы (без заранее спланированных индексов), где нужна быстрая агрегация по иерархии и т.д...Какая это может быть предметная область? Незнаю...интуитивно — что из области науки — математики, физики, графики/визуализации...К сожалению я занимаюсь только бизнес задачами и спектр мыслей ограничен...
Вы слышали о QlikView ? qleversolutions.ru/qlikview/tecnology
Там много тумана напущено, и колончастая БД, и ин-мэмори, и сжатие, и даже байки про супероптимизацию на ассемблере для конкретных моделей процов Интела :) ...
Но в сухом остатке — эта штука работает, и вынудила майкрософт и оракл поднажаться и уделить время BI-решениям, подтянуть хвосты так сказать.
Т.е. как она работает для обывателя — каждую ночь в хранилище заливается с нуля допусти продажи товаров (приличные объемы) — там это быстро загружается реально, затем в процессе пользовательских запросов (либо произвольных от балды, либо преднастроенных в их приложениях/документах) данные очень быстро выгребаются. Запросы действительно делай хоть идиотские — работает примерно одинаково по времени выполнения (почти влет), в то время как РСУБД со спроектированными заранее индексами или ОЛАП-куб — от неправильного запроса — сильно задумается.
Т.е. такая вот задача — бизнес-анализ — произвольный, быстрый, простой.
Поэтому я вас и склонял к идее поиска нишевой задачи, на которой можно будет порвать классические Р -СУБД.

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

Ключевые слова: «рассматривать» и «угол зрения».
Какие механизмы Dremel предоставляет для обеспечения консистентности связей?

NoSQL нишевая штука. Горизонтальное масштабирование во все стороны там как правило «ис каропки». Равно каки возможность хранить-выбирать данные в разных форматах без особого гемора. Если их правильно готовить и применять по делу — вполне себе приличный инструмент.

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

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

Вполне себе может заменить. Хотябы потому, что там нужно в раз 10 меньше педалить кода и работает на порядок быстрее. Реляционки могут остаться там где нужна серьезная аналитика. Ито, там где бигдата, с реляционной аналитикой может и не сложиться ...

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

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

Хотелось бы пример. За одно и замеряем количество кода и скорость работы.
С меня решение на Dnipro c вас на реляционке.
Подойдет ? Задачу из предметной области я даю вам возможность предложить любую.

Крім назви СКБД треба ще міняти підхід до проектування архітектури самої БД.
Теж брав участь у проекті, де хотіли реляційні дані запихнути у нереляційну MongoDB. Звісно все працювало, але треба було довго возитись з JOIN-ами, аби це все використовувати в представленні.

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

Більшість даних якщо «правильно» змінити структуру, можна «поскладати» у нереляційному форматі.
Просто це ще треба вміти зробити :)

вопрос не как это сделать, а зачем это делать

це дає приріст в продуктивності,
можливість «легше» адаптовувати продукт відповідно до нових вимог,
легший старт для нових розроблюваних рішень,
можливість зберігати дані, не так як зручно для читання, а як зручно програмі (json)

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

це дає приріст в продуктивності,
тут нужно добавить для некоторого круга задач
можливість “легше” адаптовувати продукт відповідно до нових вимог,
ребята также думали
habrahabr.ru/post/231213
можливість зберігати дані, не так як зручно для читання, а як зручно програмі (json)
В мире очень много задач, очень много программ и очень много форматов.
В том числе есть такие задачи, где с данными с одной БД работают несколько программ и клиентов, одни по json, вторые xml, третьи нативно... я уже не говорю что у каждого фреймвокра свои форматы внутри json, так, что опять таки не все однозначно...

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

ребята также думали
habrahabr.ru/post/231213

Может написать в строк 50-100 кода каркас для социальной сети на документалке и опровергнуть наконец эту желтую статейку...

Давно пора, лучше сразу Facebook на строк 200 кода написать и утереть нос наконец этому Цукербергу

Жаль, Цукерберг не читает поджелтевший хабр и натыкал в свой Фейсбук NoSql выше крыши.

Можно первоисточник почитать?

Да с кем Вы спорите — поберегите нервы :)
gigaom.com/...ts-on-making-mysql-scale
www.facebook.com/MySQLatFacebook

Там фронтом стоят NoSql решения. Они же на 90% и справляются с нагрузкой. Остальное беком лежит на MySql.

ребята также думали
habrahabr.ru/post/231213
Тому, що
це ще треба вміти зробити

Есть как минимум следующие причины:

1. Предварительная фиксация модели данных, которая требуется при строгом соответствии RDBMS со всеми её нормальными формами, может быть чрезмерной, незрелой и дорогой. Менять устройство отдельных параметров в документе типа 7-уровневый JSON, переносить их, перегруппировывать — резко проще, чем создавать новые таблицы, проходиться перестройщиком данных, менять параметры отношений между ключами...

Более того, в системах «continuous delivery» типа наших любимых социалок — то время, когда остановится на конкретной структуре, может вообще не наступить.

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

2. Хранение в реляционном виде означает разброс группы данных, которые часто используются вместе, по разным местам. В тяжёлых случаях — по разным дискам, массивам или даже NAS’ам. Сколь бы ни были эффективны кэши, всё равно с какого-то уровня они не помогают. Как в процессорах сейчас пришли к оптимуму в виде весьма длинной порции данных для обмена с RAM (32 байта — ARM, 64 — x86, 128 — PPC), так и для обмена с диском есть свои оптимальные размеры (колеблятся от 50-100KB для SSD и быстрых HDD, и до единиц мегабайт для медленных HDD и/или дальней связи, типа iSCSI). Поэтому, сокращение количества отдельных чтений и записей за счёт увеличения единицы хранения до такого порога оправдывает себя сокращением затрат на отдельную операцию.

Эти тенденции, например, ещё в районе 2000г. привели к появлению log-structured merge (LSM) взамен традиционных B-tree-based подходов — которое радикально искореняет случайно разбросанные записи (ценой увеличения объёма хранения в тяжёлом случае на порядок).

Более того, в системах «continuous delivery» типа наших любимых социалок — то время, когда остановится на конкретной структуре, может вообще не наступить.
+1
Проблемы же от более вероятных недоработок типа где-то забыли чего-то достроить, чи делают это на ходу — минимальны (я тут рядом писал — если вдруг FB в конкретный момент сформирует ленту без трети постингов, большинство и не заметит). Если где-то нужна “абсолютная” надёжность, то её строят отдельно.
для цього в MongoDB є таке поняття як Write Concern, що дозволяє аплікації впевнитись, що дані були записані на диск.

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

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

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

Сначала мы все храним в одном документе
так більша швидкодія зчитування, за рахунок того, що з диску ми зчитуємо один суцільний блок, а не шукаємо де знаходиться інша «порція»
Сначала нам не важна запись на диск, теперь оказывается важна
багато людей взагалі підтримує підхід «InMemory only», тут же ж можна працювати з різними варіаціями одразу «з коробки»
хоронить РСУБД рановато будет
ніхто його не хоронить, просто треба розуміти, що це не єдиноможливі рішення, як думає більшість. Бо у більшості ВУЗів про не реляційні вчать мало (якщо взагалі вчать) і народ вірить у «єдиноможливі» реляційні бази даних.
Бо у більшості ВУЗів про не реляційні вчать мало (якщо взагалі вчать) і народ вірить у “єдиноможливі” реляційні бази даних.

Ничего в этом мире не меняется... если бы я ходил в институте на информатику я бы верил в “единовозможности” калькулятора Б3-34 :)

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

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

А типо РСУБД не ушла от изначальной идеи. Допилили и xml колонки и иерархические типы и использование менеджед сборки и ОРМ сверху и главное всё в рамках реляционной модели...

Бесспорно ушла, но и я не утверждаю что работать например с Json в РСУБД также легко как NoSQL. В Оracle например более менее полноценный json появился только в 12-й версии.
Тенденции таковы, что стирается грань между документной моделью и реляционной, базы обрастают не свойственными изначально им фичами и пока перспективным выглядит гибридное направление.

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

2. Не факт. В настоящее время в РСУБД есть инструменты которые позволяют управлять хранением данных. В зависимости от данных, запросов и окружения можно указать как и где хранить данные, хоть вместе хоть отдельно.

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

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

Я же выше писал

для одних задач лучше РСУБД, для других NoSQL, для третьих гибрид.... выбирать БД строит от задачи, данных и окружения...

на том-же и сошлись... ну и ладненько

пример с юзерами, когда вся информация о юзере хранится в каждом документе, но если юзер сменил адрес например, в РСУБД нам нужно сделать update одного поля, в NoSQL выбрать все документы где этот юзер встречается и изменить атрибут в каждом документе.
це неправильно спроектована БД
могла бути окрема колекція, яка повністю описує користувача, а всі решта колекцій мали б звичайний ключ (індекс чи посилання).
Просто питання тільки в тому, як ці дані будуть використовуватись, що часто записується, що тільки читається, як часто будуть змінюватись ті чи інші дані, що саме може змінюватись. І в залежності вже від цієї інформації можна проектувати структуру.

А в реляційному світі є нормальні форми, які кажуть, що кожна таблиця повинна мати ключ, уникати повторень, дані які мають повторення, виносяться у окрему таблицю і т.д. В результаті на великих проектах отримуємо «павутину» схем, в яких голову можна зламати.
Це можна спростити, тримаючи ці дані разом, але це вже NoSQL )

могла бути окрема колекція, яка повністю описує користувача, а всі решта колекцій мали б звичайний ключ (індекс чи посилання)

Это не что иное как реляционная модель

А в реляційному світі є нормальні форми, які кажуть, що кожна таблиця повинна мати ключ, уникати повторень, дані які мають повторення, виносяться у окрему таблицю і т.д.

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

могла бути окрема колекція, яка повністю описує користувача, а всі решта колекцій мали б звичайний ключ (індекс чи посилання)
Это не что иное как реляционная модель
І так, і ні. В реляційній моделі — це «зв’язок», в нереляційній — це однакові значення, за якими можна знайти деякі об’єкти.
Але це зазвичай не штучний ключ, а «природній», тобто який може відображатись без значень на які посилається (без операції JOIN).
Таким чином об’єкт який містить значення і той який на нього посилається — це 2 незалежні об’єкти, а ключ використовується тільки на рівні аплікації.
це 2 незалежні об’єкти
Если это 2 независимых объекта, в таком случае изменение атрибута нужно отразить в этих 2-х объектах.
И опять сначала.

тому треба обирати атрибут, який буде рідко або взагалі не мінятись)

В реляційній моделі — це «зв’язок», в нереляційній — це однакові значення, за якими можна знайти деякі об’єкти.

технічно тут немає різниці
жодної

наведіть будь ласка ще аргументів

Плац. Куда катиться Гугль *facepalm*
Набираю в гугле, «site:sql.ru dniprodb» — по вашему запросу ничего не найдено
Набираю в бубне, «ssql dniprodb» — всё есть booben.com/...b+1&s=online&a=search&p=1

А хотел отискать вотету картинку.
www.sql.ru/...tualfile.aspx?id=18581006

Теперь по существу.
db.AddDoc("{'Company':'AnySoft', 'Country':'USA', 'Employees':[{'FirstName':'Ivan','LastName':'Ivanov','Age':20, 'Childs':[{'FirstName':'Ivanko','LastName':'Ivankov','Age':2},{'FirstName':'Ivanka','LastName':'Ivankova','Age':3}]}," + "{'FirstName':'Petr','LastName':'Petrov','Age':21, 'Childs':[{'FirstName':'Petrako','LastName':'Petravkov','Age':1},{'FirstName':'Petravka','LastName':'Petravkova','Age':5}]}]}"); db.AddDoc("{'Company':'MySoft', 'Country':'Ukraine', 'Employees':[{'FirstName':'Иван','LastName':'Иванов','Age':20, 'Childs':[{'FirstName':'Иванко','LastName':'Иванков','Age':2},{'FirstName':'Иванка','LastName':'Иванкова','Age':3}]}," + "{'FirstName':'Петр','LastName':'Петров','Age':21, 'Childs':[{'FirstName':'Петрако','LastName':'Петраков','Age':1},{'FirstName':'Петравка','LastName':'Петравкова','Age':5}]}]}");

Здесь у нас описана некоторая предметная область. Каждый документ содержит описание компании. У компании есть набор сотрудников. У каждого сотрудника есть набор детей. Теперь как это выглядит с точки зрения интерфейса. Мы видим центральный грид с списком компаний и на даблклике открываются четыре дочерних (вложеных) формы, каждая из которых редактриует свою часть документа.

Кажется, если бы подобную предметную область у нас потребовали бы описать на MS SQL или Oracle, то это не было бы простой задачей. Но на на этой базе такую задачу можно описать всего в несколько десятков строк кода и 15 минут времени

Теперь совсем уж по существу :) Тут много было разных мелких холиворов, вообщем предлагаю от этого всего абстрагироваться и перевести какойто более-менее реальный проект на эту субд.
От себя предлагаю безвозмедный саппорт и реализацию всей бизнесс логики связаной с базой данных. Это отличный шанс получить бесплатно высокопроизводительную базу, профессиональную помощь от меня и с минимумом кода для ее поддержки. Идеально подойдет молодой стартап, которому нужны ресурсы и который еще не имеет много много гигабайт данных (на них сложнее отлаживать логику базы).
В случае неудачи, обещаю «все вернуть как было» перевести на MS SQL обратно :)

PS: Да, предложение актуально для .NET проектов.

Чем это отличается от firebase.com ?

Ваше решение не подходит для банковских операций, требующих максимальный уровень изоляции — serializable. Вот с вашего счета списалось 100500 грн и сервер упал раньше чем через 500 мс (отложенная запись не произошла) и шо дальше? Ждать 45 дней и писать заявление в банк?. Почитайте про уровни изоляции на википедии. Очень важная тема.

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

Учитывая претензии — незачет!

Из ответов ниже:

И наконец третий режим подразумевает честный комит и флаш на диск после каждой транзакции. В таком режиме мерялись с MS SQL в частности подобие бухгалтерского теста вроде TPС-H который моделирует движения на складе.
serializable

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

А на банковское ПО я пока не расчитываю. Слишком консервативная область :)

«Что будет если сервер упадет? А у нас не падал!» ©
youtu.be/RVwXdCfzJZA?t=1142
тема немного не ваша, но optimistic style development раскрыт.

«Что будет если сервер упадет? А у нас не падал!» ©

Открою вам маленькую тайну, если винчестеры выйдут из строя у сервера, то будет уже всем наплевать что там стояло. Oracle Enterprise Edition или Dnipro :)
Зачастую, свежий бекап и зеркалирующий сервер важнее чем тысячу маркетинговых лозунгов с ACID. Но это я в общем, без холивара. Конечно как минимум Durability должно быть.

Обычно там стоят raid какова веротяность что raid выйдет из строя.

Не поверите — крайне высокая. Аппаратные RAID контроллеры сейчас делают настолько топорно, что даже тысячебаксовые глючат и горят пачками. Мы вот совершенно на днях с такими наигрались, не рады.
Из разработки аппаратных RAID вся грамотная мысль ушла году этак в 2005, остались только индусы-двоечники. Честно говоря, это сейчас выглядит той областью, где хорошо бы помогло opensource, но последнее скорее будет реализовано в стиле «Linux на мелкой платке с десятком подключенных дисков и доступом по iSCSI».
Почему оттуда ушёл разум — вопрос интересный — но мне кажется, что виной этому конкуренты в виде всех программных решений типа линуксового md*, которое есть давно, но тогда активно пошло в использование, и материнки с набортным зеркалом через BIOS; а поменять бизнес-модель не смогли (до того момента большинство этих реализаций сидело на проприетарных RTOS на странном железе).
В результате — остаётся из более-менее внятных решений или совсем уж монстры специализированных NAS за цену ещё вдесятеро дороже, или всё чисто программно на уровне OS с соответствующими проблемами производительности (XOR’ить потоки блоков через AVX, конечно, дешевле, чем пословно, но всё равно медленнее, чем на специальном ASIC). А ещё в OS-based не будет батарейки на контроллере.

Из разработки аппаратных RAID вся грамотная мысль ушла году этак в 2005
Постепенно все переползают на полупрограммные решения. Типа кеш и батарейка — с нас, а логика из дров уже. Для набортников уже практически стандарт, как винмодем (не к ночи будет помянут) в свое время. Причем с теми же проблемами крайней зависимости от ОС.
.
Однако антиофтопик — со стораджем вообще вопрос не стоит «если», стоит только «когда».
Ибо помимо веников (которые кстати тоже горазды пачками выпадать по разным причинам) и контроллеров, есть еще питание, шина данных со шнурками-разъемами, разновеселые глюки памяти, ошибки администрирования, логики приложений и т.д.

Зачем блокировать таблицу, если есть MVCC?

TC с этим не знаком, он свято верит, что в реляционных базах

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

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

TC с этим не знаком, он свято верит, что в реляционных базах

Определитесь. Мы про блокировочник или версионник говорим. На разных реляционках есть разные реализации.

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

Ну таки все мешают всем. И

MVCC
это уже как говорится — средство на пожаре.
Зачем блокировать таблицу, если есть MVCC?

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

не... что-то тут не так
выше уже было что в одном документе не получается.

История адрессов хранится в другом месте, в другом документе, который уже описывает саму компанию. Я это так вижу
И делать дополнительных проверок на версии — не нужно.
Прежде чем это утверждать, думаю нужно изучить глубже принципы работы реляционных баз, что такое многоверсионность, транзакции и уровни изоляции и для чего это нужно. Очевидно, что материала из википедии недостаточно.
Это конечно если важна целостность данных, консистентность... если эти принципы не важны,
то тогда да.. цацки и оверхед по производительности, ну пропадет клиент со всей его историей ну и фиг с ним.

Чем то вы мне напоминаете жигулистов. Так исторически сложилось, что индустрия взяла в оборот бензиновый двигатель. Нельзя сказать, что это было неудачное решение. Но со временем бензиновый двигатель оброс множеством переферийных устройств. Разные карбюраторы, сцепления, бензонасосы, катализаторы, выхлопная труба, радиатор, турбина, компрессор, стартер, масляный фильтр, коробка передач и тд тд тд ... продолжать можно очень долго. Прошло сто лет и на арене появились электромобили. Это такая архитектура, где сам двигатель можно встроить в колесо, а все то барахло что я перечислил выше — просто выбросить. И разгонятся будет до 100 не за 10 секунд, а за секунды 3-4.

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

Понимаете как смешно выглядите ? Вы разберитесь сначала в вопросе. Даже не так. Я предлагаю просто взять проект и сделать его на новой базе, или хотябы пример. А потом уже вернуться к вашим «карбюраторам-бензонасосам».

Я предлагаю просто взять проект и сделать его на новой базе, или хотябы пример

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

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

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

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

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

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

Это как, с радиатором и охладительным бачком ? Ясно понятно.

PS: Кстате как реляционного жигулиста, у меня активный опыт уже скоро будет 15 лет, такшта если троллинг, то пожалуйста потоньше, потоньше господа =).

Чтото я не понял. Это вы не можете обьяснить где действительно нужны транзакции а где нет. Кинулись в финансовую систему, а там оказывается почти все построено на двухфазных комитах. Кинулись в вебмагазины бронирования, а там блокировки реализованы в бизнесс логике, если по уму.
вы меня с кем-то спутали, внимательно перечитайте мои посты и ваши ответы.
Я никуда не кидался, а смоделировал 2 простейшие ситуации которые сломали вашу же логику.
у меня активный опыт уже скоро будет 15 лет
меня ваш активный опыт как-то не очень интересует.
вы меня с кем-то спутали, внимательно перечитайте мои посты и ваши ответы.
Я никуда не кидался, а смоделировал 2 простейшие ситуации которые сломали вашу же логику.

Какие именно ситуации. Ситуации начинаются с предметной области. Озвучиваем, разбираемся.

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

тсс... дайте ТС насладиться сферическим конем в вакууме.
он же сказал, что ему транзакции не нужны т.к. не будет блокировок... потом правда сам же сделал для себя открытие, что в многопользовательской не read only системе блокировки таки будут... о сколько там открытий чудных у ТС еще впереди.

Чего только стоит
«Не секрет, что до 50% современной базы RDBMS занимает хранение ID строк, которые можно не хранить в обьектной модели NoSQL.»

видимо 15 лет активного опыта было несколько не в этой предметной области

Чего только стоит
«Не секрет, что до 50% современной базы RDBMS занимает хранение ID строк, которые можно не хранить в обьектной модели NoSQL.»

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

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

Допустим у вас есть документ, на 1000 аттрибутов в документалке. И есть тотже документ на 1000 аттрибутов размазаный по 100 таблицам в реляционке. Когда клиент запрашивает этот документ, документалка блокирует этот документ единожды. Тоесть физически делает всеголишь одну проверку на заблокированность документа. Когда мы собираем документ из 100 таблиц, сколько нам нужно сделать проверок блокировок по MVCC ? Наверное в каждой таблице нужно зайти и проверить блокировки. Одна проверка блокировки, и сто проверок блокировок. Есть разница.

Простите, это юмор такой?

MVCC потому и MVCC, что блокировок описанного вида там _нет_. Там другие механизмы. Если «клиент запрашивает этот документ» — то есть речь идёт о чтении — то всего лишь читаются актуальные версии строк.

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

Я бы понял (и это в качестве подсказки на будущее), если бы Вы говорили о другом. В первую очередь о локальности группы чтений и записей; о том, что если это действительно «документ», то прочитать его целиком с одного-двух блоков диска лучше, чем шариться по сотне таблиц (кстати, почему именно 100 таблиц? 100 разных концепций? если это иерархия атрибутов, то скорее всего будет не более 4 таблиц, но, возможно, со строками в сильно разных местах). Писать точно так же лучше целиком, если нет пересечений с другими. И да, это действует до определённого объёма (зависит от оперативности диска, скорости связи с ним, тно сейчас можно условной границей брать 100KB). Но и это лечится в реляционках, если построить встроенный индекс по id документа (в MS SQL и Postgres это называется идиотским, но уже устоявшимся термином clustered index), он резко локализует поиск, приводя к эффективности, вполне близкой к той, что если писать объект BLOBом. Наконец, те же структурированные документы (например, в JSON) есть во многих RDBMS, начиная с PQ (Postgres). И да, там есть работа с подключами в содержимом, сохраняя связность хранения.

А если у вас логика хранения не укладывается нормально на варианты толстых непересекающихся документов, индексируемых идентификатором или другим простым индексом, а вместо этого есть хитрые кросс-связи или заметные пересечения содержания — вся эта оптимизация на толстые атомарно писомые BLOB’ы начинает выглядеть подозрительно или вообще работать хуже «разбросанной» реляционки. Всё зависит от задачи.

MVCC потому и MVCC, что блокировок описанного вида там _нет_. Там другие механизмы. Если «клиент запрашивает этот документ» — то есть речь идёт о чтении — то всего лишь читаются актуальные версии строк.

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

Послушайте. Вы не поняли суть, то о чем я вам говорил.

Вполне возможно. Вы-то её даже не попытались высказать.

Все есть в бенчмарках.

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

Я не говорил, что «раскидывать по 100 таблицам» лучше, я говорил, какая настоящая причина лучшей производительности (в среднем) в подходе «один объект» vs. «100 таблиц». И если Вы выжимаете всё возможное, вам нужно знать настоящую причину.

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

Смешно.

какая настоящая причина лучшей производительности

Ваша настоящая причина описана в стиле бабушкиных секретов для механических винчестеров без кеширования. Не учитываете десятки, если не сотни разных факторов.

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

То-то на SSD размер блока страниц для стирания колеблется от 128KB до 1MB. Это делает из них настоящие механические винчестеры без кэширования, да.</sarcasm>

Не учитываете десятки, если не сотни разных факторов.

Это вы свели всё к одному фактору «количество блокировок», даже не разобравшись, что такое эта блокировка. Я хотя бы ещё один добавил на рассмотрение.

Это вы свели всё к одному фактору «количество блокировок», даже не разобравшись, что такое эта блокировка. Я хотя бы ещё один добавил на рассмотрение.

Если я вам повторю то, что говорил еще в самом начале темы — что документ на самом деле это не документ, а набор ключей в хранилище. Что модель данных инвертирована и развернута на 180 градусов, что само по себе Trie намного лучше работает чем BinaryTree и вы врядле сможете предложить правильный контрпример то окончательно сломаю вам мозг. Книжные штампы не действуют =)

а набор ключей в хранилище.

А мы в данной подветке обсуждали именно документ. Давайте не прыгать между темами.

что само по себе Trie намного лучше работает чем BinaryTree

В определённых условиях, далеко не всегда.

вы врядле сможете предложить правильный контрпример

Этих контрпримеров полон интернет. Зачем мне что-то дополнительно стараться? Я верю, что для ваших структур это оптимум, но так не везде.

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

Книжные штампы не действуют =)

Это не штампы, и они действуют.


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

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

Это вы свели всё к одному фактору «количество блокировок», даже не разобравшись, что такое эта блокировка. Я хотя бы ещё один добавил на рассмотрение.

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

Я помню эту аналогию, но если у вас задача иметь 4 колеса, то от этого не уйти.

А вот в пределах 4-колёсной зоны, да, есть много вариантов.

о-о-о, да вы плаваете в азах... :-(

как же все плохо

можно достичь блокировкой таблицы
дальше нет смысла что-либо обсуждать

Serializable это и есть максимальный уровень излояции. Вы имели ввидк минимальный?
Вы понимаете как работают транзакции? Вы ознакомились с принципами ACID? Результат не будет зафиксирован в базе еслсервер упадет м операция не выполнится
По поводу уровня изоляции seriliazble. Он используется для предотвращения фантомных апдейтов в строке, которых не лишена repeatable read.

Пожалуй проведу еще небольшой ликбез на тему мифы документоориентированых систем:

Миф 1: Чтобы прочитать часть документа мне нужно вытянуть из базы весь текстовый документ.
Нет, весь джисон документ только за фасадом выглядит как джисон. На самом деле это набор ключей в хранилище. Следовательно чтобы получить 10 аттрибутов из 1000 одного документа нужно запросить всего 10 ключей. Минимальный трафик. Один и тотже документ может редактировать несколько пользователей. Если они запросили части документа которые не пересекаются, то они друг другу не мешают. При сохранении документа прийдется перезаписать только ключи связанные с измененными атрибутами документа, а не весь документ.

Миф 2: При добавлении или удалении атрибута в середине документа нужно перезаписать весь документ. Неверно. Добавление нового аттрибута документа, или нового значения в массив документа, эквивалентно добавлению одного нового ключа в сторедж, что является также низкозатратной операцией (на уровне ядра в районе 80-100 нс).

Миф 3: Документоориентированая база данных имеет оверхед при хранении данных.
На самом деле при инвертировании индекса удается добится существенного сжатия (по крайней мере теоретически). Если джисон документы представить как однотипные текстовые документы, то в инвертированом виде они хранятся с существенным сжатиям, поскольку пути к аттрибутам прописаны в Trie структуре единожды в независимости от количества документов. Также стоит учесть что 30% современных реляционных баз данных, это айдишники для связи таблиц. Что в документоориентированых базах также отсудствует.

Миф 4: Прогресс остановился, MS SQL\Oracle\Mongo нужное подчеркнуть верх инженерной мысли. На самом деле это обычные древние проекты, с кодом не первой свежести. (Кто заглядывал в проекты 10ти-15ти летней давности, тот меня поймет :) ). Больше играет роль правильная мат модель данных. В некоторых классических случаях, реляционные базы данных могут по скорости отставать в сотни и даже тысячи раз. Типичный пример, джоин чтобы получить адресс компании пользователя, где произведен его автомобиль.

Например для документоориентированой базы, такой запрос будет равен одному взятию ключа. (Около 100 нс)
{User:{Car:{Company:{Address:’Street 1′}}}}

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

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

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

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

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

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

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

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

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

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

Если ты думаешь что в банке есть только 2 типа счетов(депозитный и карточный) — ты глубоко ошибаешься.
Для начала подумай над кейсами
— «Вася принес в кассу банка пачку нала чтобы погасить свой кредит»
— «ЧП Петя оплатил товар ООО „Рога и копыта“ и при у них счета в одном банке»
Можно выйти за рамки банковской тематики. Например интернет магазин
— «Таня заказала 3 упаковки шампуня. Это надо отразить одновременно в кол-ве доступных упаковок и в танином заказе»
Я думаю идея ясна.

— «Вася принес в кассу банка пачку нала чтобы погасить свой кредит»

И где тут транзакция, где атомарная проводка между двумя счетами ?

И где тут транзакция, где атомарная проводка между двумя счетами ?
ты думаешь что кассир трекает кол-во принесенной налички в специальной тетрадке? Или вообще не трекает?

Еще раз, где там транзакция ?
Ты пришел, внес наличку 10 грн. Кассирша положила червонец в кешдровер. Прошел один атомарный апдейт где твой баланс увеличили на 10 грн в базе данных. Где транзакция то ?

Ты хоть раз в отделении банка был или без паспорта банковские операции не дают проводить? :)

Переход на личности на техническом вопросе.
Ок, слив засчитан.

Как раз к моменту написани джоинов года яерез 3 у него паспорт появмися

Усложним пример про Таню
Всего в наличии имеется 4 пачки шампуня. Одновременно с Таней, заказывающей 3 пачки шампуня, Лена заказывает 2.

Банки уже начали торговать шампунем. Забавно.

Чукча не читатель? Ну я повторю:

Можно выйти за рамки банковской тематики. Например интернет магазин

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

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

Тоесть вы предлаете продавать товар которого уже нет на складе, принять оплату и потом начать процесс роллбека в процессинговых системах ? Гениально !

Я просто привел кейс параллельного апдейта одного документа(который элементарно решается в РСУБД), и который ломает озвученную тобой концепцию «один человек берет один документ, редактирует и никому не мешает».

Тоесть ты с банков перепрыгнул на бронирование шампуня, а с шампуня опять в банки (с их досье) и это норм ? Ок.

Я привел примеры из разных предметных областей, показывающие что концепция «один пользователь-один документ» работает только в мире эльфов и единорогов. У нас же в полный рост проблемы «один пользователь транзакционно меняет несколько документов», «несколько пользователей транзакционно меняют один/несколько документов».
В некоторых случаях можно выкрутиться двухфазным коммитом, который с ростом кол-ва участников бизнес транзакции становится все менее надежен и все более сложен в интеграции. Но зачем городить этот огород, если есть средства, которые «ис каропки» гарантируют конфигурабельный ACID.
И кстате, как такие ситуации можно обрабатывать в некоторых из нереляционных субд, я писал ниже по треду. :)

Я привел примеры из разных предметных областей

И оба неудачные.
Банки и финансовые системы во всю юзают двухфазный комит. А системы бронирования товара, обходятся блокировками в БЛ, а не транзакциями.

Я попытаюсь еще раз. Наверное зря кормлю тролля.

Банки и финансовые системы во всю юзают двухфазный комит.
... и всячески страюатся сократить участников бизнес транзакции при реализации двухфазного коммита — причины я писла выше. Ты же рекомендуешь их увеличивать — ну в добрый путь, чо уж там.
А системы бронирования товара, обходятся блокировками в БЛ, а не транзакциями.
Это твои бурные подростковые фантазии :)

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

Кстате в некоторых банках можно даже такси заказать :)
privatbank.ua/...-vikliku-ta-oplati-taks

Да что вы человека мучаете — пусть пилит :) Не забросит — через какоето время доберется до Red Book: Readings In Database.
P.S. И узрит бездну :)

Для внутрибанковских переводов — это транзакционный апдейт двух полей.

Больше. Должны ещё как минимум обновляться поля счётчиков количества операций и общей суммы (для статистики, мониторинга отклонений от плановой обстановки, etc.)
(Хотя с этими полями сложнее то, что они высококонкурентны — часто выгоднее вести короткий журнал таких операций, который интегрировать отдельной задачей. Так что всё ещё веселее.)

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

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

Ты пришел в отделение, одним махом вытянули на тебя досье и редактируют.
Это работает ровно до тех пор пока не требуется изменить 2 досье одновремено. Примеры смотри выше.

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

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

Теперь вот появляется и конкуренция а следовательно нужно думать о уровне изоляции и типе применяемой блокировки.

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

С чего это вдруг клиентам нужно бороться за таблицу?... блокировка на уровне строк, если уж так нужно пессимистическое блокирование.

ИМХО банк не самый подходящий пример для документоориентированной БД

ИМХО банк не самый подходящий пример для документоориентированной БД
Ну в теории можно похоливарить на тему event sourcing-а, но я сомневаюсь что ТС слышал что ето такое :)

Event sourcing — всего лишь паттерн, который не решает проблему совместного доступа на 100%, так как естественно могут быть такие конфликтующие изменения от разных источников, что их невозможно разрешить мерджем евентов.

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

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

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

Абстрактно — да, это решает проблему. Но я имею в виду более конкретные случаи совместного доступа, когда приходят одинаковые евенты от разных пользователей относящиеся к одному стриму определенной версии. Вопрос какому евенту отдать предпочтение? Можно конечно автоматически разрешить конфликт отдав предпочтение более позднему или более раннему евенту. Но тогда все равно евент, сгенерированный одним из пользователей будет отменен.
Попробую объяснить по-другому.
В качестве аналогии можно взять любую систему контроля версий, которая по-сути реализует event sourcing паттерн, например, Git. Здесь комиты (которые по-сути евенты) меняют состояние файлов (которые по-сути объекты). Но даже тут возникают конфликты, которые можно разрешить только вручную.
Если перенести эту аналогию обратно в event sourcing. Когда два юзера загружают одновременно обеъект определенной версии из евент стора для редактирования и что-то меняют в нем, генерируя евенты. То это напоминает две разные ветки ивентов исходящие из одной точки, которые нужно потом смерджить.

я сомневаюсь что ТС слышал что ето такое

Уровень твоей квалификации продолжает огорчать меня.
Каждый зрелый движок базы данных (включая мой) содержит модификацию CQRS + Event Sourcing. Он запрятан в логе транзакций, где база пишет write эвенты, а только потом переносит изменения в основное хранилище. Также это используется для репликации изменений между базами данных.

О, я смотрю ты 2 новых крутых аббревиатуры нагуглил — не останавливайся, продолжай в том же духе! :)

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

За этим, разговор для меня перестал быть интересным. Откланиваюс.

Спасибо за топик вообще и за этот комментарий в частности — от души посмеялся :)

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

Если кто-то со стороны меняет телефон клиента, когда этот клиент находится ногами в банке, то тут повод для работы внутренней СБ :)

А если серьёзно — да, проблема безусловно есть.

Если говорить о списании средств со счета еще более печальней получиться.

Я тут неподалёку проезжался с ворчанием по этим решениям -
"«"
Если что-то внутрях у такого монстра, как FB, не работает — ну там нейтрино лишнее пролетело, провода в православизаторе перепутались, хакеры DDDoS устроили или мекс на свиче заветную кнопку «Reset to factory settings» придавил — это вообще должно юзеру показываться, пусть даже в виде вопросительного знака гифом 1×1 пиксель, или это лишнее знание?

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

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

Из всего этого получаются интересные выводы.

1. Одна из целей первичного Big Data (уже уходящего мема) — работа систем даже при отказе их частей — достигнута. Но не за счёт всех этих страшных мер типа «распределённых хранилищ», корректности разложения данных, кворума при записи и т.п. — а просто за счёт того, что данных так много, что отсутствие их части просто не замечается. Выпал десяток постов? Фиг с ним. Из-за кривизны фильтров месяцами не видишь чьих-то постингов? И так полна лента котегов. Если ты явно про кого-то не вспомнил — он только элемент статистики. Важно только свежее и актуальное. Не оглядывайтесь в прошлое, двигайтесь вперёд. Котеги в помощь.

2. Как следствие предыдущего — корректность работы информационной системы типа Facebook вообще никого (опять же статистически) не интересует. Интересуются этим только отдельные отклонения (типа меня), которые ещё помнят, что бывает и надёжный софт. «90% качество — не брак». И впрямь, это же не 10%, как «пятый сорт».
"""

Если кто-то со стороны меняет телефон клиента, когда этот клиент находится ногами в банке, то тут повод для работы внутренней СБ :)

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

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

На самом деле это так пример в лоб.

Я утрировал, да. Хотя такие задержки в обработке и участие клерков в простейших движениях это как-то не в пользу такого банка.

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

Угу.

Например для документоориентированой базы, такой запрос будет равен одному взятию ключа. (Около 100 нс)
{User:{Car:{Company:{Address:’Street 1′}}}}

А что будет если компания вдруг поменяла адрес на ’Street 2′?

А этот вопрос не так прост как кажется.
Клиент купил машину у компании, которая находилась по адрессу Street 1.
Если изменить адресс для компании на Street 2, то мы внесем в базу логическое противоречие,
ведь клиент не покупал машину по адрессу Street 2. Но вот если нужно будет проводить возврат товара или ремонт, то логичней обратиться по адрессу Street 2. Вообщем все зависит от предметной области. В идеале нужно хранить историю перемещения компании, и в документоориентированой базе это будет выглядеть тоже более природно.

Т.е. что-то типа {User:{Car:{Company:{Address:’Street 2′,PreviousAddress:’Street 1′.....}}}}
и так для каждого атрибута и каждого User?

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

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

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

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

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

Это всеравно не даст той производительности что дает инвертированый индекс на Trie. К томуже денормализованые данные, он будет хранить более компактно, за счет инвертации данных. В бенчмарках все есть.

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

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

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

За счет чего уделывать то ?
Как приспособить, например, в бенчмарке MS SQL чтобы на тесте того же дерева комментариев (аля Доу) не сливался в 40+ раз.
forum.pikosec.com/viewtopic.php?f=12&t=16

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

Как приспособить, например, в бенчмарке MS SQL чтобы на тесте того же дерева комментариев (аля Доу) не сливался в 40+ раз.
Синтетические тесты канечна забавны, но по сути никому кроме красноглазиков не нужны :)

Много способов. Например не использовать рекусивный запрос для выборки по иерархии Parent-Child, а сразу хранить иерархию в виде HierarchyID (SQL Server 2008 и выше) или Materialized Path (все версии SQL Server).

Да я бы с удовольтвием, но сильно разбираться в вашем коде неохота. Во-первых его с ходу не запустить, упадёт ошибка, ну то ладно, сделал поле NOT NULL и пошёл дальше. потом мне надо ещё консольку запустить (только код посмотрел), и сиди гадай что у вас там в ресурсах за текст запроса прописан :) Было бы хорошо видеть тест такого вида:

1) Создание структуры данных в базе
2) Выполнение запроса (его скорость меряем и сравниваем, а не 100500 заполнений таблиц и непонятно чего). И из его текста сразу понятно что он делает и какую ценность несёт.
3) Лучше без консолек, чтобы сразу было в студии видно время, как в другом вашем примере.

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

Посмотрел Ваш TSQL код.
Не все в нем хорошо, да и написан «курица лапой», местами крешает (Дима указал на nullable column for PK creation), много лишнего (зачем вначале создавать Test.Numbers а затем дропать ?),
но то что в нем есть явные промахи — очевидно.

Очень забавно смотрится конструкция типа INSERT FROM SELECT ORDER BY, а также ORDER BY в анкеркном мембере рекурсивного CTE, что автор пытается таким образом сотворить ?
.
Вторая проблема, Вы явно не понимаете стратегию индексирования.
Много DDL с созданием constraints & indexes, и все мимо. Посмотрите план выполнение финального стейтмента. Key LookUp/Bookmark явно просит покрывающего индекса. Банальная ошибка в создании составного индекса и понимания порядка столбцов в нем дает представление о техническом уровне.
Раз выставили код — получите рeцензию.
Я бы сказал что лелел джун или писал индус ;) Шучу. Насчет индуса.
В целом код на явную троечку, без стиля.

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

А по существу самого тест сценария то он таки натянут за уши.
Производим выборку чилдов первых 1000 парентов,
SQL крайне эффективен в выборке чилдов одного, конкретного перента ( на вашем примере это < 1ms with serial plan ), но с ростом перентов время увеличивается линейно ( LOOP JOIN with SEEK per parent ).

После оптимизации (как я вижу ее ) Cost плана падает втрое.
Если реализовать через HierarchyID Cost такой же как и через CTE + Optimization, однако реальное время еще втрое меньше. Дальше не стал тратить время.

Еще один важный момент во всем это. Стоимость плана во всех случая меньше cost threshold for parallelism, а значит тяжелая артиллерия еще не запущена.

В любой случае респект.

MS SQL не мой код. Это писали для меня, чтобы очередной раз показать «как надо» :). Вот я и пердлагаю, может еще кто хочет его переписать.

Как предлагаете так Вам и пишут ;)

Я только, что попробовал переписать логику на NativeCompiled objects. (SP + TVP).
Тестировал на CTP 3.2. Ряд ограничений еще мешает развернуться на нормальном TSQL, однако если на кону стоит производительность, то пришлось развернуть рекурсию.

Предварительно выглядит что можно ускорить процесс как минимум еще в 2-4 раза.

Есть много подходов, и техник. Если делать в лоб то любая СУБД не спасет. СУБД это не только свалка данных + SQL поверху, это прежде всего инструмент. B грамотных руках он сияет, в неумелых .....

Вот потому мне и лениво писать сразу на две базы данных один и тотже код. Когда какойто Джигит залетает, он истинно истинно уверен, что MS SQL будет работать быстрее в его умелых руках. А я както уже хорошо понимаю какие будут результаты, потому мне лениво писать код и за меня пишут код :)

Предварительно выглядит что можно ускорить процесс как минимум еще в 2-4 раза.

Это какбе хорошо, но нужно ускорить используя всевозможные костыли и оптимизации хотябы в 10 раз.

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

Это какбе хорошо, но нужно ускорить используя всевозможные костыли и оптимизации хотябы в 10 раз.

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

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

Вы хотите, чтобы я процитировал пол ветки, чтобы наконец дошло, что наряду с парой достоинств есть очевидные недостатки ?. Ликвидация которых приведет к тому что данная СУБД будет отличатся от MS SQL в только худшую сторону !

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

Я бы тут ответил старой пословицей из рекламы.
«Навiщо платити бiльше» ©
Зачем сидеть и оптимизировать часами MS SQL код неочевидными и извращенными способами, если простой Днипро код «из каробки» даст производительность ну пускай не в 40 раз после всех ваших оптимизаций, но в 10 так точно. Это не мало. Там где раньше пользователь в UI ждал 10 секунд чего-то там, будет ждать меньше секунды.

Короче. Використовуй Украiнське, хе хе :)

Логика имеет место быть. Но давайте посмотрим на это так.

Нужна определенная фича — купи новую СУБД. Так ? А потом построй их них зоопарк и утони в саппорте.

Корпоративный клиент он консервативен был есть и дай ему здравия таким и остатся.

Если ваша СУБД так хороша — продайте ее ! Напишите бизнес предложение и разошлите. Серия технических ассecтментов (а не диванного трепа) укажет так ли все хорошо под капотом.

Удачи.

Нужна определенная фича — купи новую СУБД. Так ? А потом построй их них зоопарк и утони в саппорте.

Зачем покупать. Нужно для начало попробовать. Убедиться что это эффективно работает. Поставить себе галочку и при возможности — использовать.

Если ваша СУБД так хороша — продайте ее ! Напишите бизнес предложение и разошлите.

Так мне в ответ напишут, цитирую:

Корпоративный клиент он консервативен был есть и дай ему здравия таким и остатся.

Твоя правда. «Здесь» нет логики.

а карманы для растущих в объеме ключей?

Мне понравилась дерзость ТС :)
В 90-х работал прикладным программистом c иерархической СУБД STAY 1.3. Она имела кучу проблем, но в конкретных задачах — показывала чудеса в сравнении с тогдашними конкурентами clipper/foxpro. Но эта СУБД не перенесла новых задач и требований времени...увы.
ИМХО:
Сила традиционных реляц. СУБД в их универсальности, и в наличии инфраструктуры вокруг них (старые проекты, разработчики, книги, имя, тонны исправленных багов, перспективность их существования в будущем).
Если рассматривать узкие задачи (супер быстрая вставка/супер быстрый поиск/ супер быстрая агрегация) — то наверняка можно создать специализированную СУБД которая будет лучше/быстрее традиционной.

Если рассматривать узкие задачи

Это какие задачи ? Те которые можно выразить через Json документы ?
А есть задачи где выразить предметную область через Json ’ы нельзя чтоли ?

Узкие задачи — это те для которых критична 1-2 характеристики, а остальными можно пренебречь.
Предметную область можно выразить как

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

Это есть приимущество, если у вас веб и джаваскрипт.
Джаваскрипт может нативно обрабатывать документы с базы данных.

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

это только если база по вебу будет отдавать публичные данные :)
а если возможность менять / не показывать данные — то из консольки хрома/фф можно будет это сделать :) или городить в самой базе какое-то серверное секьюрити.

Джоин в сотни микросекунд?????
Почитай про batched key access например
Что это за мифы? Для кого они? Для бабки с рынка?

Сравнение с MS SQL грубоватое :) Не совсем корректно делать такое сравнение. Цитирую ваш тест для MS SQL:


—OUR TEST ============================================================================

declare @sum int
set @sum = 0

declare @i int
set @i = 0

while(@i < 10000)
begin
SELECT @sum = @sum + count(*)
FROM Company c
INNER JOIN Employee e ON c.ID = e.CompanyID
INNER JOIN Child h ON e.ID = h.EmployeeID
WHERE c.Country = ’UK’
AND e.Age = 25
AND h.Age = 5

set @i = @i + 1
end

select @sum

Сам запрос — бесполезен, но это ладно, рассмотрим технические детали. Штука в том, что MS SQL для итеративного выполнения не предназначен :) Если кому и придётся что-то такое написать, то напишется что-то типа такого:


declare @initial_sum int

declare @sum int
set @sum = 0

declare @i int
set @i = 0

SELECT @initial_sum = count(*)
FROM Company c
INNER JOIN Employee e ON c.ID = e.CompanyID
INNER JOIN Child h ON e.ID = h.EmployeeID
WHERE c.Country = ’UK’
AND e.Age = 25
AND h.Age = 5

while(@i < 10000)
begin
SELECT @sum += @initial_sum

set @i = @i + 1
end

select @sum

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

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

ну оборачивать SQL в что-то менее совершенное...
завернуть язык четвертого поколения в язык третьего поколения и сравнивать в цикле....
а давайте наоборот?
что-то типа рекурсивного обращения SQL к себе и к в вашей базе?
.
Хотя — снимаю шляпу перед идеей. Я ведь только идеи и кушаю ))

Идея использовать Tries для индексации JSON — неплохая.
Однако приведенные тесты, как минимум, некорректны. Ваша база, пока что, полностью in memory.
Т.е. в тесте со вставкой, вы, грубо говоря, сравниваете запись в память с записью на диск (впрочем я не знаю какие настройки монги при этом использовались).
Тест с чтением иерархической структуры также некорректен: хранение и чтение иерархических данных из плоских таблиц с кросс джоинами и переливаниями во временные таблицы — далеко не самая эффективная вещь. В случае с MSSQL данные также читаются с диска, а в вашей базе она хранится и читается из памяти и уже в развернутом виде, насколько я понял.
Также, MongoDB и SQLServer имеют какой-то оверхед связанный с транзакциями и прочими дополнительными штуками, которые у вас просто еще не реализованы.

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

Там есть три режима работы. Первый это чистый инмемори. Прочитали с диска всю базу, поработали, сохранили. Второй режим подразумевает что данные попадают на диск с задержкой примерно в 500 мс. В таком режиме тестировались с Монго. У Монго был выставлен аналогичный режим. И наконец третий режим подразумевает честный комит и флаш на диск после каждой транзакции. В таком режиме мерялись с MS SQL в частности подобие бухгалтерского теста вроде TPС-H который моделирует движения на складе. Единственое что верно — режим ИнМемори действительно есть в плане что все данные подняты с диска. Почему так сделано — потому что закон Мура не остановился для RAM и думаю скоро мы увидим 0.5-1TB памяти в бюджетных конфигурациях.

Сравните свою базу, например, с Memcached.

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

В SQL запросе я вижу выполнение бОльшего количества операций: поиск по диапазону дат, сортировку по дате, джоин и юнион, которые, как минимум, должны вносить сложность O(n log n) для сортировки, O(n) для джоина и т.п. И я не вижу этих операций в запросе к вашей БД.
Можете пояснить этот момент?

Memcached я предложил как in memory БД, поскольку не уверен, что Mongo и SQL Server работают в ваших тестах исключительно с памятью. На счет runtime complexity различных структур данных и связанных с ними нюансов я в курсе как бы.

Можете пояснить этот момент?
О каком именно коде речь ?

С форума

;with cte as (
select top 1000 id, parent, message
from test.Tree where parent is null and from_date between ’20100101′ and ’20160101′
order by from_date desc
union all
select t.id, t.parent, t.message
from cte e
join test.Tree t on t.parent=e.id
)
select id, parent, message
from cte e

Да, там с этим примером есть ньюансы. Изначально ставилась задача, сделать бенчмарк который похож на сайт Доу. Тоесть есть тема, есть под ней дерево комментариев. Запрос — по айди темы получить саму тему и иерархией под ней комментарии. В MS SQL это сделали через фильтр дат. У мен через фильтр по айди темы. Плюс у MS SQL там есть фора, поскольку весь бенчмарк заканчивается на получении ридера, с которого еще нужно вытянуть данные и промапить на бизнесс обьект, а это тоже затратно. У меня все по чесному, сохранили бизнесс обьект прочитали иерархический бизнесс обьект через ОРМ. Сортировки у меня нет, поскольку комментарии добавляются в порядке даты создания. В MS SQL она есть, поскольку он недетменирует без сортировки порядок вывода комментариев.
Юнион там висит поскольку CTE и с иерархиями MS SQL немного говнкодисто работает.
Позже этот тест доводили до ума, результаты впринципе были теже что там описаны.

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

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

Это хороший вопрос. Одна тема на Доу в документоориентированой базе представлена в виде одного Джисон документа, где комментарии это однотипные обьекты вложенные в документ на произвольную глубину. Есть только один способ, обойти все дерево документа и собрать все комментарии определенного пользователя. Это получить все комментарии уровня 1, потом уровня 2, потом уровня 3 и тд. Допустим макс. вложенность 10. Значит будет десять строк кода, десять запросов.

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

А если тем будет 1000000( ну допустим у нас не доу а реддит) и уровень вложенности комментариев не 10 а 100.... то получим всего лишь 10 лямов запросов — но конечно же очень быстрых :D

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

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

s.pikabu.ru/...1370854627_412776286.jpeg

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

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

Еще раз почитайте мифы документоориентированых систем. Только на фасаде документ выглядит как джисон, так удобстно для работы. На самом деле это набор ключей. Инвертация индексов делает то, что количество ключей в сторедже не зависит от количества документов, а зависит от нормального распределения значений атрибутов. Чем больше уникальных аттрибутов, тем больше ключей. Конкретно для этой задачи Доу комментаторов, это говорит о том, что ключ для одного пользователя будет один. Больше пользователей, больше ключей. От количества документов это не зависит. Дальше взять все документы пользователя с уровня 1, будет одно, подчеркиваю одно, взятие ключа. Это около 100 наносекунд на уровне ядра для длинного ключа. Если уровней 10 то это будет 10 взятий ключей. По 100 нано, это одна микросекунда, на найти все комментарии пользователей за все года во всех темах (!). Причем все эти запросы будут последовательными, и скорей всего отлично ляжут в кеш процессора. Дальше, конечно в этом расчете не учтена сериализация, десериализация с обоих сторон, передача по сети, что составляет уже накладные расходы и в мат модели не участвует. Но для матмодели, это достаточно удачный запрос.

Не понимаю почему загрузка всех комментариев, оставленных пользователем зависит от уровня вложенности комментариев в конкретных темах и почему нужно делать много запросов. А если он оставлял комментарии в тысяче тем с произвольным уровнем вложенности? Сканировать все темы в поисках его комментариев?
О сериализации нет смысла упоминать, так как она зависит только от объема возвращаемых данных и не влияет на алгоритмическую сложность поиска необходимых данных.

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

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

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

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

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

Сканы — это уже нехорошо

Всё, я понял контекст. В моем предложении выше Сканы, это означает что список документов получен и по нему просто нужно пробежаться чтобы сериализовать и передать клиенту :)
Это проход по массиву, по сути дела.

Вот вы и получили объяснение, почему в соцсетях нынешнего формата всё так легко теряется :)

MSSQL данные тоже читает из памяти. С диска данные читаются, как и в любой другой базе, только при первом чтении. Для этого теста (если его запустить впервые) первый цакл поднимет всё в память, 9999 последующих будут работать только с память. Но то я так, придираюсь :)

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

никакой гарантии консистентности данных, контроля транзакций

Это с чего ты взял ? База пишет лог транзакций. Это сделать было не сложно.

>Монго код 49.7 сек.
>Днипро код 0.514 сек
>Mongo код 1.6 сек
>Dnipro DB код 0,161 сек
>MS SQL код, время выполение последнего запроса 8 сек.
>DniproDB, время выполнение последнего запроса 0,281 сек.
......

Сжечь шайтана !!!

Рукописи не горят ! © Мастер и маргарита :)

C 67го года, B*-trees с компрессией ключей, MUMPS. (Из современных — это Intersystems Caché, GT.M, MiniM). Самый быстрый OLTP на котором лежит куча банковского процессинга во всем мире, например. И чего его изобретать еще один лисапет?

Зачем было придумывать Facebook, когда уже был MySpace ?

Там я чуток вверху рассказывал, бинарные деревья не эффективны для хранения Json документов. Всему виной длинные и похожие между собой ключи. Например у Вас есть 1 млн ключей каждый длиной 50 байт. Причем каждый ключ совпадает с другим по первым 46 байт. Итого при поиске бинарное дерево при сравнении всегда будет шерстить эти 46 байт при каждом сравнении, ведь они совпадают. Префиксное дерево работает не так. Оно хранит эти 46 байт единожды, а остальные 4 байта это ветвление дерева. Это значительно эффективней работает.

читаем про компрессию ключей еще раз. и про B*-trees с компрессией ключей в частности

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

B*-trees
эффективней В каких именно параметрах он будет эффективней чем Trie ? Параметров тут тоже может быть около десяти и все может менятся при разной природе ключей и разном количестве ключей.
Третье — уже риторический вопрос. Откуда такая уверенность что с 67го года прогресс остановился ? Теже Джуди массивы придуманы в 2000х, пошерстите хабр, там каждые две недели чтото новенькое по поисковым R&D в этой области живее всех живых.

Ну, если Judy arrays уже эффективно научились персистить на диск, и апдейтить там, то мы, конечно, в шоколаде.
Что же касается компрессии ключей, то этот механизм как раз и позволяет делать Trie-like структуры хранения не отказываясь от «полного» дерева, в промышленных реализациях повторяющаяся голова ключа хранится один раз, ровно как в префиксном дереве. B* всего лишь хранит лексикографически близкие ключи вместе, что значительно ускоряет поиски в условиях наличия блочного ввода-вывода. С 67го года там сделано очень много, поскольку повторюсь — MUMPS базы работают в куче mission-critical приложений, в том числе и весьма требовательных по латентности и durability (как тот же упоминавшийся card processing).

Ну, если Judy arrays уже эффективно научились персистить на диск, и апдейтить там, то мы, конечно, в шоколаде.

Judy я не писал, за эту реализацию не в ответе. У меня есть своя эффективная реализация, которая работает как с диском с копеечными затратами на ОЗУ, так и с в сочетании с LRU. Но конечно лучше всего работает в ИнМемори. Если математически рассматривать, то в сочетании с патрицией Trie алгоритм выгодней чем любые B* деревья. Исключение сканы по диапазонам, но тут нужно тоже смотреть/учитывать разные факторы.
Trie меньше генерирует так называемых seek times, что важно для чтения данных с механических винчестеров. Кроме того, нужно понимать что мы уже вошли в эпоху SSD и больших обьемов ОЗУ, где seek time могут не играть значительной роли. И дизайнившиися под механические винчестеры базы, попросту устаревают. Потому на практике, ИнМемори с подвержденными коммитами на диск думаю будет составлять тенденцию для большинства проектов в будуйщем.

Что же касается компрессии ключей, то этот механизм как раз и позволяет делать Trie-like структуры хранения не отказываясь от «полного» дерева, в промышленных реализациях повторяющаяся голова ключа хранится один раз, ровно как в префиксном дереве. B* всего лишь хранит лексикографически близкие ключи вместе, что значительно ускоряет поиски в условиях наличия блочного ввода-вывода. С 67го года там сделано очень много, поскольку повторюсь — MUMPS базы работают в куче mission-critical приложений, в том числе и весьма требовательных по латентности и durability (как тот же упоминавшийся card processing).

Это все легкий троллинг. Аля, давайте потроллим испытателей вертолетов Апач, рисунками Леонардо-Да-Винчи за 67й год. Нужны эффективные реализации. Но этих самых реализаций я до сих пор не вижу. Не увидел даже названия алгоритмов, из-за которых B Star, обычное попсовое бородатое дерево для блочного чтения, должно работать эффективней/, в том числе в плане комрессии. Перечитывайте вверху мою статью, почему именно Trie и почему именно в инвертированом индексе это то «о чем так долго говорили большевики» :)

Это все легкий троллинг. Аля, давайте потроллим испытателей вертолетов Апач, рисунками Леонардо-Да-Винчи за 67й год. Нужны эффективные реализации. Но этих самых реализаций я до сих пор не вижу.

Это все потому, что вы невнимательно читаете. Полагаю, это касается и чтения кода и статей, описывающих реализованные в том коде алгорится (иначе Judy не всплыл бы даже в кошмарном сне, не то, что в разговоре о дисковых базах. Эфективных реализаций есть море, весьма живых, и они уже упоминались — Intersystems Caché, FIS GT.M, MiniM.

На этом, думаю, с моей стороны комментирование закончено.

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

Причем здесь Кеш ? Что в ней лучше ? Что революционного ?
Обьективно лет 5 назад писали немало к ней бенчмарков, причем даже не я, а по просьбе мне помогали. Уровень MS-SQL, может местами быстрее работает, но как расплата жуткий код на глобалах.

У меня комплексное решение. ОРМ под .NET и другой подход на инвертированых индексах с полностью переработанным Trie — который дает существенный прирост производительности.

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

Не легко принимать что носкл (M) состоявшаяся технология старше си, веселей думать что это стильно модно и молодёжно.

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

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

Intersystems Caché
есть серьёзный минус — это стоимость. И как следствие — закрытый код. Операции записи блоков скрыты от доступа разработчика. Но покопавшись можно найти много интересного, за вас копаться никто не будет.
то должны с благодарностью отзываться на критику, в тоим числе конструктивную,

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

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

Как пользователь — критикуйте на здоровье, только рад.

Вы что-то раздосадовались — не стоит. Моей критики тут не было и советов я вам не даю — вам они не нужны. Если вы чего-то не видите это не значит что этого нет.

вы знаете название Cache.
Ну я хоть название знаю, в отличии от вас, и жуткий код на глобалах ничем не лучше жуткого кода на С — но никто не заставлет никого писать жуткий код, язык не виноват, тем более такой изящный язык как М
Не нужно себя переоценивать.
Золотые слова!)
Не легко принимать что носкл (M) состоявшаяся технология старше си
... в чистую проигрававшая конкуренцию sql в мейнстриме лет эдак 30-40, и только сейчас начали отыгрываться, делая ставки на «скалабилити(шардинг и репликация) ис каропки забесплатно за 5 минут» .

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

А шардинг и репликация там действительно из коробки и действительно за 5 минут — но вот не бесплатно, увы, ни разу.

... в чистую проигрававшая конкуренцию sql в мейнстриме лет эдак 30-40

Только в определённых областях. Файловые системы, например, никогда не были SQL/RDBMS — они типичные иерархические БД. Хотя попытки и их завести под эту схему предпринимались регулярно.

и только сейчас начали отыгрываться, делая ставки на «скалабилити(шардинг и репликация) ис каропки забесплатно за 5 минут»

Потому что улучшилась теория и появились новые требования.

...поисковых алгоритмов, прям как звезд на небе. Но я бы их разделил на три основные категории. Это разные виды бинарных деревьев. Хештаблицы и ... Trie...

Структуры данных и алгоритмы (поисковые алгоритмы) это немного разные вещи, как бы.

Хороший Key\Value Storage или в мирском миру ассоциативный массив, я бы скорей назвал маленькой операционной системой. У него есть свой рукопашный аллокатор памяти, свои (иногда больше десятка) встроеных алгоритмов сжатия, механизмы балансировки, обхода диапазанов, свой механизм работы с диском, иногда с элементами LRU и еще много чего такого, что делает его самодостаточной обособленой низкоуровневой экосистемой. А за фасадом, конечно простой АПИ.

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

На мою вещь доков нет, но могу дать док на один из одноклассников, тоже Trie
judy.sourceforge.net/doc/shop_interm.pdf

круто, ток букв много ) . Потом почитаю как-нить , спс

Підписатись на коментарі