Re[16]: Взаимодействие с Базой Данных из C# по схеме MS
От: IB Австрия http://rsdn.ru
Дата: 17.09.08 09:07
Оценка: 2 (1) -1 :)
Здравствуйте, Cyberax, Вы писали:

C>То есть?

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

C>А потом по связям этих объектов пройтись, с использованием LL.

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

C>Да. И что из этого?

Из этого следует, что лучше сразу додумать.

C> С LL ситуация абсолютно аналогичная.

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

C>ORM реально позволяет сократить затраты по времени разработки, так что всё нормально. И использовать ORM совсем несложно.

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

C>Ну а что по-твоему делает LL?

Замазывает проблему, вметсо ее решения.

C>>>В том-то и дело, что справляются хуже.

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

C>LINQ — он для выбора данных. Ну получишь ты массив анонимных туплов. Что дальше делать с ними?

Во-первых, не обязательно анонимных, а во-вторых — передам в сервис, который знает что с ними делать.

C>Ну не половину, просто некоторые баги в тёмных углах там пофиксил. Оказалось быстрее, чем переписывать всё с нуля.

Конечно быстрее. После того как ты угробил кучу времени разбираясь с гибернейтом, естественно оказалось быстрее довести дело до конца, чем все бросать... =)
... << RSDN@Home 1.2.0 alpha rev. 673>>
Мы уже победили, просто это еще не так заметно...
Re[19]: Взаимодействие с Базой Данных из C# по схеме MS
От: Cyberax Марс  
Дата: 17.09.08 09:45
Оценка: 6 (1) +2
Здравствуйте, Sinclair, Вы писали:

C>>LL тоже даёт тебе функциональное преимущество — возможность писать persistent-unaware код.

S>Это преимущества совершенно разного рода. Контроль размеров спасает меня от ошибки.
S>От какой ошибки спасает меня возможность писать persistent-unaware код?
От ошибки: "утащу-ка я всё в ХП".

S>Я в очередной раз говорю о том, что абстракция LL — leaky. Не надо ее сравнивать с

Hint: ВСЕ абстракции в какой-то мере leaky. Вопрос в том, перевешивают ли преимущества абстракции её текучесть.

C>>Может быть, логика в процессе разработки поменялась, или ещё что-нибудь. Не все же делают странички, просто показывающие результат одного запроса.

S>Ну поменялась — мы начали загружать другие данные. В чем проблема?
Так менять надо. Особенно замечательно, если получение данных и их отображение достаточно отделены. Или если получением данных занимается какой-то общий сервис.

S>А по факту он используется для "неперсистентных графов"?

Да. В основном, на графах объектов, полученных в виде XML от автономных узлов у клиентов, или на "толстом" GUI-клиенте.

C>>Конечно, можно было бы написать тонкий фильтр в виде хранимки, но тогда пришлось бы поддерживать два варианта кода — в этой хранимке, и на Java.

S>Нет, я не предлагаю опускать такую логику в СУБД. Я всего лишь не понимаю, какое место здесь занимает Lazy Load.
Ситуация — человек хочет взять отгул на какой-то день. Мне для принятия решения нужно: контракт этого человека, контракт с агенством, предоставившим этого человека, историю этого человека, статус в профсоюзе, наличие замены этому человеку и т.п.

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

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

S>На первом этапе — нет. На втором оказывается, что поднимать StoreItem со всеми его потрохами только для того, чтобы показать его Name в составе Order Item — слишом дорого. В итоге делают двухуровневый прокси: StoreItem режут на StoreItemName и StoreItemFull. И всё это потому, что полноценная ORM предлагает жесткую схему объектов.

Жжжуть. Во-первых, можно сделать lazy loading для отдельных полей (Hibernate это умеет). Во-вторых, так я бы точно не делал.

C>>Ты забыл только упомянуть, что классический SQL — он не Turing-complete. ОЧЕНЬ не Turing-complete.

S>Классический SQL — вообще в некотором роде фикция, т.к. он опирается на скалярные функции, набор которых — implementation-specific. А вообще, вроде бы должен быть turing-complete. Ведь достаточно иметь ноль, инкремент, и выбор N-го аргумента
SQL тогда должен быть достаточно мощным, чтобы соревноваться с Java/C#.

C>>Если не нравятся длинные пути — просто переходишь на реляционный стиль. В этом и сила ORM.

S>Ну-ну. И как этот реляционный стиль дружит с транзакциями и кэшем?
Нормально дружит. Какие тут проблемы?

