Здравствуйте, alex_public, Вы писали:
_>Порезать БД на части? ) Да, это большая проблема. Собственно она даже не всегда гарантированно решаема. И в nosql базах с автоматическом шардингом этим заниматься не надо. Там настраиваются только связи между серверами.
С помощью простого middleware вообще небольшая проблема. Это маркетинговый буллшит, что нельзя шардинг сделать в РСУБД. Просто в РСУБД это ненужно, гораздо дешевле выходит иметь один толстый сервер по цене двух железок. Но когда scale-up становится невыгоден, то вполне можно делать scale-out. Правда в современных условиях scale-out может понадобиться только для масштабов яндекса, гугла, фб или аналогичных гигантов.
_>Ну так ты сам же подтверждаешь мои слова. Да, соответствующих верхней границе спектра (полный аналоги транзакций из РСУБД) не много (но есть!).
Есть конечно, и они все плтаные, с TCO повыше SQL Server.
_> Но в остальных то тоже обычно что-то есть. Всяческие разновидности "лёгких" транзакций, которые формально не подходят под ACID. Так вот "лёгкие" это не означает, что они работают как-то наполовину или неправильно. Там абсолютно точно такое же поведение как и у РСУБД. Просто применимы они не ко всем операциям/данным, потому и лёгкие. Ну так а если в нашей задаче будут нужны только как раз подходящие запросы (или если говорить более корректно: если мы правильно выбрали СУБД под нашу задачу), то какие проблемы? )
Проблемы обычно такие, что задачи со временем меняются. noSQL по сути не позволяют писать adhoc запросы как SQL (c ACID гарантиями), поэтому ты вынужден изначально готовить схему под все возможные запросы. А если вдруг запросы поменялись, то все, жопа. Или теряешь гарантии, или компенсируешь тоннами медленного кода.
_>>>2. С учётом тенденций развития веб'а (где в очень многих случаях сильные гарантии не нужны) именно nosql решения могут стать лидирующими. G>>Это очень сильное заявление. noSQL в вебе подходит только для readonly сценариев с выборкой по ключу, то есть статических сайтов. Но умные люди уже научились генерировать статические сайты на голом HTML и неважно что работает в бекэнде. Как только появляется динамика и сложные запросы — noSQL сосет.
_>Ты же сам приводил примеры с лайками и т.п.)))
Это совершенно нетипичные сценарии, их нет смысла рассматривать.
_>К примеру если глянуть сюда http://www.slideshare.net/m0nstermind/c-one-joker, то видно что в основу они положили nosql решение. Хотя у них была уже полностью развёрнутая инфраструктура на базе SQL Server (от которой как раз и отказываются в пользу NewSql решения).
Не приводи в пример соцсети. Ты никогда в жизни не сделаешь ни одного решения, которое будет испытывать хотябы 10% проблем массовой соцсети.
Хороший пример — Stackoverflow, инфы полно, нагрузка высокая, данных достаточно много. и там все работает на одном SQL Server.
G>>Ты неправильно понял. Потеря гарантий всегда влечет за собой больше операций для того, чтобы эти гарантии частично восстановить. И очень часто бывает, что дополнительные операции отнимают в итоге больше времени, чем сэкономили. Причем со временем количество дополнительных операций растет и накладные расходы тоже растут. Про труд программистов я даже не говорю.
_>Ну так это означает что подобный переход был глупым и его инициатора надо выгонять. ) Только вот это скорее исключение из правил. Всё же обычно нормальные специалисты в начале всё измерят, а только потом переходят. И в большинстве случаев получают ускорение.
Все так думают, но не все понимают разницу между точечным измерением и общим. У меня есть прекрасная история, как хотели увеличить быстродействие путем перехода на mongodb с sql server. Точечные замеры давали очень хорошие результаты 15-20 раз быстрее делались чтения. Но после перехода оказалось, что просто записать данные нельзя, надо выполнить много телодвижений для записи данных, причем запись лочит коллекцию, так что остальные читать не могут. В итоге написали батч-джоб для обработки изменений. Оказалось что в совокупнсоти весь новый код жрет много ресурсов, замедляя работу приложения. В итоге в паре простых сценариев стало быстрее примерно в 2 раза, а остальных медленнее в два раза. А потом кончилась память на монге, пришлось новый сервер покупать.
В итоге потратили 3 месяца на переход, увеличили потребление ресурсов в два раза, возникла проблема с остановкой при сжатии (слава богу не 24\7 система), быстродействие в совокупности не изменилось.
А могли бы просто redis cache поставить и запросы пооптимизировать, но очень хотели на монгу перейти.
_>>>Это если все гарантии необходимы. А в конкретном частом случае например могут быть нужные только какие-то простейшие гарантии. G>>В OLTP они всегда необходимы. Будь то форум или банковский процессинг. Отсутствие такой необходимости это или мусор (твиты, лайки), или статический сайт (то есть readonly по ключу). _>А где оно на форуме необходимо то? )))
Ты же видишь свое сообщение сразу после опубликования, вот тебе и гарантии. А представь, что это происходило бы не сразу. А админ за это время захотел поделить текущую тему на две. Упс, пост потерялся.
_>>>Ну так зато в таком случае проблема переходит из технической области в административную ( грубо говоря как руководителю разработчиков заставить написать их все нужные оптимальные запросы). G>>В корне каждой административной проблемы лежит техническая. Заставить возможно, но это тупо затраты увеличит настолько, что проект станет нерентабельным.
_>Ну так зависит от ситуации. Я же уже описал варианты. Понятно, что если альтернативой служит покупка одного нового сервера, то лучше его купить. А если альтернативой служит покупка тысяч серверов, или повышение на 10% себестоимости устройства с тиражом в миллионы, то лучше уж напрячь программистов. )))
У тебя никогда не будет задач, где месяц работы программиста эквивалентен покупке хотя бы десятка серверов.
Здравствуйте, alex_public, Вы писали: _>Ну так мой собеседник утверждал, что в реляционных БД и без транзакций не будет никаких проблем. )))
Вы неверно его поняли. _>Очень даже имеет. Это в реляционных БД понятие транзакции является строго определённым. А в мире nosql БД оно своё у каждой СУБД. Более того, у некоторых СУБД оно зависит от используемой модели данных и запросов. Т.е. в конкретной СУБД и для конкретной модели данных определённые запросы легко вкладываются в транзакцию, а другие нет.
Ещё раз: понятие транзакции является строго определённым везде. Оно формулируется не в терминах реляционной модели, а в терминах абстрактных операций. Как правило — записей и чтений.
Просто от RDBMS требуют полную реализацию этого определения, и, с некоторыми огрехами, все топовые СУБД его реализуют без компромиссов. А в мире NoSQL транзакций, как правило, нет, из-за чего начинается юление типа "ну, они как бы есть, но не для всех запросов". То, что большинство NoSQL баз выдают за "поддержку транзакций" — атомарность на уровне одной операции.
Но, простите, отсутствие атомарности на уровне одной операции означает, что СУБД фактически повреждает данные, т.е. это банальный баг.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, gandjustas, Вы писали:
_>>Порезать БД на части? ) Да, это большая проблема. Собственно она даже не всегда гарантированно решаема. И в nosql базах с автоматическом шардингом этим заниматься не надо. Там настраиваются только связи между серверами. G>С помощью простого middleware вообще небольшая проблема. Это маркетинговый буллшит, что нельзя шардинг сделать в РСУБД. Просто в РСУБД это ненужно, гораздо дешевле выходит иметь один толстый сервер по цене двух железок. Но когда scale-up становится невыгоден, то вполне можно делать scale-out. Правда в современных условиях scale-out может понадобиться только для масштабов яндекса, гугла, фб или аналогичных гигантов.
Гораздо дешевле? ))) Это с каких это пор жирные кластеры стали дешёвыми? ) Как раз наоборот, намного дешевле взять несколько простенький серверов (можно вообще на Атоме), объединённых в сеть.
Да, и я уже в который раз тебя поправляю. Речь не о невозможности шардинга на РСУБД, а о невозможности автоматического шардинга.
G>Проблемы обычно такие, что задачи со временем меняются. noSQL по сути не позволяют писать adhoc запросы как SQL (c ACID гарантиями), поэтому ты вынужден изначально готовить схему под все возможные запросы. А если вдруг запросы поменялись, то все, жопа. Или теряешь гарантии, или компенсируешь тоннами медленного кода.
Ну да, согласен, это инструмент требующий умений и продумывания заранее. Но это ещё не повод его не использовать.
_>>Ты же сам приводил примеры с лайками и т.п.))) G>Это совершенно нетипичные сценарии, их нет смысла рассматривать.
В том то и дело, что современный веб движется именно в эту сторону. ))) Т.е. если бы был один фейсбук, то я согласился бы что это исключение. Но кругом плодятся сервисы всё более и более простые по функциональности и сложные по масштабности (Твиттеры, Инстаграмы и прочая нечисть). Причём сервисы уже становится модно писать в стиле прямого обращения из браузера к БД (какой-нибудь nosql, выдающей наружу REST). Я не говорю, что мне это нравится, но такова реальность.
G>Все так думают, но не все понимают разницу между точечным измерением и общим. У меня есть прекрасная история, как хотели увеличить быстродействие путем перехода на mongodb с sql server. Точечные замеры давали очень хорошие результаты 15-20 раз быстрее делались чтения. Но после перехода оказалось, что просто записать данные нельзя, надо выполнить много телодвижений для записи данных, причем запись лочит коллекцию, так что остальные читать не могут. В итоге написали батч-джоб для обработки изменений. Оказалось что в совокупнсоти весь новый код жрет много ресурсов, замедляя работу приложения. В итоге в паре простых сценариев стало быстрее примерно в 2 раза, а остальных медленнее в два раза. А потом кончилась память на монге, пришлось новый сервер покупать. G>В итоге потратили 3 месяца на переход, увеличили потребление ресурсов в два раза, возникла проблема с остановкой при сжатии (слава богу не 24\7 система), быстродействие в совокупности не изменилось.
Значит не верно выбрали СУБД.
G>А могли бы просто redis cache поставить и запросы пооптимизировать, но очень хотели на монгу перейти.
Хыхы, redis — это вообще то тоже игрушка из мира nosql. )))
_>>А где оно на форуме необходимо то? ))) G>Ты же видишь свое сообщение сразу после опубликования, вот тебе и гарантии. А представь, что это происходило бы не сразу. А админ за это время захотел поделить текущую тему на две. Упс, пост потерялся.
Так и не понял причём тут ACID на форуме. И видим мы своё сообщение благодаря просто следующему запросу, а не как следствие кода возврата БД. Кстати, а вот один из самых современных (и при этом крайне быстрый) движков форумов https://nodebb.org работает с тремя (кстати, как раз через обсуждаемый выше слой абстракции БД) nosql СУБД и никаких проблем не испытывает. Причём одна из них как раз совсем не соответствующая ACID Redis.
_>>Ну так зависит от ситуации. Я же уже описал варианты. Понятно, что если альтернативой служит покупка одного нового сервера, то лучше его купить. А если альтернативой служит покупка тысяч серверов, или повышение на 10% себестоимости устройства с тиражом в миллионы, то лучше уж напрячь программистов. ))) G>У тебя никогда не будет задач, где месяц работы программиста эквивалентен покупке хотя бы десятка серверов.
Я что-то не понял, ты считаешь что это не реальные цифры или что? )
Здравствуйте, Sinclair, Вы писали:
S>Ещё раз: понятие транзакции является строго определённым везде. Оно формулируется не в терминах реляционной модели, а в терминах абстрактных операций. Как правило — записей и чтений.
Конечно. И это определение полностью удовлетворяется во многих nosql СУБД на некотором множестве запросов.
S>Просто от RDBMS требуют полную реализацию этого определения, и, с некоторыми огрехами, все топовые СУБД его реализуют без компромиссов. А в мире NoSQL транзакций, как правило, нет, из-за чего начинается юление типа "ну, они как бы есть, но не для всех запросов". То, что большинство NoSQL баз выдают за "поддержку транзакций" — атомарность на уровне одной операции. S>Но, простите, отсутствие атомарности на уровне одной операции означает, что СУБД фактически повреждает данные, т.е. это банальный баг.
Ещё раз повторяюсь. Нам на практике требуется что-то вроде "две записи должны добавляться только парой", а не требование вида "хотим транзакции на любых видах запросов". Так что если для конкретных двух нужных нам запросов тразакции nosql работают, то тот факт, что они не работают на других видах запросов нам абсолютно безразличен.
Здравствуйте, IT, Вы писали:
IT>На самом деле единственной альтернативой linq может стать compile-time кодогенерация. Желательно с возможностью синтаксического расширения языка.
А можно более развернуто?
Просто среди плюсов linq не была упомянута возможность собирать запросы в runtime. Например, когда мы к некому IQuerable<T> докидываем неких Where условий. Как это можно решить в compile-time, учитывая вышеописанную параметрозависимую кодогенерацию (пример со значением переменной null)?
И про синтаксическое расширение тоже не понял: имеется ввиду возможность встроить в язык некий аналог linq, возможность автору аналога к нему докручивать фичи, возможность конечного пользователя что-то там синтаксические расширить?
имеется в виду?
Статические запросы построенные через динамическую/runtime композицию? — это не помеха для compile-time генерации.
STD>Например, когда мы к некому IQuerable<T> докидываем неких Where условий. Как это можно решить в compile-time, учитывая вышеописанную параметрозависимую кодогенерацию (пример со значением переменной null)?
Здравствуйте, alex_public, Вы писали:
_>Здравствуйте, gandjustas, Вы писали:
_>>>Порезать БД на части? ) Да, это большая проблема. Собственно она даже не всегда гарантированно решаема. И в nosql базах с автоматическом шардингом этим заниматься не надо. Там настраиваются только связи между серверами. G>>С помощью простого middleware вообще небольшая проблема. Это маркетинговый буллшит, что нельзя шардинг сделать в РСУБД. Просто в РСУБД это ненужно, гораздо дешевле выходит иметь один толстый сервер по цене двух железок. Но когда scale-up становится невыгоден, то вполне можно делать scale-out. Правда в современных условиях scale-out может понадобиться только для масштабов яндекса, гугла, фб или аналогичных гигантов.
_>Гораздо дешевле? ))) Это с каких это пор жирные кластеры стали дешёвыми? ) Как раз наоборот, намного дешевле взять несколько простенький серверов (можно вообще на Атоме), объединённых в сеть.
Это тоже миф, который поддерживают апологеты nosql и подобной муйни. Я перед новым годом считал hp-шные серверы. Сервер в два раз толще оказался на 30% дешевле, чем два сервера.
Кроме того нужно понимать, что большая часть быстродействия РСУБД упирается в диски, так что поставить еще один SSD может отказаться выгоднее чем еще один процессор или больше памяти.
У scale up конечно есть предел, но гораздо дальше, чем кажется некоторым.
_>Да, и я уже в который раз тебя поправляю. Речь не о невозможности шардинга на РСУБД, а о невозможности автоматического шардинга.
Ок, шардить таки можно, но чуть сложнее, чем в nosql, ок?
При этом помним, что у РСУБД потребность в шардинге на порядок ниже. Грубо говоря noSQL нужно шардить когда объем данных больше объема ОП, а у РСУБД такой необходимости нет.
G>>Проблемы обычно такие, что задачи со временем меняются. noSQL по сути не позволяют писать adhoc запросы как SQL (c ACID гарантиями), поэтому ты вынужден изначально готовить схему под все возможные запросы. А если вдруг запросы поменялись, то все, жопа. Или теряешь гарантии, или компенсируешь тоннами медленного кода. _>Ну да, согласен, это инструмент требующий умений и продумывания заранее. Но это ещё не повод его не использовать.
То есть ты признаешь, что использование noSQL требует больше затрат, чем классические РСУБД, тогда зачем их использовать? Сложнее, ресурсов больше надо, в чем профит?
_>>>Ты же сам приводил примеры с лайками и т.п.))) G>>Это совершенно нетипичные сценарии, их нет смысла рассматривать.
_>В том то и дело, что современный веб движется именно в эту сторону. ))) Т.е. если бы был один фейсбук, то я согласился бы что это исключение. Но кругом плодятся сервисы всё более и более простые по функциональности и сложные по масштабности (Твиттеры, Инстаграмы и прочая нечисть). Причём сервисы уже становится модно писать в стиле прямого обращения из браузера к БД (какой-нибудь nosql, выдающей наружу REST). Я не говорю, что мне это нравится, но такова реальность.
Что ты имеешь ввиду под "современный веб движется именно в эту сторону"? Все используют фейсбук, твиттер и прочите соцсети как сервис. Но практически никто не пишет свои лайки на 100500 миллионов пользователей. А в масштабах того же stackowerflow все прекрасно работает на РСУБД. И это офигенно большие масштабы для типичного веб-проекта. 99% веб-проектов до таких масштабов не дорастут никогда.
G>>В итоге потратили 3 месяца на переход, увеличили потребление ресурсов в два раза, возникла проблема с остановкой при сжатии (слава богу не 24\7 система), быстродействие в совокупности не изменилось. _>Значит не верно выбрали СУБД.
Выбрали ровно так как ты описываешь.
G>>А могли бы просто redis cache поставить и запросы пооптимизировать, но очень хотели на монгу перейти. _>Хыхы, redis — это вообще то тоже игрушка из мира nosql. )))
Редис это кэш, никакого отношения к persistent storage не имеет. По сути почти весь nosql это попытка на простой key-value кэш натянуть persistance. Попытка скорее неудачная.
_>>>А где оно на форуме необходимо то? ))) G>>Ты же видишь свое сообщение сразу после опубликования, вот тебе и гарантии. А представь, что это происходило бы не сразу. А админ за это время захотел поделить текущую тему на две. Упс, пост потерялся.
_>Так и не понял причём тут ACID на форуме.
Видимо дальше разговор бесполезен раз не понял.
_> И видим мы своё сообщение благодаря просто следующему запросу, а не как следствие кода возврата БД.
Когда жмешь отправить — видишь "ваше сообщение добавлено", это и его гарантия, что следующий запрос достанет новое сообщение.
А в nosql было бы "ваше сообщение скоро будет добавлено, поэфпячьте страницу, чтобы его увидеть. А тут начинаются конкуретные апдейты, например для выделения подветки в отделенную тему и база приходит в неконсистентное состояние.
_>Кстати, а вот один из самых современных (и при этом крайне быстрый) движков форумов https://nodebb.org работает с тремя (кстати, как раз через обсуждаемый выше слой абстракции БД) nosql СУБД и никаких проблем не испытывает. Причём одна из них как раз совсем не соответствующая ACID Redis.
Покажи живой инстанс с посещяемостью rsdn.
_>>>Ну так зависит от ситуации. Я же уже описал варианты. Понятно, что если альтернативой служит покупка одного нового сервера, то лучше его купить. А если альтернативой служит покупка тысяч серверов, или повышение на 10% себестоимости устройства с тиражом в миллионы, то лучше уж напрячь программистов. ))) G>>У тебя никогда не будет задач, где месяц работы программиста эквивалентен покупке хотя бы десятка серверов. _>Я что-то не понял, ты считаешь что это не реальные цифры или что? )
Нет, я считаю что ты говоришь, о том, чего у тебя и большинства тут присутствующих никогда не будет. А если рассмотреть то, с чем сталкивается большинство ежедневно, то будет ровно обратная картина тому, что ты говоришь.
Здравствуйте, alex_public, Вы писали:
_>Здравствуйте, Sinclair, Вы писали:
S>>Ещё раз: понятие транзакции является строго определённым везде. Оно формулируется не в терминах реляционной модели, а в терминах абстрактных операций. Как правило — записей и чтений.
_>Конечно. И это определение полностью удовлетворяется во многих nosql СУБД на некотором множестве запросов.
Ты далек от реальности.
Есть лишь единицы nosql движков, которые реализуют транзакции, охватывающие несколько запросов.
Также есть лишь единицы nosql движков, которые могут делать запросы сложнее, чем выборка по ключу.
А пересечение этих двух множеств дает один-два движка, которые имеют TCO выше SQL Server.
_>Ещё раз повторяюсь. Нам на практике требуется что-то вроде "две записи должны добавляться только парой", а не требование вида "хотим транзакции на любых видах запросов". Так что если для конкретных двух нужных нам запросов транзакции nosql работают, то тот факт, что они не работают на других видах запросов нам абсолютно безразличен.
Вот правила вроде "две записи должны добавляться только парой" возникают\меняются по ходу разработки очень часто, а перестраивать схему nosql хранилища каждый раз не представляется возможным. Поэтому можем спокойно считать, что в долгосрочной перспективе почти все nosql движки не умеют делать транзакции.
имеется в виду?
Речь про 1 и 2.
>1) Запросы статические по сути, но сконструированные из нескольких частей, возможно даже в разных функциях. >2) Статические запросы построенные через динамическую композицию — статические части запроса комбинируются разными способами в зависимости от runtime условий (то есть расширение пункта 1).
Да, именно этот вариант мне и не понятен.
Из того что я понял, предлагается представить AST-запроса в типе и производить вычисления в typelevel. Тогда вопрос не к макросам, а к системе типов. Ни в C#, ни в Nemerle typelevel вычислений не предвидится, потому я и хотел узнать у IT, как он видит linq в compile time, и как ему могла помочь Nitra.
EP>Вот здесь
auto q1 = context.Employees;
auto q2 = conditional(!IsNullOrEmpty(lastName), q1.Where(e.LastName = lastName));
auto q3 = conditional(!IsNullOrEmpty(firstName), q2.Where(e.FirstName= firstName));
auto q4 = conditional(HasValue(employmentDateFrom), q3.Where(e.EmploymentDate >= employmentDateFrom.Value));
auto q5 = conditional(HasValue(employmentDateTo)), q4.Where(e.EmploymentDate <= employmentDateTo.Value));
//далее в Presentation Layer (в другом месте)auto list = await q5.Take(pageSize).Select(/*projection*/).ToListAsync();
>При попытке выполнить этот запрос, будет произведено 4 runtime проверки, в результате чего будет выбрана одна из 16 сгенерированных в compile-time версий запроса (причём которые могут кардинально отличаться друг от друга). >Если не нравится экспоненциальное количество запросов в исполняемом файле, то можно добавить динамики. Да, при этом запрос будет частично строится в runtime (с возможным кэшированием), но при этом не будет дорогой runtime reflection — в ней тут нет принципиальной необходимости, достаточно compile-time reflection.
Для наглядности заменил условия
auto q2 = conditional(searchParams.HasFilterByLastName, q1.Where(e.LastName == searchParams.LastName));
auto q3 = conditional(searchParams.HasFilterByFirstName, q2.Where(e.FirstName == searchParams.FirstName));
Тут, со слов IT, мы на каждый qN.Where(e.SomeField == someValue), где someValue может быть null, получаем еще по 2 варианта sql-запроса (с параметром и с 'is null'). Соответственно, число генерируемых запросов растет по экспоненте не только от количества условий, но и от числа нуллабельных переменных.
>4) Стирание полного типа запроса — это позволяет частично отличающимся запросам иметь одинаковый тип. Степень отличия контролируется тем, насколько стёрт тип. >Насколько я вижу, вариант 4) тоже далеко не всегда необходим. Причём каких-то принципиальных предпосылок/аргументов к его необходимости в этом топике я не увидел.
Всегда или нет, но я видел множество ярлычков с какой-то часто используемой логикой вроде:
public IQuerable<Employe> ActiveEmployees { return _context.Employees.Where(e => e.IsActive); }
Итог:
1. нужен язык, поддерживающий вычисления в typelevel
2. размер генерируемого кода растет экспоненциально от числа условий и числа нуллабельных переменных (это только пример с Where разобрали)
3. при изменение запроса, весь зависимый код должен быть перекомпилирован
4. создание публичного интерфейса (типо паттерна "репозиторий") затруднено
5. непонятно, при чем здесь макросы
Здравствуйте, STDray, Вы писали:
STD>Итог: STD>1. нужен язык, поддерживающий вычисления в typelevel STD>2. размер генерируемого кода растет экспоненциально от числа условий и числа нуллабельных переменных (это только пример с Where разобрали) STD>3. при изменение запроса, весь зависимый код должен быть перекомпилирован STD>4. создание публичного интерфейса (типо паттерна "репозиторий") затруднено STD>5. непонятно, при чем здесь макросы
Это необязательно.
Краткий экскурс как обычно работает Linq to something:
1) Строится Expression Tree в рантайме (медленно)
2) ET имеет крайне неудобную структуру для обработки, фактически ты смотришь на выражение "снизу вверх", поэтому следующим шагом ET перестраивается к виду, похожему на исходный запрос. (достаточно быстро, но зависит)
3) Получившийся ET мапится на метаданные (медленно)
4) Генерируется SQL из ET с маппингом (быстро)
5) Выполняется SQL (медленно)
6) Результат мапится на объекты (медленно)
Так вот во всех современных провайдерах п3 и п6 ускоряются за счет кеширования. Фактически основная проблема с быстродействием на сегодня на п1 и п2.
П1 — это то, что генерит компилятор, и библиотеки в это вмешатся не могут. Было бы идеально, если бы прямо в процессе компиляции вместо ET генерировались более "легковесные" (читай не использующие рефлексию) деревья сразу с метаданными меппинга.
Усложняет все IQueryable<T>, так как это универсальный тип и вызов Select невозможно обработать не зная что там внутри IQueryable лежит.
Ну и пердобработку кешей для п3 и п6 тоже можно вынести в compile time. Хотя с п6 сложнее, на каждый тип может мапиться несколько запросов и до разбора дерева по сути неизвестно какой запрос это будет.
K>Почему бы не выкинуть промежуточные этапы? После построения AST на клиенте передавать прямо его в СУБД. В итоге затраты времени linq уменьшат затраты времени в СУБД.
Я бы добавил автоматическую генерацию классов для объектов базы самим sql сервером. А внутри классов воткнуть валидацию.
И чтобы EF мог передать объект в хранимку, а лучше даже коллекцию объектов.
Еще хочу триггер на объект у клиента, и многопоточность в рамках подключения с возможностью навесить nolock на выборку.
Здравствуйте, STDray, Вы писали:
STD>Просто среди плюсов linq не была упомянута возможность собирать запросы в runtime. Например, когда мы к некому IQuerable<T> докидываем неких Where условий. Как это можно решить в compile-time, учитывая вышеописанную параметрозависимую кодогенерацию (пример со значением переменной null)?
Linq сам по себе не лучший способ работы с SQL. Это, конечно, лучше, чем всё остальное, но далеко не идеал, которым могла бы стать генерация специализированного SQL AST. К сожалению, Linq позволяет описывать вещи, которые потом невозможно натянуть на SQL. Некоторые вещи сложны в парсинге и бьют по производительности. Некоторые очень неочевидны. Некоторых просто не хватает. Специализированный расширяемый DSL, встаиваемый в компилятор могбы легко решить все эти проблемы.
Проблема с Where, конечно, частично останется. Но это всё же будет генерации почти SQL — SQL AST, а не непонятно чего, что потом ещё придётся разбирать и транслировать в этот самый SQL AST. Генерация SQL из SQL AST — это простейшая однопроходная задача, в отличии от разбора ET. А если дерево не строится динамически, не содержит проблем вроде null и в компайл-тайм известно под какую СУБД строится SQL, то можно смело строить готовый SQL.
STD>И про синтаксическое расширение тоже не понял: имеется ввиду возможность встроить в язык некий аналог linq, возможность автору аналога к нему докручивать фичи, возможность конечного пользователя что-то там синтаксические расширить?
Да. Например, в linq comprehensions люто не хватает вещей вроде union/skip/take/first/to list/etc. В результате приходится мешать в кучу linq comprehensions и method chaining. Расширение синтаксиса позволило бы решить эту проблему и ещё кучу вроде преобразования GroupJoin/SelectMany в LEFT JOIN.
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, STDray, Вы писали:
>>1) Запросы статические по сути, но сконструированные из нескольких частей, возможно даже в разных функциях. >>2) Статические запросы построенные через динамическую композицию — статические части запроса комбинируются разными способами в зависимости от runtime условий (то есть расширение пункта 1). STD>Да, именно этот вариант мне и не понятен. STD>Из того что я понял, предлагается представить AST-запроса в типе и производить вычисления в typelevel. Тогда вопрос не к макросам, а к системе типов. Ни в C#, ни в Nemerle typelevel вычислений не предвидится, потому я и хотел узнать у IT, как он видит linq в compile time, и как ему могла помочь Nitra.
Nemelre позволяет описать на макросах (которые по сути являются plugin'ом к компилятору) встроенный domain-specific язык для запросов, обработка которого будет происходить во время компиляции этими макросами. То есть вычисления здесь compile-time, но не type-level, а macro/plugin-level.
>>При попытке выполнить этот запрос, будет произведено 4 runtime проверки, в результате чего будет выбрана одна из 16 сгенерированных в compile-time версий запроса (причём которые могут кардинально отличаться друг от друга). >>Если не нравится экспоненциальное количество запросов в исполняемом файле, то можно добавить динамики. Да, при этом запрос будет частично строится в runtime (с возможным кэшированием), но при этом не будет дорогой runtime reflection — в ней тут нет принципиальной необходимости, достаточно compile-time reflection. STD>Для наглядности заменил условия STD>
STD>Тут, со слов IT, мы на каждый qN.Where(e.SomeField == someValue), где someValue может быть null, получаем еще по 2 варианта sql-запроса (с параметром и с 'is null'). Соответственно, число генерируемых запросов растет по экспоненте не только от количества условий, но и от числа нуллабельных переменных.
Nullable я тоже отношу к условиям. И кстати, я думаю куча лишних nullable появляется не от самой задачи/запроса, а от того что в C# по умолчанию nullable-pointer semantics.
На счёт экспоненциального роста — то тут, как я уже сказал, либо генерировать все запросы заранее, либо добавлять динамики. Причём эта динамика может быть легковесной. Думаю далеко не каждое условие существенно влияет на вид запроса — часто это всего лишь присутствие или отсутствие какой-нибудь подстроки.
>>4) Стирание полного типа запроса — это позволяет частично отличающимся запросам иметь одинаковый тип. Степень отличия контролируется тем, насколько стёрт тип. >>Насколько я вижу, вариант 4) тоже далеко не всегда необходим. Причём каких-то принципиальных предпосылок/аргументов к его необходимости в этом топике я не увидел. STD>Всегда или нет, но я видел множество ярлычков с какой-то часто используемой логикой вроде: STD>
public IQuerable<Employe> ActiveEmployees { return _context.Employees.Where(e => e.IsActive); }
Возможно это от ограничений C#, а не продиктованное задачей стирание типа. В C++ например можно вот так:
auto ActiveEmployees() { return _context.Employees.Where(Employees::IsActive); }
STD>Итог: STD>1. нужен язык, поддерживающий вычисления в typelevel
Нужно средство позволяющее описать Domain Specific Language запросов и обрабатывать его на этапе сборки приложения. А встроен ли этот DSL в язык общего назначения, и если встроен то реализован ли он через вычисления на типах, или на макросах, или на функциях времени компиляции — это уже детали.
STD>2. размер генерируемого кода растет экспоненциально от числа условий и числа нуллабельных переменных (это только пример с Where разобрали)
Если полностью генерировать каждый запрос — то да. Точнее экспоненциально растёт количество сгенерированных строчек запроса, а например тот же код mapping'а может быть одним и тем же при разных условиях where.
Более того, экспоненциальный рост мы получим и при кэшировании LINQ — в долгоиграющем приложении будут встречаться разные комбинации условий.
STD>3. при изменение запроса, весь зависимый код должен быть перекомпилирован
Да.
STD>4. создание публичного интерфейса (типо паттерна "репозиторий") затруднено
Проблема со стиранием типа есть, да. Вопрос в том, действительно ли оно нужно задаче, или используется только из-за ограничений языка.
STD>5. непонятно, при чем здесь макросы
В Nemerle это основной (единственный?) способ метапрограммирования.
Здравствуйте, IT, Вы писали:
IT>Это, конечно, лучше, чем всё остальное, но далеко не идеал, которым могла бы стать генерация специализированного SQL AST. К сожалению, Linq позволяет описывать вещи, которые потом невозможно натянуть на SQL.
Речь про использование в лямбдах каких-то функций, которые не имеют аналогов в SQL?
IT>Проблема с Where, конечно, частично останется. Но это всё же будет генерации почти SQL — SQL AST, а не непонятно чего, что потом ещё придётся разбирать и транслировать в этот самый SQL AST. Генерация SQL из SQL AST — это простейшая однопроходная задача, в отличии от разбора ET. А если дерево не строится динамически, не содержит проблем вроде null и в компайл-тайм известно под какую СУБД строится SQL, то можно смело строить готовый SQL.
А этот SQL AST где-то можно увидеть, например в linq2db?
IT>Да. Например, в linq comprehensions люто не хватает вещей вроде union/skip/take/first/to list/etc. В результате приходится мешать в кучу linq comprehensions и method chaining. Расширение синтаксиса позволило бы решить эту проблему и ещё кучу вроде преобразования GroupJoin/SelectMany в LEFT JOIN.
Просто насколько я могу судить, в Nemerle расширять синтаксис можно только в рамках макробиблиотеки предоставляющей данный DSL.
Здравствуйте, gandjustas, Вы писали:
_>>Гораздо дешевле? ))) Это с каких это пор жирные кластеры стали дешёвыми? ) Как раз наоборот, намного дешевле взять несколько простенький серверов (можно вообще на Атоме), объединённых в сеть. G>Это тоже миф, который поддерживают апологеты nosql и подобной муйни. Я перед новым годом считал hp-шные серверы. Сервер в два раз толще оказался на 30% дешевле, чем два сервера.
Это в какой ценовой категории интересно? )
Да, кстати, и два сервера к тому же дают дополнительную надёжность... )
G>Ок, шардить таки можно, но чуть сложнее, чем в nosql, ок? G>При этом помним, что у РСУБД потребность в шардинге на порядок ниже. Грубо говоря noSQL нужно шардить когда объем данных больше объема ОП, а у РСУБД такой необходимости нет.
Угу. ) Это из серии на ассемблере писать таки можно, но чуть сложнее, чем на C#. )
_>>Ну да, согласен, это инструмент требующий умений и продумывания заранее. Но это ещё не повод его не использовать. G>То есть ты признаешь, что использование noSQL требует больше затрат, чем классические РСУБД, тогда зачем их использовать? Сложнее, ресурсов больше надо, в чем профит?
Про ресурсы я ничего такого не говорил. Как раз наоборот, nosql БД обычно летают на совсем дохлых серверах. ))) А вот умений программиста с ними действительно надо больше.
G>Что ты имеешь ввиду под "современный веб движется именно в эту сторону"? Все используют фейсбук, твиттер и прочите соцсети как сервис. Но практически никто не пишет свои лайки на 100500 миллионов пользователей. А в масштабах того же stackowerflow все прекрасно работает на РСУБД. И это офигенно большие масштабы для типичного веб-проекта. 99% веб-проектов до таких масштабов не дорастут никогда.
Stackowerflow и т.п. — это старые проекты. Потому и работают на РСУБД. Речь о текущих стартапах (или уже не совсем стартапах)))).
_>>Хыхы, redis — это вообще то тоже игрушка из мира nosql. ))) G>Редис это кэш, никакого отношения к persistent storage не имеет. По сути почти весь nosql это попытка на простой key-value кэш натянуть persistance. Попытка скорее неудачная.
https://ru.wikipedia.org/wiki/Redis — "Нереляционная высокопроизводительная СУБД." А пример именно кэша, это Memcached (неожиданное название, да? ), который в отличие от Redis не умеет сохранят данные на диск. Ну и кстати для просто кэша у Redis'a многовато типов данных. )))
G>Когда жмешь отправить — видишь "ваше сообщение добавлено", это и его гарантия, что следующий запрос достанет новое сообщение. G>А в nosql было бы "ваше сообщение скоро будет добавлено, поэфпячьте страницу, чтобы его увидеть. А тут начинаются конкуретные апдейты, например для выделения подветки в отделенную тему и база приходит в неконсистентное состояние.
ОК, давай, приведи эту https://community.nodebb.org БД в неконсистентное состояние. )))
_>>Кстати, а вот один из самых современных (и при этом крайне быстрый) движков форумов https://nodebb.org работает с тремя (кстати, как раз через обсуждаемый выше слой абстракции БД) nosql СУБД и никаких проблем не испытывает. Причём одна из них как раз совсем не соответствующая ACID Redis. G>Покажи живой инстанс с посещяемостью rsdn.
Вообще то прямой по моей ссылке в меню можно было найти живое демо. Но я на всякий случай уже дал прямую ссылку в предыдущем абзаце. )))
_>>Я что-то не понял, ты считаешь что это не реальные цифры или что? ) G>Нет, я считаю что ты говоришь, о том, чего у тебя и большинства тут присутствующих никогда не будет. А если рассмотреть то, с чем сталкивается большинство ежедневно, то будет ровно обратная картина тому, что ты говоришь.
Т.е. переводя на русский язык твои кривые намёки, можно сказать, что ты считаешь описанную ситуацию (с преимуществом оптимизации программистами, над заменой железа) редким случаем? )
Здравствуйте, gandjustas, Вы писали:
G>Ты далек от реальности. G>Есть лишь единицы nosql движков, которые реализуют транзакции, охватывающие несколько запросов. G>Также есть лишь единицы nosql движков, которые могут делать запросы сложнее, чем выборка по ключу.
Во-первых ты опять же не учитываешь модель данных и требования на запросы. К примеру если нам нужны ограничения только по модификации внутри одного документа, то... )))
Во-вторых во многих таких СУБД имеется реализация CAS, что соответственно позволяет нам сделать эффективную версионность, откаты и т.п. Что может быть даже интереснее банальных транзакций.
G>Вот правила вроде "две записи должны добавляться только парой" возникают\меняются по ходу разработки очень часто, а перестраивать схему nosql хранилища каждый раз не представляется возможным. Поэтому можем спокойно считать, что в долгосрочной перспективе почти все nosql движки не умеют делать транзакции.
Нууу таким проектировщикам действительно не стоит давать в руки подобные инструменты)))
Здравствуйте, alex_public, Вы писали:
_>>>Кстати, а вот один из самых современных (и при этом крайне быстрый) движков форумов https://nodebb.org работает с тремя (кстати, как раз через обсуждаемый выше слой абстракции БД) nosql СУБД и никаких проблем не испытывает. Причём одна из них как раз совсем не соответствующая ACID Redis. G>>Покажи живой инстанс с посещяемостью rsdn.
_>Вообще то прямой по моей ссылке в меню можно было найти живое демо. Но я на всякий случай уже дал прямую ссылку в предыдущем абзаце. )))
Открыл https://community.nodebb.org/topic/180/who-is-using-nodebb/235, увидел десятки линков с отборнейшим хайлоадом и вебскейлом.
>_>ОК, давай, приведи эту https://community.nodebb.org БД в неконсистентное состояние. )))
Такой хайлод заддэдасить или расконсистентить невозможно никак.
Здравствуйте, STDray, Вы писали:
IT>>Это, конечно, лучше, чем всё остальное, но далеко не идеал, которым могла бы стать генерация специализированного SQL AST. К сожалению, Linq позволяет описывать вещи, которые потом невозможно натянуть на SQL. STD>Речь про использование в лямбдах каких-то функций, которые не имеют аналогов в SQL?
Нет. С лямбдами как раз всё просто. Речь идёт о конструкциях более высокого уровня. Например, опредделённый колорит в запрос приносит Union и Distinct, через которые передаются не просто поля, а объекты, у которых впоследствии используются ассоциации.
IT>>Проблема с Where, конечно, частично останется. Но это всё же будет генерации почти SQL — SQL AST, а не непонятно чего, что потом ещё придётся разбирать и транслировать в этот самый SQL AST. Генерация SQL из SQL AST — это простейшая однопроходная задача, в отличии от разбора ET. А если дерево не строится динамически, не содержит проблем вроде null и в компайл-тайм известно под какую СУБД строится SQL, то можно смело строить готовый SQL. STD>А этот SQL AST где-то можно увидеть, например в linq2db?
https://github.com/linq2db/linq2db/tree/master/Source/SqlQuery — кривенький, но рабочий. По уму надо это дело переделать в аля-ADT структуру и вынести оттуда всю лишнюю функциональность.
IT>>Да. Например, в linq comprehensions люто не хватает вещей вроде union/skip/take/first/to list/etc. В результате приходится мешать в кучу linq comprehensions и method chaining. Расширение синтаксиса позволило бы решить эту проблему и ещё кучу вроде преобразования GroupJoin/SelectMany в LEFT JOIN. STD>Просто насколько я могу судить, в Nemerle расширять синтаксис можно только в рамках макробиблиотеки предоставляющей данный DSL.
Одна из идей Нитры как раз предоставить возможность внешних расширений таких DSL.
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, alex_public, Вы писали:
_>Здравствуйте, gandjustas, Вы писали:
_>>>Гораздо дешевле? ))) Это с каких это пор жирные кластеры стали дешёвыми? ) Как раз наоборот, намного дешевле взять несколько простенький серверов (можно вообще на Атоме), объединённых в сеть. G>>Это тоже миф, который поддерживают апологеты nosql и подобной муйни. Я перед новым годом считал hp-шные серверы. Сервер в два раз толще оказался на 30% дешевле, чем два сервера.
_>Это в какой ценовой категории интересно? )
500к-1М рублей
_>Да, кстати, и два сервера к тому же дают дополнительную надёжность... )
Это только при покупке дополнительных мощностей, сверх необходимого. В противном случае наоборот снижает надежность, так как отказ любого сервера ведет к остановке системы или к деградации производительности.
Если ты шардишь базу в монге, а потом у тебя одна из шард падает, то без реплики ты в большинстве случаев не сможешь продолжать работу.
G>>Ок, шардить таки можно, но чуть сложнее, чем в nosql, ок? G>>При этом помним, что у РСУБД потребность в шардинге на порядок ниже. Грубо говоря noSQL нужно шардить когда объем данных больше объема ОП, а у РСУБД такой необходимости нет. _>Угу. ) Это из серии на ассемблере писать таки можно, но чуть сложнее, чем на C#. )
Я делал шардинг и писал программы на ассемблере, шардинг попроще будет. Да и потребность в нем на порядки (в 10-100 раз) ниже в РСУБД.
_>>>Ну да, согласен, это инструмент требующий умений и продумывания заранее. Но это ещё не повод его не использовать. G>>То есть ты признаешь, что использование noSQL требует больше затрат, чем классические РСУБД, тогда зачем их использовать? Сложнее, ресурсов больше надо, в чем профит? _>Про ресурсы я ничего такого не говорил. Как раз наоборот, nosql БД обычно летают на совсем дохлых серверах. ))) А вот умений программиста с ними действительно надо больше.
Ты опять сравниваешь точечные замеры? Не понял еще что отсутствие гарантий замедляет систему?
G>>Что ты имеешь ввиду под "современный веб движется именно в эту сторону"? Все используют фейсбук, твиттер и прочите соцсети как сервис. Но практически никто не пишет свои лайки на 100500 миллионов пользователей. А в масштабах того же stackowerflow все прекрасно работает на РСУБД. И это офигенно большие масштабы для типичного веб-проекта. 99% веб-проектов до таких масштабов не дорастут никогда.
_>Stackowerflow и т.п. — это старые проекты. Потому и работают на РСУБД.
Ты думаешьтам такие лоши работают, что если бы были профит от nosql они бы не отказались от sqlserver?
_>Речь о текущих стартапах (или уже не совсем стартапах)))).
Вот тебе о стартапах — http://habrahabr.ru/post/231213/ как раз соцсеть с лайками. Прочитай внимательно прежде чем продолжать писать.
_>>>Хыхы, redis — это вообще то тоже игрушка из мира nosql. ))) G>>Редис это кэш, никакого отношения к persistent storage не имеет. По сути почти весь nosql это попытка на простой key-value кэш натянуть persistance. Попытка скорее неудачная.
_>https://ru.wikipedia.org/wiki/Redis — "Нереляционная высокопроизводительная СУБД." А пример именно кэша, это Memcached (неожиданное название, да? ), который в отличие от Redis не умеет сохранят данные на диск. Ну и кстати для просто кэша у Redis'a многовато типов данных. )))
Ты удивишься, но все инстансы редиса, которые я видел в продакшене имеют отключенный persistance. Не нужен он там.
А memcached — говно, банально нету возможности атомарно увеличить счетчик. Без этого его даже в качестве кеша можно использовать с огромной натяжкой.
G>>Когда жмешь отправить — видишь "ваше сообщение добавлено", это и его гарантия, что следующий запрос достанет новое сообщение. G>>А в nosql было бы "ваше сообщение скоро будет добавлено, поэфпячьте страницу, чтобы его увидеть. А тут начинаются конкуретные апдейты, например для выделения подветки в отделенную тему и база приходит в неконсистентное состояние.
_>ОК, давай, приведи эту https://community.nodebb.org БД в неконсистентное состояние. )))
На каждый пост выполняется около 5 обращений к монге, любое падение и база в неконсистентном состоянии. Кроме того это плохо будет работать с multimaster репликацией, так как при репликации вместо инкремента в базу уходит новое значение и легко потерять значения в счетчике при параллельной записи в два разных мастера. Даже ниче специально делать не нужно, оно само рассинхронизируется. Думаешь почему в монгу добавили autoincrement поля?
_>>>Кстати, а вот один из самых современных (и при этом крайне быстрый) движков форумов https://nodebb.org работает с тремя (кстати, как раз через обсуждаемый выше слой абстракции БД) nosql СУБД и никаких проблем не испытывает. Причём одна из них как раз совсем не соответствующая ACID Redis. G>>Покажи живой инстанс с посещяемостью rsdn.
_>Вообще то прямой по моей ссылке в меню можно было найти живое демо. Но я на всякий случай уже дал прямую ссылку в предыдущем абзаце. )))
Еще раз: Покажи живой инстанс с посещяемостью rsdn
_>>>Я что-то не понял, ты считаешь что это не реальные цифры или что? ) G>>Нет, я считаю что ты говоришь, о том, чего у тебя и большинства тут присутствующих никогда не будет. А если рассмотреть то, с чем сталкивается большинство ежедневно, то будет ровно обратная картина тому, что ты говоришь. _>Т.е. переводя на русский язык твои кривые намёки, можно сказать, что ты считаешь описанную ситуацию (с преимуществом оптимизации программистами, над заменой железа) редким случаем? )
Я считаю, что такое возникает гораздо реже, чем об этом ты пишешь.