Здравствуйте, Cyberax, Вы писали:
C>Я же тебе говорил вроде как это пофиксить Делаем свой LazyLoadingHandler и в нём делегируем вызовы в db-поток (или хотя ставим синхронизацию на обращение к сессии).
Хе-хе — я забыл уже Может к этому и вернусь. Как локальное решение для одного места чтения данных — мне подойдёт, но идея распространить на всё приложение мне не нравится. Да. Нужно подумать.
C>Как вариант — отключить LL и смотреть где выпадет.
Здравствуйте, Cyberax, Вы писали:
ANS>>Естественно, это проблема не ORM вообще, а проблема неоптимальности конкретного Hibernate. Проблема ORM в невозможности без проблем работу распаралелить или закешировать. C>"Проблема ORM" или "Проблема Hibernate"?
Проблема скорости — проблема Хиба, проблема с тем, что в каждом потоке нужно вычитывать свои данные — проблема ORM вообще. А вычитывать LL в отдельной транзакции (как в ORM с поэтическим названием Ebean) мне не нравится по транзакционным точкам зрения.
ANS>>Попытки что-то закешировать приводили поначалу к слабоуловимым ошибкамт(совершенно разным и феерическим), а теперь привела к необходимости превентивно резолвить все LL ссылки. Т.е. на всякий случай приходится грузить дерево объектов, потому что не ясно какой кусок, когда и кому понадобится. C>Так ведь и без ORM пришлось бы все данные загружать, так как LL бы не было в принципе. В чём разница?
Найн. Сейчас приходится грузить все данные по любому на всякий случай. Так как узнать где какие данные используются можно только эксперементально
Понял в чем дело! ИМХО, ты неправильно используешь join. Он создан для объединения таблиц, а ты используешь его для отсева данных.
select pr.id from prefect
where pr.parent_group = (select st.parent_group from student st where id = ?)
Вот этот запрос непротиворечит Закону Деметры.
Другой вопрос применим ли он к SQL. Ведь наличие "скобочек" не означает, что внутренний селект стал другой функцией.
P.S. То что оба запроса будут преобразованы в один и тот же план выполнения -- заслуга того что оптимизации оперции join разработчики БД отдали много времени.
Re[25]: Взаимодействие с Базой Данных из C# по схеме MS
Здравствуйте, Aikin, Вы писали:
A>В том-то и дело, что это поле, а не свойство! Свойство == метод. В отличии от него поле допускает безконтрольное изменение объекта. Так же как и anObject.Collection.Add(...)
А часто контроль-то нужен? Мне вот контроль нужен исключительно редко. Get/set методы делают из-за того, что сложно проводить рефакторинг кода, использующего прямой доступ к полям, когда специальные действия всё-таки понадобятся.
В языках, где можно нормально перехватывать доступ к полям при необходимости — методы get/set не нужны.
A>Понял. A>В обоих случаях нарушается Закон Деметры. В обоих вариантах код плох.
В топку тогда "закон", мешающий делать нужные вещи.
A>Задам тебе тот же вопрос: A>Чем отличается код A>
A>select pr.id from prefect pr
A>inner join group grp on pr.parent_group=grp.id
A>inner join student st on st.parent_group=grp.id
A>where st.id=?
A>
A>от A>
A>select pr.id from prefect pr
A>inner join student st on st.parent_group=pr.parent_group
A>where st.id=?
A>
A>?
Ничем, это просто другая форма записи. Надо было более хитрое отношение просто сделать, чтоб так переписать не получилось.
C>>Потом появляются методы TransferIfStudentIsLocal, TransferWithoutReissuingZachetka. A>C какой такой стати?!! Я могу, конечно, представить как такое может получитсья. Но голову на плечах все же иметь нужно
Что значит "с какой-такой стати"? Оно так и нужно бывает, в итоге. Хотя пример со студентом и зачёткой, конечно, натянутый.
Sapienti sat!
Re[26]: Взаимодействие с Базой Данных из C# по схеме MS
Здравствуйте, Cyberax, Вы писали:
A>>В том-то и дело, что это поле, а не свойство! Свойство == метод. В отличии от него поле допускает безконтрольное изменение объекта. Так же как и anObject.Collection.Add(...) C>А часто контроль-то нужен? Мне вот контроль нужен исключительно редко.
Если это не тупой контейнер, то да.
C>Get/set методы делают из-за того, что сложно проводить рефакторинг кода, использующего прямой доступ к полям, когда специальные действия всё-таки понадобятся.
То же самое относится к коллекциям.
A>>Понял. A>>В обоих случаях нарушается Закон Деметры. В обоих вариантах код плох. C>В топку тогда "закон", мешающий делать нужные вещи.
Продолжу: "...нужным мне способом".
C>>>Потом появляются методы TransferIfStudentIsLocal, TransferWithoutReissuingZachetka. A>>C какой такой стати?!! Я могу, конечно, представить как такое может получитсья. Но голову на плечах все же иметь нужно C>Что значит "с какой-такой стати"? Оно так и нужно бывает, в итоге. Хотя пример со студентом и зачёткой, конечно, натянутый.
Я спрашиваю с какой стати появляются толпы методов TransferStudentXYZ()?
Кроме того, даже если они появятся, то они будут локализованы "в своем болоте" и использовать внутри себя один единственный метод переводящий студента из одной группы в другую.
А вообще, Cyberax, не хочешь -- не используй этот закон. Что я к тебе привязался
Всего хорошего.
Re[27]: Взаимодействие с Базой Данных из C# по схеме MS
Здравствуйте, Aikin, Вы писали:
C>>А часто контроль-то нужен? Мне вот контроль нужен исключительно редко. A>Если это не тупой контейнер, то да.
А для чего? Просто интересно так.
C>>Get/set методы делают из-за того, что сложно проводить рефакторинг кода, использующего прямой доступ к полям, когда специальные действия всё-таки понадобятся. A>То же самое относится к коллекциям.
С коллекциями вообще всё плохо. Хотя бы из-за того, что в .NET/Java нет нормальных интерфейсов константных коллекций.
A>>>В обоих случаях нарушается Закон Деметры. В обоих вариантах код плох. C>>В топку тогда "закон", мешающий делать нужные вещи. A>Продолжу: "...нужным мне способом".
Ну так предложи лучший способ.
C>>Что значит "с какой-такой стати"? Оно так и нужно бывает, в итоге. Хотя пример со студентом и зачёткой, конечно, натянутый. A>Я спрашиваю с какой стати появляются толпы методов TransferStudentXYZ()?
Бизнес-процессы часто бывают со сложными вариациями.
A>Кроме того, даже если они появятся, то они будут локализованы "в своем болоте" и использовать внутри себя один единственный метод переводящий студента из одной группы в другую.
Тогда этот метод сведётся к одной строчке. Вот в чём и проблема.
A>А вообще, Cyberax, не хочешь -- не используй этот закон. Что я к тебе привязался
Ну так сам же начал
Sapienti sat!
Re[19]: Взаимодействие с Базой Данных из C# по схеме MS
Здравствуйте, Sinclair, Вы писали:
C>>Ты забыл только упомянуть, что классический SQL — он не Turing-complete. ОЧЕНЬ не Turing-complete. S>Классический SQL — вообще в некотором роде фикция, т.к. он опирается на скалярные функции, набор которых — implementation-specific. А вообще, вроде бы должен быть turing-complete. Ведь достаточно иметь ноль, инкремент, и выбор N-го аргумента
Нет, совсем нет. Ещё оператор примитивной рекурсии забыл.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[28]: Взаимодействие с Базой Данных из C# по схеме MS
Здравствуйте, Cyberax, Вы писали:
C>>>А часто контроль-то нужен? Мне вот контроль нужен исключительно редко. A>>Если это не тупой контейнер, то да. C>А для чего? Просто интересно так.
Я неправильно тебя понял. Контроль-то нужен не частно, но вот отделение самой коллекции от методов ее изменения я практикую почти всегда (исключая "тупые контейнеры").
C>>>Get/set методы делают из-за того, что сложно проводить рефакторинг кода, использующего прямой доступ к полям, когда специальные действия всё-таки понадобятся. A>>То же самое относится к коллекциям. C>С коллекциями вообще всё плохо. Хотя бы из-за того, что в .NET/Java нет нормальных интерфейсов константных коллекций.
В 80% достаточно IEnumeranble, в остальных случаях написать кастомный интерфейс не сложно.
A>>А вообще, Cyberax, не хочешь -- не используй этот закон. Что я к тебе привязался C>Ну так сам же начал
Я обратил внимание и даже не хотел спорить, но ты меня вынудил
Re[25]: Взаимодействие с Базой Данных из C# по схеме MS
Здравствуйте, Aikin, Вы писали:
A>Понял в чем дело! ИМХО, ты неправильно используешь join. Он создан для объединения таблиц, а ты используешь его для отсева данных.
А я что делаю? Соединяю таблицы по ключам. Самое прямое применение для join.
A>
A>select pr.id from prefect
A> where pr.parent_group = (select st.parent_group from student st where id = ?)
A>
A>Вот этот запрос непротиворечит Закону Деметры.
Точно так же противоречит, особенно если ещё один уровень введёшь. Ты просто записываешь одно и то же выражение в разных видах.
A>Другой вопрос применим ли он к SQL. Ведь наличие "скобочек" не означает, что внутренний селект стал другой функцией.
Суть от этого не меняется.
Sapienti sat!
Re[6]: Взаимодействие с Базой Данных из C# по схеме MS
ANS>> А появился потому, что из ОО программы удобнее работать с "объектной формой" чем с реляционными данными. IB>Это заблуждение, к сожалению довольно популярное. Корни его, на самом деле, проистекают из другого, еще более популярного заблуждения — интуитивно-ошибочной интерпретации понятия "ОО программа".
про OO — согласен оно не к месту, но и не с реляционыыми данными.
главное чтобы написаный код могли вместе смотреть заказчик и разработчик,
чтобы когда я буду рядом с ним чтото править по его словам — оно понимал что происходит. чтобы цикл — девеломпент -> фидбек был минимальным.
увы релационные данные не способтвуют этому.
Re[12]: Взаимодействие с Базой Данных из C# по схеме MS
Здравствуйте, IB, Вы писали:
G>>4) Реляционная модель — это не та модель, в которой удобно работать в твоей проге. IB>Собственно, мой поинт в этой дискуссии ровно в том, что на данный момент, для работы с данными, реляционная модель, таки удобнее любой другой. И лучше работать в ОО с реляционной моделью, чем пытаться из данных строить графы объектов. Другое дело, что идеальным решением может быть что-то еще, но это "что-то еще", определенно сильно смахивает на ту же реляционку.
Я тебе чисто, как настоящий сварщик своему коллеге, скажу в ответ вот что. Вступление.
Лет 10 назад мы с друзьями занимались корпоративными приложениями на базе RDBMS, и были рьяниыми сторонниками нормализации и многоуровневых архитектур.
Потом, жизнь заставила позаниматься 1С. Скажем так, я участвовал в открытии двух стартапов 1С-Франчайзи, в обоих — на ключевых ролях, при этом сам активно выполнял наиболее сложные заказы и переучивал людей с RDBMS на 1С. Плевались страшно. Но бабки есть бабки — 1С реально давал прирост в продуктовности от 2 до 10 (!) раз (измеряли) на большинстве заказов по автоматизации по сравнению с RDBMS с 2+ и 3 звенкой.
Потому, через два года, один мой друг пригласил меня помочь в проектировании системы оперативного учета на базе MS SQL и VB. После ознакомления с требованиями, мы решили отступить от правил нормализации и фактически воспроизвести идеологию 1С в данной системе (справочник-документ-отчет — знаком с ней?).
Суть этой идеологии состоит в значительном отходе от нормализации, и оперировании иерархически структурированными сущностями, близкими к предметной области, с реляционными отношениями между ними. Сущностям соответсвует "справочник". Действиям — "документ". Аналитику ты получаешь на основании ROLAP-звезд, записи в которые вносят действия-"документы", это "отчет". В результате, твоя база данных не только "объектна", она "темпоральна", туда встроена своего рода машина времени. Найдя ошибку в рассчете, ты можешь откатить время назад, исправить ее, и накатить вперед, и ошибка исправится. Правда, удобное свойство? Однако, 1Сv7 был ацки медленным. Нам хотелось те же свойства, только штоб быстро работало. Такое возможно.
Данная методология существенно удобнее в случае бизнес систем как для анализа, так и для разработки. Она на порядок выше уровнем, чем классический подход с ER-BP моделями, и прочим. Я хорошо владею классикой, и знаю что говорю.
Так вот. Эмулируя данный подход поверх реляционной БД, мы получили в меньшие сроки лучше структурированную систему, и не проиграв в производительности. Словили — добавочный геморрой с частичной нормализацией и тем, что бизнес-правила записаны в терминах реляционной модели на TransactSQL, а не в терминах составных документов. То есть, чтобы получить gain в продуктивности, надо поменять концепцию^ и думать не в реляционных терминах — они слишком далеки от бизнеса, налицо semantic gap. А как только начинаешь думать в близких к предметной области терминах, RDBMS только гемор создает.
Так вот, эта модель, "справочник-документ-отчет", отлично ложится на безсхемные базы класса map-reduce. Это просто манна небесная, от какого количества проблем она освобождает. Реляционная модель только создает ненужный гемор, как в анализе, так и в разработке.
Ты говоришь она удобна? Не согласен.
Re[31]: Взаимодействие с Базой Данных из C# по схеме MS
Здравствуйте, Andrei N.Sobchuck, Вы писали:
ANS>Проблема скорости — проблема Хиба, проблема с тем, что в каждом потоке нужно вычитывать свои данные — проблема ORM вообще.
Т.е. threadsafe ORM даже в теории невозможны?
ANS>А вычитывать LL в отдельной транзакции (как в ORM с поэтическим названием Ebean) мне не нравится по транзакционным точкам зрения.
Моё решение для твоего случая как раз идеальным будет.
C>>Так ведь и без ORM пришлось бы все данные загружать, так как LL бы не было в принципе. В чём разница? ANS>Найн. Сейчас приходится грузить все данные по любому на всякий случай. Так как узнать где какие данные используются можно только эксперементально
Ну так что без ORM-то изменится?
Sapienti sat!
Re[13]: Взаимодействие с Базой Данных из C# по схеме MS
Здравствуйте, Gaperton, Вы писали:
G>Так вот, эта модель, "справочник-документ-отчет", отлично ложится на безсхемные базы класса map-reduce. Это просто манна небесная, от какого количества проблем она освобождает. Реляционная модель только создает ненужный гемор, как в анализе, так и в разработке.
Это всё работает до поры до времени. На небольших объёмах можно все данные вообще складывать в один блоб и не париться. Всё в XML, XML в блоб. При сегодняшних гигагерцах небольшая бухгалтерия будет летать со свистом. Всевозможные Money от майкрософта и разные квик-буки вообще никаких SQL-серверов не используют и ничего. Проблемы начинаются когда чтобы получить отчёт всё это нужно поднять в память и перемолотить, а памяти и гигагерцев не хватает.
Неясность изложения обычно происходит от путаницы в мыслях.
Если нам не помогут, то мы тоже никого не пощадим.
Re[20]: Взаимодействие с Базой Данных из C# по схеме MS
Здравствуйте, ., Вы писали: .>Нет, совсем нет. Ещё оператор примитивной рекурсии забыл.
Но-но, не надо тут метамодели привлекать. А то недалеко и до Зеноновых парадоксов. Вот где у нас "оператор применения оператора"? А без него непонятно, почему это мы считаем себя вправе применить рекурсию.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[24]: Взаимодействие с Базой Данных из C# по схеме MS
Здравствуйте, Cyberax, Вы писали:
C>Да нифига не рекомендует.
Как это не рекомендует? C>Мне точно так же может потребоваться работа с объектами, скажем , двумя уровнями ниже текущего.
Может. C>И то что они все образуют дерево — тут ничего не решает.
Ты, наверное, не понял. Тебе запрещено обращаться "двумя уровнями ниже текущего". Ты будешь обращаться к "одному уровню ниже текущего", а уже он будет обращаться к своему "нижнему уровню". Это понятно?
C>Да и причём оно здесь вообще?
Это математическое представление принципа Деметры.
C>Ну вот чем отличается вот это: C>
C>select pr.id from prefect pr
C>inner join group grp on pr.parent_group=grp.id
C>inner join student st on st.parent_group=grp.id
C>where st.id=?
C>
C>?
C>Ну кроме того, что мне потребовалась одна простая строчка там, где тебе придётся писать кучу SQL-кода (или LINQ-кода, не суть важно).
Ну, во-первых код отличается тем, что он написан человеком, укушенным ORM. Неукушенные пишут вот так:
select pr.id from prefect pr
inner join student st on pr.parent_group = st.parent_group
where st.id=?
Укушенные постоянно испытывают тягу к избыточному использованию промежуточных сущностей.
C>И почему "закон" Деметры действует в одном случае, но не действует в другом?
Во-вторых, этот код никакого отношения к принципу Деметры не имеет, поскольку здесь нет разыменования ссылок. Совсем. Достаточно убрать where, и это вообще будет полностью симметричный относительно student и prefect запрос. Никто из них ни к кому не обращается. Вопросы типа "почему этот закон не действует" — то же самое, что и спрашивать "а почему налоговые льготы не применимы к закону всемирного тяготения"?
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[32]: Взаимодействие с Базой Данных из C# по схеме MS
Здравствуйте, Cyberax, Вы писали:
ANS>>Проблема скорости — проблема Хиба, проблема с тем, что в каждом потоке нужно вычитывать свои данные — проблема ORM вообще. C>Т.е. threadsafe ORM даже в теории невозможны?
В общем случае — да.
ANS>>А вычитывать LL в отдельной транзакции (как в ORM с поэтическим названием Ebean) мне не нравится по транзакционным точкам зрения. C>Моё решение для твоего случая как раз идеальным будет.
Так этот случай только в нескольких точках запросов. В других местах всё должно быть как обычно. Но это проблема решаемая
C>Ну так что без ORM-то изменится?
Смотри нужно загружать на всякий случай A, B, C, D всегда. А так можно будет загружать A, B или C, D потому что будет видно, что без C, D код не компилится, а A, B не нужен. Плюс зачастую возникает неоптимальность N+1 поведения из-за способа доступа в объектной модели. Естественно решается введением прелоадинга, но такие места могут вести себя нормально при маленькой нагрузке и приводить к проблемам с масштабируемостью. Моё предположение — если бы изначально учитывался способ доступа к реляционным данным, то ряд проблем бы просто не возникало.
Здравствуйте, mogadanez, Вы писали:
M>главное чтобы написаный код могли вместе смотреть заказчик и разработчик,
Если заказчик сам не является разработчиком, то смотреть код ему бесполезно.
M>чтобы когда я буду рядом с ним чтото править по его словам — оно понимал что происходит. чтобы цикл — девеломпент -> фидбек был минимальным. M>увы релационные данные не способтвуют этому.
Это почему это?! Типа заказчик вполне в состоянии вкурить C#, а вот SQL ему не под силу?!
... << RSDN@Home 1.2.0 alpha rev. 673>>
Мы уже победили, просто это еще не так заметно...
Re[13]: Взаимодействие с Базой Данных из C# по схеме MS
Здравствуйте, Gaperton, Вы писали:
G>Я тебе чисто, как настоящий сварщик своему коллеге, скажу в ответ вот что. Вступление.
А я, типа, только каску держал?
G>Лет 10 назад мы с друзьями занимались корпоративными приложениями на базе RDBMS, и были рьяниыми сторонниками нормализации и многоуровневых архитектур.
Нормализация тут непричем. Реляционка хороша тем, что связи там протаптываются с другого конца, чем в OO, в следствии чего любая иерархия строится по месту, а не прибивается гвоздями на этапе проектирования. И такой способ работы с данными удобнее, так как иерархия объектов сильно зависит от конкретного юзкейса и вообще имеет тенденцию эволюционировтаь в процессе эксплуатации приложения и изменениия требований.
G>Так вот, эта модель, "справочник-документ-отчет", отлично ложится на безсхемные базы класса map-reduce.
Посмотрим, если это окажется так, то буду только рад.. С одной стороны "безсхемность" воодушевляет, с другой — одной масштабируемостью в ширь всех проблем с производительностью не вылечишь. Работа с данными характерна тем, что очень плохо размазываются по нескольким серверам и безболезненно масштабировать в ширь можно довольно узкий класс задач. Это очень хорошо видно на tpc-c тестах, где одна большая железка рвет кластеры из 20-40 машин на звездно-полосатый флаг.
... << RSDN@Home 1.2.0 alpha rev. 673>>
Мы уже победили, просто это еще не так заметно...
Re[8]: Взаимодействие с Базой Данных из C# по схеме MS
Здравствуйте, IB, Вы писали:
IB>Здравствуйте, mogadanez, Вы писали:
M>>главное чтобы написаный код могли вместе смотреть заказчик и разработчик, IB>Если заказчик сам не является разработчиком, то смотреть код ему бесполезно.
Это не так.
M>>чтобы когда я буду рядом с ним чтото править по его словам — оно понимал что происходит. чтобы цикл — девеломпент -> фидбек был минимальным. M>>увы релационные данные не способтвуют этому. IB>Это почему это?! Типа заказчик вполне в состоянии вкурить C#, а вот SQL ему не под силу?!
скорее DSL, на крайний случай fluent-interface.
Re[25]: Взаимодействие с Базой Данных из C# по схеме MS
Здравствуйте, Sinclair, Вы писали:
C>>Да нифига не рекомендует. S>Как это не рекомендует?
Так. Циклические графы замечательно тоже подходят.
C>>И то что они все образуют дерево — тут ничего не решает. S>Ты, наверное, не понял. Тебе запрещено обращаться "двумя уровнями ниже текущего". Ты будешь обращаться к "одному уровню ниже текущего", а уже он будет обращаться к своему "нижнему уровню". Это понятно?
Это понятно и нафиг не нужно. Например, при работе с древовидными структурами, где узлы однотипны.
S>Укушенные постоянно испытывают тягу к избыточному использованию промежуточных сущностей.
Ну добавь:
select pr.id, pr.name, ..., grp.id, grp.name, grp.code from prefect pr
inner join group grp on pr.parent_group=grp.id
inner join student st on st.parent_group=grp.id
where st.id=?
Т.е. сразу загружаем нужные данные.
C>>И почему "закон" Деметры действует в одном случае, но не действует в другом? S>Во-вторых, этот код никакого отношения к принципу Деметры не имеет, поскольку здесь нет разыменования ссылок. Совсем.
Есть. Точно такое же, как и в student.getParentGroup().getPrefect(). Просто оно выражается по-другому — через объединения по PK.
S>Достаточно убрать where, и это вообще будет полностью симметричный относительно student и prefect запрос. Никто из них ни к кому не обращается.
Ну так берём коллекцию AllObjects — и выбираем на ней нужные объекты с помощью фильтра. То же самое получится. Только вот это глупо, без where мы полную фигню получим. А с where у нас симметрия моментально теряется.