S>
S>from OrderItem i in Connection.OrderItems 
S>    join StoreItem si on i.StoreItemID equals si.ID
S>    select si.Name, i.Quantity
S>

S>Прямо не знаю, сколько нужно ручной работы .
А теперь, пожалуйста, для всех OrderItem'ов, которые находятся в wishlist'е пользователя покажи мне их подробные детали.

Потом детали показать ещё для всех item'ов, помеченных количеством звёзд, выше порога, указанного в профиле пользователя.

C>>Про бОльшее количество деталей, за которыми надо следить.

S>Странно. Деталей меньше в LWORM, а следить приходится больше .
Так не приходится

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

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

В том же Hibernate в Java подключение кэша сводится к нескольким строкам в конфиге, и он даже будет в дефолтной конфигурации работать почти для всех случаев.
Sapienti sat!
Re[20]: Взаимодействие с Базой Данных из C# по схеме MS
От: Sinclair Россия https://github.com/evilguest/
Дата: 17.09.08 11:20
Оценка: +1
Здравствуйте, Cyberax, Вы писали:

C>От ошибки: "утащу-ка я всё в ХП".

1. Не вижу, каким образом LWORM и отсутствие LL провоцирует меня "утащить всё в ХП".
2. Не могу понять, почему утаскивание всего в ХП — это ошибка.
3. Продолжаю непонимать, почему ты смешиваешь ошибку неопределенного поведения (которая возникает при выходе за границы) c ошибкой проектирования.

C>Hint: ВСЕ абстракции в какой-то мере leaky. Вопрос в том, перевешивают ли преимущества абстракции её текучесть.

Hint: Вопрос в том, в какой мере абстракция leaky. Абстракции "Remoteness Ignorance" (aka RPC) и "Persistence Ignorance" — leaky как дырявое ведро.


C>Так менять надо.

А так и так менять надо. Только в лайтвейт подходе сразу видно "ок, тут нам потребуются еще и такие данные", а в ORM ты легким манием руки замедляешь страничку в два-три раза, а потом начинаешь бегать с профайлером наперевес, чтоб понять, откуда всё взялось. А оказывается, там у тебя лишний объект поднялся из базы.
C>Особенно замечательно, если получение данных и их отображение достаточно отделены.

S>>А по факту он используется для "неперсистентных графов"?

C>Да. В основном, на графах объектов, полученных в виде XML от автономных узлов у клиентов, или на "толстом" GUI-клиенте.
Интересно было бы посмотреть на эти графы объектов, и каким именно образом у вас достигается единство обработки transient и LL. И нельзя ли это вынести за пределы LL, и обеспечить статический контроль компилятором соответствия алгоритма обрабатываемой модели.

S>>Нет, я не предлагаю опускать такую логику в СУБД. Я всего лишь не понимаю, какое место здесь занимает Lazy Load.

C>Ситуация — человек хочет взять отгул на какой-то день. Мне для принятия решения нужно: контракт этого человека, контракт с агенством, предоставившим этого человека, историю этого человека, статус в профсоюзе, наличие замены этому человеку и т.п.

C>Один только список inner join'ов будет на страницу, если сразу все данные подгружать.

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

C>Причём вполне вероятно, что почти все эти данные не потребуются, если первое же правило даст отрицательный результат.


C>Да, и на практике почти все необходимые данные (контракты между кадровым агенством и заказчиком, профсоюзные данные и т.п.) будут висеть в кэше. Следовательно, обращение к ним будет на порядки быстрее запроса к БД.

Ну, нас же волнует не количество cache hit, а количество cache miss. Даже один cache miss — это практически то же самое, как если бы мы честно забрали все данные из базы. А если мы начинаем раздувать кэш, то появляются другие проблемы.

C>Жжжуть. Во-первых, можно сделать lazy loading для отдельных полей (Hibernate это умеет).

Да-да, именно для отдельных. Вот это и превращает схему в Ктулху. ж)
C>Во-вторых, так я бы точно не делал.

C>SQL тогда должен быть достаточно мощным, чтобы соревноваться с Java/C#.

Не надо путать мощность языка с его turing-completeness.

C>>>Если не нравятся длинные пути — просто переходишь на реляционный стиль. В этом и сила ORM.

S>>Ну-ну. И как этот реляционный стиль дружит с транзакциями и кэшем?
C>Нормально дружит. Какие тут проблемы?
Ну вот гибернейт свои запросы где выполняет — в сервере или в кэше? А если у меня в кэше есть измененные объекты, которые всё еще незакоммичены в СУБД, каким образом вычисляются предикаты? А в контексте этой же транзакции?

S>>
S>>from OrderItem i in Connection.OrderItems 
S>>    join StoreItem si on i.StoreItemID equals si.ID
S>>    select si.Name, i.Quantity
S>>

S>>Прямо не знаю, сколько нужно ручной работы .
C>А теперь, пожалуйста, для всех OrderItem'ов, которые находятся в wishlist'е пользователя покажи мне их подробные детали.
Что именно понимается под "подробными деталями"? Ты сомневаешься, что я смогу поджойнить вишлист с ордерайтемами на linq?

C>Потом детали показать ещё для всех item'ов, помеченных количеством звёзд, выше порога, указанного в профиле пользователя.

Перестань — устанет рука.

C>Так не приходится


C>Локальная когерентность кэша решается интеграцией его в ORM. Межузловая когерентность — с помощью кластерных кэшей. Руками его делать — это да, полная дупа.

При чем здесь руками? Речь о том, что чем толще кэш, тем больше затраты на когерентность. Неважно, руками или головой — просто появляется нужда в распределенных транзакциях и оповещениях о сбросе кэша. А это нифига не бесплатно.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[21]: Взаимодействие с Базой Данных из C# по схеме MS
От: Andrei N.Sobchuck Украина www.smalltalk.ru
Дата: 17.09.08 12:38
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Hint: Вопрос в том, в какой мере абстракция leaky. Абстракции "Remoteness Ignorance" (aka RPC) и "Persistence Ignorance" — leaky как дырявое ведро.


Кстати, на тему RPC есть статья г-на Армстронга (того что с Erlang). Там в коментах еще есть ссылки интересные.
http://www.smalltalk.ru << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Я ненавижу Hibernate
Автор: Andrei N.Sobchuck
Дата: 08.01.08
!
Re[21]: Взаимодействие с Базой Данных из C# по схеме MS
От: Cyberax Марс  
Дата: 17.09.08 12:49
Оценка:
Здравствуйте, Sinclair, Вы писали:

C>>От ошибки: "утащу-ка я всё в ХП".

S>1. Не вижу, каким образом LWORM и отсутствие LL провоцирует меня "утащить всё в ХП".
Чтобы сразу загрузить все данные.

S>2. Не могу понять, почему утаскивание всего в ХП — это ошибка.

Не буду сейчас флеймить...

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

Ну ладно. Ты пишешь код с тщательной проверкой cache-friendlyness? А ведь тут уже приводились horror stories с многодесятикратными замедлениями доступа при промахах по кэшу.

C>>Hint: ВСЕ абстракции в какой-то мере leaky. Вопрос в том, перевешивают ли преимущества абстракции её текучесть.

S>Hint: Вопрос в том, в какой мере абстракция leaky. Абстракции "Remoteness Ignorance" (aka RPC) и "Persistence Ignorance" — leaky как дырявое ведро.
Но тем не менее, иногда полезны. Например, RPC через FibreChannel (с латентностью в микросекунды) — приятнейшая вещь.

S>А так и так менять надо. Только в лайтвейт подходе сразу видно "ок, тут нам потребуются еще и такие данные", а в ORM ты легким манием руки замедляешь страничку в два-три раза, а потом начинаешь бегать с профайлером наперевес, чтоб понять, откуда всё взялось. А оказывается, там у тебя лишний объект поднялся из базы.

Чаще всего замедления просто нет.

S>Интересно было бы посмотреть на эти графы объектов, и каким именно образом у вас достигается единство обработки transient и LL. И нельзя ли это вынести за пределы LL, и обеспечить статический контроль компилятором соответствия алгоритма обрабатываемой модели.

Там у меня сложная система для всего этого Статический контроль — вряд ли, не представляю как это возможно сделать.

C>>Один только список inner join'ов будет на страницу, если сразу все данные подгружать.

S>Так, теперь мы уже до inner join договорились. Они-то тут причем?
Чтоб утащить данные одним запросом.

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

Сейчас померял память — во время выполнения запроса потребление подскакивает на 5Мб. Значит, что-то порядка 500 килобайт данных из БД уходит.

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

S>Ну, нас же волнует не количество cache hit, а количество cache miss. Даже один cache miss — это практически то же самое, как если бы мы честно забрали все данные из базы. А если мы начинаем раздувать кэш, то появляются другие проблемы.

Объём многих данных сильно ограничен. Скажем, контрактов не будет больше нескольких десятков тысяч — оно всё ложится в кэш и там сидит. Профсоюзных данных тоже не так много, оно тоже всё будет резидентным.

Посмотрел в статистку — cache miss'ов в системе набирается сотня штук за день. Надо бы посмотреть откуда, не должно быть их вообще...

C>>SQL тогда должен быть достаточно мощным, чтобы соревноваться с Java/C#.

S> Не надо путать мощность языка с его turing-completeness.
Ну так не надо путать теоретическую полноту по Тьюрингу и юзабельность.

S>Ну вот гибернейт свои запросы где выполняет — в сервере или в кэше? А если у меня в кэше есть измененные объекты, которые всё еще незакоммичены в СУБД, каким образом вычисляются предикаты? А в контексте этой же транзакции?

Запросы выполняются в БД. Из кэша данные берутся только при простых запросах по PK или lookup'у коллекций. С транзакциями полностью всё совместимо, кэши в Hibernate дают изоляцию READ COMMITED для всей транзакции, при испльзовании пессимистических блокировок — даже REPEATABLE READ.

Могу подробнее объяснить, если интересно.

S>Что именно понимается под "подробными деталями"? Ты сомневаешься, что я смогу поджойнить вишлист с ордерайтемами на linq?

Подробные детали — из объектов DetailedInfo и VendorInfo. Поджойнить ты сможешь без проблем, но представь, что отображение у тебя в generic-коде делается.

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

Это часто всё равно дешевле, чем работа с БД. У меня как раз сейчас кластерный кэш используется, кстати.
Sapienti sat!
Re[3]: Взаимодействие с Базой Данных из C# по схеме MS
От: WaSh http://kxlm.blogspot.com/
Дата: 17.09.08 18:28
Оценка:
согласен...
... << RSDN@Home 1.2.0 alpha 4 rev. 1108>>
блог http://kxlm.blogspot.com/
Re[22]: Взаимодействие с Базой Данных из C# по схеме MS
От: Sinclair Россия https://github.com/evilguest/
Дата: 18.09.08 03:33
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>Чтобы сразу загрузить все данные.

не вижу логики.

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

C>Ну ладно. Ты пишешь код с тщательной проверкой cache-friendlyness? А ведь тут уже приводились horror stories с многодесятикратными замедлениями доступа при промахах по кэшу.
Нет. В коде, который я пишу, processor cache miss стоит бесконечно мало по сравнению с временем исполнения запроса.

C>Но тем не менее, иногда полезны. Например, RPC через FibreChannel (с латентностью в микросекунды) — приятнейшая вещь.

Ну, наверное и Persistence Ignorance поверх чего-нибудь экзотического — приятнейшая вещь. Осталось найти, поверх чего именно.

C>Чаще всего замедления просто нет.

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

C>Там у меня сложная система для всего этого Статический контроль — вряд ли, не представляю как это возможно сделать.

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

S>>Так, теперь мы уже до inner join договорились. Они-то тут причем?

C>Чтоб утащить данные одним запросом.
Бред какой-то. Зачем одним запросом-то? Делаешь batch и всех делов .

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

C>Сейчас померял память — во время выполнения запроса потребление подскакивает на 5Мб. Значит, что-то порядка 500 килобайт данных из БД уходит.
Это ты неправильно меришь. Ты по алгоритму пройдись, посмотри, что ему реально нужно. В то, что ты там мегабайты из базы гоняешь я легко верю — c ORM в это легко наступить.

C>Нужен неполный контракт, но экономить на паре полей там просто смысла нет, не это там bottleneck. Опять же, если пытаться оптимизировать вытягиваемые данные вплоть до поля — получим Ктулху-запрос.

Не получим. Это вы просто SQL готовить не умеете. Вон, уже иннер джойны пошли... С таким подходом вам конечно прямая дорога в ОРМ. Чтоб ктулхов от вас спрятать. Ктулху-игноранс?

C>Объём многих данных сильно ограничен. Скажем, контрактов не будет больше нескольких десятков тысяч — оно всё ложится в кэш и там сидит.

Если у тебя на пару контрактов уходит 5 метров, сколько же потребуется для десятков тысяч?
C>Профсоюзных данных тоже не так много, оно тоже всё будет резидентным.

C>Посмотрел в статистку — cache miss'ов в системе набирается сотня штук за день. Надо бы посмотреть откуда, не должно быть их вообще...


C>Ну так не надо путать теоретическую полноту по Тьюрингу и юзабельность.

Я-то не путаю. Это ты начал рассказывать про то, как неполнота SQL тебе мешает жить.

S>>Ну вот гибернейт свои запросы где выполняет — в сервере или в кэше? А если у меня в кэше есть измененные объекты, которые всё еще незакоммичены в СУБД, каким образом вычисляются предикаты? А в контексте этой же транзакции?

C>Запросы выполняются в БД. Из кэша данные берутся только при простых запросах по PK или lookup'у коллекций. С транзакциями полностью всё совместимо, кэши в Hibernate дают изоляцию READ COMMITED для всей транзакции, при испльзовании пессимистических блокировок — даже REPEATABLE READ.

C>Могу подробнее объяснить, если интересно.

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

C>Подробные детали — из объектов DetailedInfo и VendorInfo. Поджойнить ты сможешь без проблем, но представь, что отображение у тебя в generic-коде делается.

Ну, представляю, и что? В чем проблема-то?
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[23]: Взаимодействие с Базой Данных из C# по схеме MS
От: Cyberax Марс  
Дата: 18.09.08 08:52
Оценка:
Здравствуйте, Sinclair, Вы писали:

C>>Чтобы сразу загрузить все данные.

S> не вижу логики.
Объяснить?

C>>Ну ладно. Ты пишешь код с тщательной проверкой cache-friendlyness? А ведь тут уже приводились horror stories с многодесятикратными замедлениями доступа при промахах по кэшу.

S>Нет. В коде, который я пишу, processor cache miss стоит бесконечно мало по сравнению с временем исполнения запроса.
Не так уж мало — замедление при cache miss достигает порядка 20 раз.

C>>Но тем не менее, иногда полезны. Например, RPC через FibreChannel (с латентностью в микросекунды) — приятнейшая вещь.

S>Ну, наверное и Persistence Ignorance поверх чего-нибудь экзотического — приятнейшая вещь. Осталось найти, поверх чего именно.
Hibernate

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

Обычно эти часики надоедают мне самому ещё при отладке. Так что я их исправляю.

C>>Там у меня сложная система для всего этого Статический контроль — вряд ли, не представляю как это возможно сделать.

S>Лично я как раз хорошо себе представляю. Тебя же не удивляет, что компилятор ухитряется отказываться компилировать итерацию по классам, которые не поддерживают Enumerable pattern?
Это-то примитив, ничего сложного.

C>>Чтоб утащить данные одним запросом.

S>Бред какой-то. Зачем одним запросом-то? Делаешь batch и всех делов .
Ну будет список команд в batch'е на страницу. Разница-то какая?

C>>Сейчас померял память — во время выполнения запроса потребление подскакивает на 5Мб. Значит, что-то порядка 500 килобайт данных из БД уходит.

S>Это ты неправильно меришь. Ты по алгоритму пройдись, посмотри, что ему реально нужно. В то, что ты там мегабайты из базы гоняешь я легко верю — c ORM в это легко наступить.
Оно только то что нужно подгоняет (ленивые ссылки, однако). Если разбирать на отдельные поля — сильно большого выигрыша не будет, нет у меня там таблиц с килобайтными полями.

S>Не получим. Это вы просто SQL готовить не умеете. Вон, уже иннер джойны пошли... С таким подходом вам конечно прямая дорога в ОРМ. Чтоб ктулхов от вас спрятать. Ктулху-игноранс?

Ага. Чтоб с ума не свёл.

C>>Объём многих данных сильно ограничен. Скажем, контрактов не будет больше нескольких десятков тысяч — оно всё ложится в кэш и там сидит.

S>Если у тебя на пару контрактов уходит 5 метров, сколько же потребуется для десятков тысяч?
Я оцениваю где-то в 10Гб памяти. Сейчас совокупная ёмкость памяти всех узлов — около 40Гб.

C>>Ну так не надо путать теоретическую полноту по Тьюрингу и юзабельность.

S>Я-то не путаю. Это ты начал рассказывать про то, как неполнота SQL тебе мешает жить.
Мешает.

C>>Могу подробнее объяснить, если интересно.

S>Объясни. Мне интересно, как именно происходит чудо.
Оптимистическое версирование и никакого мошенничества

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

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

S>Можешь просто ответить на вопрос: что вернет реляционный запрос, если у меня в кэше есть незакоммиченный объект, модифицированный в этой же транзакции?

Перед запросом этот объект будет (по умолчанию) за-flush-ен в БД (без коммита), так что БД вернёт всё корректно.

C>>Подробные детали — из объектов DetailedInfo и VendorInfo. Поджойнить ты сможешь без проблем, но представь, что отображение у тебя в generic-коде делается.

S>Ну, представляю, и что? В чем проблема-то?
Запросы будут расти. А ещё особенно приятно, если оно не всегда нужно будет.
Sapienti sat!
Re[24]: Взаимодействие с Базой Данных из C# по схеме MS
От: Sinclair Россия https://github.com/evilguest/
Дата: 18.09.08 09:47
Оценка: +1
Здравствуйте, Cyberax, Вы писали:

C>Объяснить?

Объясни.

S>>Нет. В коде, который я пишу, processor cache miss стоит бесконечно мало по сравнению с временем исполнения запроса.

C>Не так уж мало — замедление при cache miss достигает порядка 20 раз.
Замедление чего? Поясняю: вот у нас на генерацию страницы уходит 20ms. Сколько стоит один processor cache miss? А сколько стоит miss в Hibernate?

C>Ну будет список команд в batch'е на страницу. Разница-то какая?

Разница будет в плане выполнения.

C>Оно только то что нужно подгоняет (ленивые ссылки, однако). Если разбирать на отдельные поля — сильно большого выигрыша не будет, нет у меня там таблиц с килобайтными полями.

Дело не в размере полей, дело в их количестве. Грамотная проекция — это очень хорошо, потому что 80% полей используются только иногда.
S>>Если у тебя на пару контрактов уходит 5 метров, сколько же потребуется для десятков тысяч?
C>Я оцениваю где-то в 10Гб памяти. Сейчас совокупная ёмкость памяти всех узлов — около 40Гб.
Круто. Что тут скажешь. А характерный размер БД какой будет?

S>>Объясни. Мне интересно, как именно происходит чудо.

C>Оптимистическое версирование и никакого мошенничества
То есть каждая транзакция получает свою независимую копию объекта из кэша?

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


C>Перед запросом этот объект будет (по умолчанию) за-flush-ен в БД (без коммита), так что БД вернёт всё корректно.

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

C>Запросы будут расти. А ещё особенно приятно, если оно не всегда нужно будет.

Особенно приятно то, что в LWORM подходе ты как раз выбираешь то, что нужно. Явным образом. Это в FBORM стоит тебе сослаться на VendorInfo, как подтянется всё лишнее.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[25]: Взаимодействие с Базой Данных из C# по схеме MS
От: Cyberax Марс  
Дата: 18.09.08 19:53
Оценка: +1
Здравствуйте, Sinclair, Вы писали:

C>>Объяснить?

S>Объясни.
Объ

C>>Не так уж мало — замедление при cache miss достигает порядка 20 раз.

S>Замедление чего? Поясняю: вот у нас на генерацию страницы уходит 20ms. Сколько стоит один processor cache miss? А сколько стоит miss в Hibernate?
"Один журнал помещаем в серную кислоту, а другой в дистиллированую воду"

Cache miss стоит в Hibernate ровно столько, сколько стоит roundtrip до БД с простейшим запросом (выбор объекта по PK или коллекции по обратной ссылке).

C>>Ну будет список команд в batch'е на страницу. Разница-то какая?

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

S>Дело не в размере полей, дело в их количестве. Грамотная проекция — это очень хорошо, потому что 80% полей используются только иногда.

Ерунда это. Я нафиг не буду смотреть какие мне поля могут понадобится во всех ветках алгоритма — это сэкономит буквально почти ничего.

C>>Я оцениваю где-то в 10Гб памяти. Сейчас совокупная ёмкость памяти всех узлов — около 40Гб.

S>Круто. Что тут скажешь. А характерный размер БД какой будет?
Пока перешагивает за 5Гб, планируется, что будет прирастать примерно по 3-4Гб в год. Но там большая часть того, что читается вообще всего пару раз за всё время использование приложения. "Горячих" данных сильно больше становиться не будет.

C>>Оптимистическое версирование и никакого мошенничества

S>То есть каждая транзакция получает свою независимую копию объекта из кэша?
Да. Независимые копии нужны ещё для поддержания корректности идентичности объектов.

C>>Перед запросом этот объект будет (по умолчанию) за-flush-ен в БД (без коммита), так что БД вернёт всё корректно.

S>То есть каждый реляционный запрос приводит к принудительному сбросу накопленных модификаций, и при этом еще и удерживается открытая транзакция???? Копец.
Да. Но это не имеет отношения к кэшу второго уровня (разделяемому). Тут даже если ты используешь ТакойЛегковесныйМэпперЧтоОнИмеетОтрицательнуюМассу, то при изменении данных в памяти без их апдейта в БД — не стоит ждать consistency от запросов.

Т.е.:
SomeObject obj=veryLightweightMapper.mapToObject("select .... from some_object...");

obj.setName("New name");

//_Не_ делаем flush
//veryLightweightMapper.saveModified(obj)

SomeObject obj2=veryLightweightMapper.mapToObject("select .... from some_object...");
assert(obj2.getName().equals(obj.getName())); //Ой, а чего это оно???

И Hibernate тут НИЧЕМ не отличается.

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

C>>Запросы будут расти. А ещё особенно приятно, если оно не всегда нужно будет.

S>Особенно приятно то, что в LWORM подходе ты как раз выбираешь то, что нужно. Явным образом. Это в FBORM стоит тебе сослаться на VendorInfo, как подтянется всё лишнее.
Ну и? Ты похож на хардкорного С-шника — они тоже используют только то, "что нужно". И нафиг им не нужны эти всякие .NET FW, навязывающие огромную библиотеку классов.

На практике разницы между взятием всего ряда и пары полей почти всегда нет. Тем более, что БД чаще всего хранят все данные ряда в одном месте. Конечно, если используются "колоночные" базы данных и прочая жуть — то вообще о каком-либо ORM стоит забыть, скорее всего.
Sapienti sat!
Re[26]: Взаимодействие с Базой Данных из C# по схеме MS
От: Cyberax Марс  
Дата: 18.09.08 19:59
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>Объ

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

C>Пока перешагивает за 5Гб, планируется, что будет прирастать примерно по 3-4Гб в год. Но там большая часть того, что читается вообще всего пару раз за всё время использование приложения. "Горячих" данных сильно больше становиться не будет.

Блин, хотел написать 50Гб и 30-40Гб в год.
Sapienti sat!
Re: Взаимодействие с Базой Данных из C# по схеме MS
От: IT Россия linq2db.com
Дата: 19.09.08 01:42
Оценка: 4 (2) +2
Здравствуйте, <Аноним>, Вы писали:

А можно я, можно я??? Спасибо!!!

А>1. Какак я понимаю, Linq забил последний гвоздь в крышку гроба NHibernate, или я ошибаюсь? Т.е. с появлением технологии Linq, NHibernate теряет всякий смысл?


Это очевидно.

Исторически DAL и прочие ORM появились как адекватный ответ на проблему типизированной работы с источником данных, точнее с отсутствием типизации. Некоторые решения остановились на минимально необходимом решении самой проблемы, некоторые пошли дальше, предлагая полную абстракцию от источника данных, используя в качестве такой абстракции объектную модель приложения. В результате мы имеем следующую модель взаимодействия: приложение <-> объектная модель <-> источник данных (включая его модель).

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

Нужна ли сама по себе объектная модель? Во многих случаях — да. Так, например, функционально богатое UI приложение может иметь свою объектную модель. Но как правило эта модель весьма сильно отличается от модели источника данных, т.к. предназначена для решения совсем других задач, никак не связанных с проблемами персистентности. Такие модели существовали задолго до появления ORM и никуда не делись с их появлением. Но объектная модель как заменитель источника данных больше не нужна. Более того, пытаясь быть и заменителем источника данных и объектной моделью приложения одновременно, такая модель делает хуже и то и другое, чем эти вещи по раздельности. Т.е. получается такая "объектная недомодель приложения совмещённая с недоисточником данных".

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

Вывод таков — объектная модель, предлагаемая ORM по сути своей сегодня являет рудимент и атавизм, тупиковую ветвь прогресса. Думаю, что следующим на очереди будет переосмыслени функции DAL
Неясность изложения обычно происходит от путаницы в мыслях.
Если нам не помогут, то мы тоже никого не пощадим.
Re[2]: Взаимодействие с Базой Данных из C# по схеме MS
От: Andrei N.Sobchuck Украина www.smalltalk.ru
Дата: 19.09.08 07:42
Оценка: -1
Здравствуйте, IT, Вы писали:

IT>Это очевидно.


IT>Исторически DAL и прочие ORM появились как адекватный ответ на проблему типизированной работы с источником данных, IT>Вывод таков — объектная модель, предлагаемая ORM по сути своей сегодня являет рудимент и атавизм, тупиковую ветвь


Связи между объектностью модели и типизируемостью нету. Значит исходный посыл ошибошен, значит весь пост ошибочен.
http://www.smalltalk.ru << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Я ненавижу Hibernate
Автор: Andrei N.Sobchuck
Дата: 08.01.08
!
Re[16]: Взаимодействие с Базой Данных из C# по схеме MS
От: Aikin Беларусь kavaleu.ru
Дата: 19.09.08 08:08
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>Чаще всего для LL характерен такой код "someStudent.getParentGroup().getGroupPrefect().addToAssignments(...)".

Law Of Demeter?
Re[17]: Взаимодействие с Базой Данных из C# по схеме MS
От: Cyberax Марс  
Дата: 19.09.08 08:21
Оценка:
Здравствуйте, Aikin, Вы писали:

C>>Чаще всего для LL характерен такой код "someStudent.getParentGroup().getGroupPrefect().addToAssignments(...)".

A>Law Of Demeter?
Тогда он периодически нарушается в реляционных БД в запросах, затрагивающих более двух таблиц.
Sapienti sat!
Re[17]: Взаимодействие с Базой Данных из C# по схеме MS
От: Cyberax Марс  
Дата: 19.09.08 08:24
Оценка:
Здравствуйте, Aikin, Вы писали:

C>>Чаще всего для LL характерен такой код "someStudent.getParentGroup().getGroupPrefect().addToAssignments(...)".

A>Law Of Demeter?
Кстати, он ещё и противоречит принципу, что методы класс должны заниматься только тем, что требует доступа к его приватным данным.
Sapienti sat!
Re[26]: Взаимодействие с Базой Данных из C# по схеме MS
От: Andrei N.Sobchuck Украина www.smalltalk.ru
Дата: 19.09.08 08:40
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>Ерунда это. Я нафиг не буду смотреть какие мне поля могут понадобится во всех ветках алгоритма — это сэкономит буквально почти ничего.


Полей — может и ерунда. А отсутсвие необходимости декларировать используемые сущности приводит к тому, что невозможно понять какому куску кода какие данные нужны и когда они будут загружены. Значит нельзя вычленить кусок кода которому для работы доступ к БД не нужен. Это приводит к принципиальной немногопоточности.
http://www.smalltalk.ru << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Я ненавижу Hibernate
Автор: Andrei N.Sobchuck
Дата: 08.01.08
!
Re[18]: Взаимодействие с Базой Данных из C# по схеме MS
От: Aikin Беларусь kavaleu.ru
Дата: 19.09.08 09:04
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>>>Чаще всего для LL характерен такой код "someStudent.getParentGroup().getGroupPrefect().addToAssignments(...)".

A>>Law Of Demeter?
C>Тогда он периодически нарушается в реляционных БД в запросах, затрагивающих более двух таблиц.
Cyberax, я его превел не в контексте спора, а сам по себе. Очень правильный закон ограничивающий связность системы. Не стоит о нем забывать.

В частности закон деметры запрещает проектировать классы с вложенными коллекциями в виде: order.Items.Add(newItem) предлагая в замен order.AddItem(newItem).

СУВ, Aikin

P.S. Тем более никаким образом он не ограничивает запросы из двух таблиц
Re[18]: Взаимодействие с Базой Данных из C# по схеме MS
От: Aikin Беларусь kavaleu.ru
Дата: 19.09.08 09:04
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>>>Чаще всего для LL характерен такой код "someStudent.getParentGroup().getGroupPrefect().addToAssignments(...)".

A>>Law Of Demeter?
C>Кстати, он ещё и противоречит принципу, что методы класс должны заниматься только тем, что требует доступа к его приватным данным.
1) Каким это образом? Тем, что он не запрещает?
2) Что это за принцип-то такой? Не мог бы ты полнее его озвучить?


СУВ, Aikin
Re[3]: Взаимодействие с Базой Данных из C# по схеме MS
От: IT Россия linq2db.com
Дата: 19.09.08 13:23
Оценка:
Здравствуйте, Andrei N.Sobchuck, Вы писали:

ANS>Связи между объектностью модели и типизируемостью нету.


А что по твоему есть типизируемость в C#?

ANS>Значит исходный посыл ошибошен, значит весь пост ошибочен.


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