Re[37]: Фреймфорк для разработки Веб и десктоп-приложений на
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 02.10.09 08:15
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, gandjustas, Вы писали:


G>>Не понял, что именно сделать джоином?


VD>Выборку данных.


Я же и говорю что явный джоин гораздо лучше LL.

А проблема SELECT N+1 в основном не так явно выглядит.
Обычно что-то в этом роде:


public class Order
{
    //LLCollection не IQueryable, поэтому при ленивой загрузке вытягиваются полные объекты
    public LLCollection<OrderLine> OrderLines { get; }

    public decimal Total
    {
        get
        {
            return OrderLines.Sum(l => l.Price * l.Quantity);
        }
    }
}

//в другом методе, в другой сборке, написанной другим человеком
...
var orders = dal.GetSomeOrders(...)
var sum = orders.Sum(o => o.Total);   
...


Ну вот как-то так.
Re[40]: Фреймфорк для разработки Веб и десктоп-приложений на
От: Ziaw Россия  
Дата: 02.10.09 08:34
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, Ziaw, Вы писали:


Z>>Я рассматриваю построение модели не как способ сокрытия реляционности, а как способ создать удобный ДСЛ для запросов.


VD>Удобнее чем LINQ все равно создать не получится. Так что ты прост делаешь бессмысленную работу.


Так LINQ прикручивают к гибернейту и если год назад я утверждал, что та реализация тупиковая, то сейчас вижу нормальное решение.
А год назад не было альтернатив с поддержкой линка для нормального построения модели под требуемые нам СУБД.
Впрочем и сейчас тулкит в продакшен пускать рисковано.
... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
Re[38]: Фреймфорк для разработки Веб и десктоп-приложений на
От: VladD2 Российская Империя www.nemerle.org
Дата: 02.10.09 08:37
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>
G>public class Order
G>{
G>    //LLCollection не IQueryable, поэтому при ленивой загрузке вытягиваются полные объекты
G>    public LLCollection<OrderLine> OrderLines { get; }

G>    public decimal Total
G>    {
G>        get
G>        {
G>            return OrderLines.Sum(l => l.Price * l.Quantity);
G>        }
G>    }
G>}

G>//в другом методе, в другой сборке, написанной другим человеком
G>...
G>var orders = dal.GetSomeOrders(...)
G>var sum = orders.Sum(o => o.Total);   
G>...
G>


G>Ну вот как-то так.


Если GetSomeOrders возвращает запрос, то они просто сокомбинируются и в результате получится единый запрос который будет оптимизирован SQL-сервером.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[41]: Фреймфорк для разработки Веб и десктоп-приложений на
От: VladD2 Российская Империя www.nemerle.org
Дата: 02.10.09 08:41
Оценка:
Здравствуйте, Ziaw, Вы писали:

VD>>Удобнее чем LINQ все равно создать не получится. Так что ты прост делаешь бессмысленную работу.


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

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

Допишет до коныа, отладит и будет все ОК. Кибернэйт пока что тоже полноценно LINQ не поддерживает.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[39]: Фреймфорк для разработки Веб и десктоп-приложений на
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 02.10.09 08:46
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, gandjustas, Вы писали:


G>>
G>>public class Order
G>>{
G>>    //LLCollection не IQueryable, поэтому при ленивой загрузке вытягиваются полные объекты
G>>    public LLCollection<OrderLine> OrderLines { get; }

G>>    public decimal Total
G>>    {
G>>        get
G>>        {
G>>            return OrderLines.Sum(l => l.Price * l.Quantity);
G>>        }
G>>    }
G>>}

G>>//в другом методе, в другой сборке, написанной другим человеком
G>>...
G>>var orders = dal.GetSomeOrders(...)
G>>var sum = orders.Sum(o => o.Total);   
G>>...
G>>


G>>Ну вот как-то так.


VD>Если GetSomeOrders возвращает запрос, то они просто сокомбинируются и в результате получится единый запрос который будет оптимизирован SQL-сервером.

Нет, потому что вычисление тотала не будет распознано.
Кроме того начитавшись фаулера люди пишут DAL, возвращающий коллекции объектов, а не IQueryable.

Я аналогичный код видел в одном проекте.
Re[40]: Фреймфорк для разработки Веб и десктоп-приложений на
От: VladD2 Российская Империя www.nemerle.org
Дата: 02.10.09 10:08
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Нет, потому что вычисление тотала не будет распознано.


Это почему же?
Да и на крайняк должна быть ошибка типизации.

G>Кроме того начитавшись фаулера люди пишут DAL, возвращающий коллекции объектов, а не IQueryable.


Это, да.

Откровенно говоря возможность мешать запросы к коллекциям с запросами к удаленным данным может привести к куче проблем. Казалось бы красивое решение, но опасное.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[41]: Фреймфорк для разработки Веб и десктоп-приложений на
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 02.10.09 10:15
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, gandjustas, Вы писали:


G>>Нет, потому что вычисление тотала не будет распознано.


VD>Это почему же?

Ну потому что тотал возвращает decimal. Для получения внутреностей придется IL разбирать.
Re[51]: Фреймфорк для разработки Веб и десктоп-приложений на
От: Cyberax Марс  
Дата: 02.10.09 10:42
Оценка:
Здравствуйте, gandjustas, Вы писали:

C>>Можно. Но в UDF это делается уродливо. Проходили уже, первая версия ровно так и работала — делался row-level security в Оракульной БД.

C>>Оно в итоге под своим весом всё упало.
G>Я же и говорю — кешировать надо.
А ты думаешь это так просто?

C>>На клиенте данные не фильтруются (я идиот, что ли?)

G>А где фильтруются? Ты же говорил что обработка не ложится на SQL...
G>Или я что-то не так понял.
На сервере перед выдачей клиенту, специальным кодом. На практике, отфильтровывается не так много объектов, так что даже особо не оптимизировали изначальное получение данных.

C>>О, так у нас уже всё через определённый слой идёт? И никаких массовых update'ов нет?

G>Если есть массовые апдейты, то вмето конкретного ключа можно получить предикат на выборку нужных записей.
G>Но я сейчас EF использую, у него с массовыми операциям совсем плохо.
Предикат будет работать и на клиенте?

C>>Так поздравляю, ты почти написал H/ORM! Ещё чуть-чуть, и оно будет готово.

G> Ну если пара сотен строк кода для реализации такого функционала — H/ORM, то да, я написал H/ORM
G>как раз подобным образом делал отправку сообщений аудита.
Тебе ещё из большого функционала нужна только реализация коллекций. И всё, получается классика ORM.

G>>>И зачем тогда их все тянуть на клиента?

C>>А то, что ты можешь часть фильтрации делать на клиенте. Скажем, поиск по словам в таблице.
G>По каким словам, в какой таблице?
Есть у тебя таблица типа с колонками "Имя", "Адрес", "Город", "Телефон". И рядом с ней поле ввода, и если туда ввести "Jo D 123", оно найдёт запись "John Doe, Some street, Some City, (123)-13241246". Мгновенно, точнее будет искать прямо пока ты вводишь.

Чрезвычайно удобная фича.

G>>>Ну с ACL уже разобрались — вполне ложится на SQL.

C>>Не ложится.
G>Ну покажи где?
Построение иерарихй.

G>Я так понимаю что стоит создать в базе списски эффективных ACL и эффективных ролей для пользователя (например на триггерах). Тогда можно фильтровать записи на севрере прямо в запросе, без вытягивания acl из базы.

Я же говорю — получается жуть. Меняется ACL у родителя — и нужно пересчитывать кэши всех детей. Не пропуская ничего, вдобавок.

Кроме того, сейчас у меня код — database independent. И работает под PostgreSQL, Oracle и (прости Боже!) MySQL. Как такое же на триггерах сделать?

G>>>Можем еще что-нибудь разобрать, не сомневаюсь что тоже окажется нормально ложащимся на SQL.

C>>Спорим?
G>ну давай.
Товар принадлежит одной или нескольким группам (обычный many-to-many). Нужно найти все наборы групп, и вывести для них товары.

Т.е. у нас есть "Brick" в группах "Materials" и "Tools for Killers" и "Knife" в группе "Tools for Killers". Нужно вывести:
"Materials, Tools for Killers" -> "Brick"
"Tools for Killers" -> "Brick"
"Tools for Killers" -> "Knife"

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

А ещё есть запросы со всякими running sums и delta'ами между строками...

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

G>>>Причем для последних работать эффективнее будет.

C>>Проблема с их _обновлением_.
G>Никаких проблем. last modified отлично работает.
Ты ещё скажи "SQL отлично работает". Каким образом ты будешь обновлять связные кэши?

G>>>Кроме того решение на HTTP будет неограниченно масштабироваться.

C>>А кто будет фильтровать результаты для каждого пользователя? Видимо, reverse proxy?
G>В этом случае reverse proxy не поможет. Кеш на клиенте все равно работать будет.
А как насчёт инкрементальности? Будем все 500 килобайт результатов каждого запроса перегружать пару раз в пару секунд?

В общем, ты даже и близко не понимаешь сложности задачи.
Sapienti sat!
Re[52]: Фреймфорк для разработки Веб и десктоп-приложений на
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 02.10.09 11:13
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>Здравствуйте, gandjustas, Вы писали:


C>>>Можно. Но в UDF это делается уродливо. Проходили уже, первая версия ровно так и работала — делался row-level security в Оракульной БД.

C>>>Оно в итоге под своим весом всё упало.
G>>Я же и говорю — кешировать надо.
C>А ты думаешь это так просто?
Все равно придется писать код вычисления "эффективных ACL" и прав пользователя, причем именно в БД, чтобы не тащить кучу данных из базы.
А вызывать этот алгоритм в триггере на изменения и складывать результаты в таблицу гораздо проще.


C>>>На клиенте данные не фильтруются (я идиот, что ли?)

G>>А где фильтруются? Ты же говорил что обработка не ложится на SQL...
G>>Или я что-то не так понял.
C>На сервере перед выдачей клиенту, специальным кодом. На практике, отфильтровывается не так много объектов, так что даже особо не оптимизировали изначальное получение данных.

C>>>О, так у нас уже всё через определённый слой идёт? И никаких массовых update'ов нет?

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

G>>>>И зачем тогда их все тянуть на клиента?

C>>>А то, что ты можешь часть фильтрации делать на клиенте. Скажем, поиск по словам в таблице.
G>>По каким словам, в какой таблице?
C>Есть у тебя таблица типа с колонками "Имя", "Адрес", "Город", "Телефон". И рядом с ней поле ввода, и если туда ввести "Jo D 123", оно найдёт запись "John Doe, Some street, Some City, (123)-13241246". Мгновенно, точнее будет искать прямо пока ты вводишь.
С задержкой, равной латентности сети.


G>>>>Ну с ACL уже разобрались — вполне ложится на SQL.

C>>>Не ложится.
G>>Ну покажи где?
C>Построение иерарихй.
CTE уже отменили?

G>>Я так понимаю что стоит создать в базе списски эффективных ACL и эффективных ролей для пользователя (например на триггерах). Тогда можно фильтровать записи на севрере прямо в запросе, без вытягивания acl из базы.

C>Я же говорю — получается жуть. Меняется ACL у родителя — и нужно пересчитывать кэши всех детей. Не пропуская ничего, вдобавок.
Да, именно так.
И часто меняется ACL сильно родительской записи? И какова глубина иерархий?

C>Кроме того, сейчас у меня код — database independent. И работает под PostgreSQL, Oracle и (прости Боже!) MySQL. Как такое же на триггерах сделать?

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

G>>>>Можем еще что-нибудь разобрать, не сомневаюсь что тоже окажется нормально ложащимся на SQL.

C>>>Спорим?
G>>ну давай.
C>Товар принадлежит одной или нескольким группам (обычный many-to-many). Нужно найти все наборы групп, и вывести для них товары.

C>Т.е. у нас есть "Brick" в группах "Materials" и "Tools for Killers" и "Knife" в группе "Tools for Killers". Нужно вывести:

C>"Materials, Tools for Killers" -> "Brick"
C>"Tools for Killers" -> "Brick"
C>"Tools for Killers" -> "Knife"


C>Причём название группы должно быть хитро отсортировано (скажем, по весу). Последняя попытка дала килобайтный SQL-запрос. Хотя императивно оно пишется в десяток строк кода.


EF:
var q = from p in db.Products        
        select {Product = p, Groups = p.Groups.OrderBy(g => g.Wheight)};


Вот как-то так.



C>А ещё есть запросы со всякими running sums и delta'ами между строками...

Ну это тот самый случай когда императивный код в SQL рулит.
Хотя я бы в MS SQL сложные аггрегаты делал бы с помощью CLR расширений.

C>Так что не надо считать реляционную модель концом всего. Это неплохой подход, но далеко не единственный и далеко не всегда лучший.

Как раз реляционная работа с данными — самый лучший вариант работы с данными.
Вот только некоторые простые для императивной обработки вещи в SQL потребуют correlated subquery и офигенную сложность выполнения.

G>>>>Причем для последних работать эффективнее будет.

C>>>Проблема с их _обновлением_.
G>>Никаких проблем. last modified отлично работает.
C>Ты ещё скажи "SQL отлично работает". Каким образом ты будешь обновлять связные кэши?
изменился last modified — кеш обновился.
Ты знаешь как кеширование в HTTP работает?


G>>>>Кроме того решение на HTTP будет неограниченно масштабироваться.

C>>>А кто будет фильтровать результаты для каждого пользователя? Видимо, reverse proxy?
G>>В этом случае reverse proxy не поможет. Кеш на клиенте все равно работать будет.
C>А как насчёт инкрементальности? Будем все 500 килобайт результатов каждого запроса перегружать пару раз в пару секунд?
А зачем их перезагружать? Они реально пару раз в секунду меняются?
Повысить гранулярность можно, тогда придется гораздо меньше перезагружать.

C>В общем, ты даже и близко не понимаешь сложности задачи.

Да сложность задачи я отлично понимаю.
Я вот сложности твоего решения не понимаю.
Re[53]: Фреймфорк для разработки Веб и десктоп-приложений на
От: Cyberax Марс  
Дата: 02.10.09 13:52
Оценка:
Здравствуйте, gandjustas, Вы писали:

C>>А ты думаешь это так просто?

G>Все равно придется писать код вычисления "эффективных ACL" и прав пользователя, причем именно в БД, чтобы не тащить кучу данных из базы.
А данные всё равно будут подниматься перед выдачей их клиенту. Так что однофигственно.

G>А вызывать этот алгоритм в триггере на изменения и складывать результаты в таблицу гораздо проще.

Ничуть. Особенно приятно, что количество таблиц примерно утраивается, ну и для ACLей ещё нужно имитировать "наследование", которое в БД нормальными средствами не делается.

Я уже ходил этим путём: http://www.rsdn.ru/forum/db/2396453.flat.aspx
Автор: Cyberax
Дата: 06.03.07


C>>Предикат будет работать и на клиенте?

G>ну если надо, то да.
Надо.

C>>Есть у тебя таблица типа с колонками "Имя", "Адрес", "Город", "Телефон". И рядом с ней поле ввода, и если туда ввести "Jo D 123", оно найдёт запись "John Doe, Some street, Some City, (123)-13241246". Мгновенно, точнее будет искать прямо пока ты вводишь.

G>С задержкой, равной латентности сети.
С задержкой, минимально ограниченной латентностью сети. К примеру, если пользователей порядка 2000 и у каждого из них по 3 адреса — запрос уже будет выполняться ощутимое время. А ещё учитываем время на передачу результатов. На практике оно весьма тормозно получается.

А ещё учитываем возможность использования wildcard'ов, которые замечательно убивают даже полнотекстовые индексы (которые весьма недёшевы, кстати).

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

C>>Построение иерарихй.

G>CTE уже отменили?
Ага. На MySQL'е, к примеру. Да и вообще они какие-то нереляционные и делают SQL полным по Тьюрингу.

C>>Я же говорю — получается жуть. Меняется ACL у родителя — и нужно пересчитывать кэши всех детей. Не пропуская ничего, вдобавок.

G>Да, именно так.
G>И часто меняется ACL сильно родительской записи? И какова глубина иерархий?
5-10 элементов. В паре вырожденных случаев около 50.

В общем, очень и очень хрупкое решение.

C>>Кроме того, сейчас у меня код — database independent. И работает под PostgreSQL, Oracle и (прости Боже!) MySQL. Как такое же на триггерах сделать?

G>Писать триггеры под разные базы, тем более их довольно небольшое количество.
Во-во. И ACLи тоже. И запросы. И можно ли всё это сделать на MySQL с его странным языком триггеров и SP? А как быть с транзакциями —

Спрашивается: ну и где наглядность L/ORM остаётся-то? Как обычно — только в теории?

C>>Причём название группы должно быть хитро отсортировано (скажем, по весу). Последняя попытка дала килобайтный SQL-запрос. Хотя императивно оно пишется в десяток строк кода.

G>EF:
G>
G>var q = from p in db.Products        
G>        select {Product = p, Groups = p.Groups.OrderBy(g => g.Wheight)};
G>

G>Вот как-то так.
Не-не. Это и я могу. Ты мне сделай так, чтоб оно список товаров выводило в том виде, в котором я его написал.

Оно реляционными методами эффективно не решается.

C>>А ещё есть запросы со всякими running sums и delta'ами между строками...

G>Ну это тот самый случай когда императивный код в SQL рулит.
G>Хотя я бы в MS SQL сложные аггрегаты делал бы с помощью CLR расширений.
Не знаю, может мне везёт, но у меня почему-то большинство таких отчётов.

C>>Так что не надо считать реляционную модель концом всего. Это неплохой подход, но далеко не единственный и далеко не всегда лучший.

G>Как раз реляционная работа с данными — самый лучший вариант работы с данными.

Скажи это Гуглу, создателям Couch DB и языка K.

G>Вот только некоторые простые для императивной обработки вещи в SQL потребуют correlated subquery и офигенную сложность выполнения.

Необязательно. Я могу взять нужные данные и руками по ним запустить обработку. На нормальном Turing-complete языке.

C>>Ты ещё скажи "SQL отлично работает". Каким образом ты будешь обновлять связные кэши?

G>изменился last modified — кеш обновился.
G>Ты знаешь как кеширование в HTTP работает?
"last modified" _на_ _что_?

C>>А как насчёт инкрементальности? Будем все 500 килобайт результатов каждого запроса перегружать пару раз в пару секунд?

G>А зачем их перезагружать? Они реально пару раз в секунду меняются?
G>Повысить гранулярность можно, тогда придется гораздо меньше перезагружать.
???
Повышаем гранулярность — и перегружаем всю "гранулу" при её изменении. Только объём увеличится.

C>>В общем, ты даже и близко не понимаешь сложности задачи.

G>Да сложность задачи я отлично понимаю.
G>Я вот сложности твоего решения не понимаю.
А нету сложности. Вся сложность в 50 килобайтах кода перехватчиков событий. И после этого оно всё автоматически.

Тебе зато придётся для каждого вида продумывать кэши, вычислять зависимости (руками!), и молиться чтоб оно работало.
Sapienti sat!
Re[5]: Фреймфорк для разработки Веб и десктоп-приложений на
От: yoriсk.kiev.ua  
Дата: 02.10.09 14:06
Оценка: -1
Здравствуйте, SHEMA, Вы писали:

SHE>Мы говорим про разработку интерфейса. То что в большинстве проектов ето занимает не самый большой процент времени — не обсуждается.


Повторюсь: менять дизайн — это копейки. Если только вы не юзабелист/дизайнер интерфейсов... Но тогда сидите в Blend и работайте там, он специально для этого и предназначен.

SHE>Вообщем за время проекта имеем свой зверинец и здоровый зоопарк от коллег — все умники

То ли дело зоопарк яваскриптов, который не компилится, непонятно как тестируется имеет внутри три-четыре ветки под разные броузеры.

SHE>Или не всю, а скажем только 32-значный код ентого продукта. И что мне теперь — посимвольно переписывать с экрана? Или предусматривать каждый чих юзера и навешивать свои менюшки "еще по часу на правую кнопку" c одним пунктом "Copy to clipboard"? Ты просто засеки скока раз за день средний юзер тыкает CTRL-C/CTRL-V...


Мало. Очень мало. "Средний юзер" т.е. оператор сидит и долбит в формы данные. Кто с телефона, кто с каких-то бумаг. Никаких копи-пейстов. Всякие там манагеры и прочие сейлзы глядят в свои ненаглядные таблицы с графиками. Копипейстить там тоже особо негде.
Вообще, у вас ИМХО с юзабилити какие-то напряги. Клиент не должен ничего копи-пейстить. Вы спрашиваете " Вот надо мне ету инфу просто послать клиенту по мылу." — так я спрошу: как эти данные разослать всем клинентам? Пятьдесят тысяч копи-пейстов, не иначе. А только premium account-у? Сделать выборку и перекопипейстить их мыла

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

YKU>>А как там этого достичь? Хаками js, попутно обходя грабельки особенностей разных броузеров?

SHE>Все зависит от постановки задачи. Большинство решаемо без хаков. Большой выбор JS библиотек и разных cross-броузерных AJAX-tookit-ов позволяет забыть об особенностях этих самых броузеров. Ну и по-любому, HTML поддерживается гораздо большим количеством броузеров, чем Silverlight

Вы всё скинули в кучу. Изначально мы о чём говорили? "enterprise level приложения (back-office-а и т.д.)". Поэтому вопросы кто там кого подерживает нас не так и сильно волнуют.
Виндовые ie+ff+opera(вроде начала), safari поддерживают — этого обычно достаточно, что-бы покрыть любой корпоративный стандарт. Если заказчик вдруг сидит на линуксах с их броузерами(я, правда, такого не видел) — тогда да, увы, наверное флеш наш выбор.
Немного в сторону:В большинстве случаем я вообще не понимаю на кой чёрт им этот веб сдался: операторы сидят в офисе, если надо — им компы как угодно сконфигурят. "Заходить отовсюду" всё равно будут с личного ноута, ситуация "забежал в интернет кафе побыстрому заэпрувить инвойсы" выглядит несколько фантастичной. Но это лирика.

Тоже самое про "кинуть линк". "Кинуть линк" — это действительно надо для морды магазина("Зиночка, погляди какая штучка"), для back-office это нафиг никому не сдалось(если очень cильно надо — Navigation application поможет отцу). То же самое и про "открытие в новом окне"(а запретить открывать новые окна в некоторых обстоятельствах штука весьма полезная). Скопировать страничку себе да диск/добавить в закладки — это тоже полезно на уровне конечного клиента, забредшего на сайт, но никак не.
Re[54]: Фреймфорк для разработки Веб и десктоп-приложений на
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 02.10.09 15:42
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>Здравствуйте, gandjustas, Вы писали:


C>>>А ты думаешь это так просто?

G>>Все равно придется писать код вычисления "эффективных ACL" и прав пользователя, причем именно в БД, чтобы не тащить кучу данных из базы.
C>А данные всё равно будут подниматься перед выдачей их клиенту. Так что однофигственно.
Да ну? Клиенту для отображени ясовсем немного данных надо.

G>>А вызывать этот алгоритм в триггере на изменения и складывать результаты в таблицу гораздо проще.

C>Ничуть. Особенно приятно, что количество таблиц примерно утраивается, ну и для ACLей ещё нужно имитировать "наследование", которое в БД нормальными средствами не делается.
Я говорю про таблицу для эффективных acl. Это будет 2-3 таблицы на всю базу.

C>Я уже ходил этим путём: http://www.rsdn.ru/forum/db/2396453.flat.aspx
Автор: Cyberax
Дата: 06.03.07

Это совсем не тот путь.

C>>>Есть у тебя таблица типа с колонками "Имя", "Адрес", "Город", "Телефон". И рядом с ней поле ввода, и если туда ввести "Jo D 123", оно найдёт запись "John Doe, Some street, Some City, (123)-13241246". Мгновенно, точнее будет искать прямо пока ты вводишь.

G>>С задержкой, равной латентности сети.
C>С задержкой, минимально ограниченной латентностью сети. К примеру, если пользователей порядка 2000 и у каждого из них по 3 адреса — запрос уже будет выполняться ощутимое время. А ещё учитываем время на передачу результатов. На практике оно весьма тормозно получается.
Я че-то туплю. Данные уже есть на клиенте (в этой самой таблице), так что все будет моментально работать, не переживай.

C>>>Я же говорю — получается жуть. Меняется ACL у родителя — и нужно пересчитывать кэши всех детей. Не пропуская ничего, вдобавок.

G>>Да, именно так.
G>>И часто меняется ACL сильно родительской записи? И какова глубина иерархий?
C>5-10 элементов. В паре вырожденных случаев около 50.
Ну это совсем немного.

C>В общем, очень и очень хрупкое решение.

Это потому что ты не умеешь его готовить.

C>>>Кроме того, сейчас у меня код — database independent. И работает под PostgreSQL, Oracle и (прости Боже!) MySQL. Как такое же на триггерах сделать?

G>>Писать триггеры под разные базы, тем более их довольно небольшое количество.
C>Во-во. И ACLи тоже. И запросы. И можно ли всё это сделать на MySQL с его странным языком триггеров и SP? А как быть с транзакциями —
Ну не пиши по MySQL, одной беслатной БД в арсенале вполне достаточно.
Если программа работает с любой БД, то или она очень простая, или не использует возможностей БД и греет воздух.

C>Спрашивается: ну и где наглядность L/ORM остаётся-то? Как обычно — только в теории?

Наглядности станет больше — станет меньше императивного кода.

C>>>Причём название группы должно быть хитро отсортировано (скажем, по весу). Последняя попытка дала килобайтный SQL-запрос. Хотя императивно оно пишется в десяток строк кода.

G>>EF:
G>>
G>>var q = from p in db.Products        
G>>        select {Product = p, Groups = p.Groups.OrderBy(g => g.Wheight)};
G>>

G>>Вот как-то так.
C>Не-не. Это и я могу. Ты мне сделай так, чтоб оно список товаров выводило в том виде, в котором я его написал.
Большая разница чтоли?
var q = from p in db.Products        
        select {Product = p.Name, Groups = p.Groups.OrderBy(g => g.Wheight).Select(g => g.Name)};

А потом склеиваешь строки.

C>Оно реляционными методами эффективно не решается.

Что именно?
Как видишь запрос выше вполне решает. Или ты хочешь и строки склеивать в БД?

C>>>А ещё есть запросы со всякими running sums и delta'ами между строками...

G>>Ну это тот самый случай когда императивный код в SQL рулит.
G>>Хотя я бы в MS SQL сложные аггрегаты делал бы с помощью CLR расширений.
C>Не знаю, может мне везёт, но у меня почему-то большинство таких отчётов.
Тебе везет или ты что-то не так делаешь.
Ингда выгоднее хранить дельты и использовать indexed\materialized view.

C>>>Так что не надо считать реляционную модель концом всего. Это неплохой подход, но далеко не единственный и далеко не всегда лучший.

G>>Как раз реляционная работа с данными — самый лучший вариант работы с данными.
C>
C>Скажи это Гуглу, создателям Couch DB и языка K.
Couch DB — из другой оперы, там данные частично-структурированные.

G>>Вот только некоторые простые для императивной обработки вещи в SQL потребуют correlated subquery и офигенную сложность выполнения.

C>Необязательно. Я могу взять нужные данные и руками по ним запустить обработку. На нормальном Turing-complete языке.
Ну собственно тебе никто не мешает это сделать. Ты можешь посчитать аггрегаты один раз и хранить их.

C>>>Ты ещё скажи "SQL отлично работает". Каким образом ты будешь обновлять связные кэши?

G>>изменился last modified — кеш обновился.
G>>Ты знаешь как кеширование в HTTP работает?
C>"last modified" _на_ _что_?
На запрос.

C>>>А как насчёт инкрементальности? Будем все 500 килобайт результатов каждого запроса перегружать пару раз в пару секунд?

G>>А зачем их перезагружать? Они реально пару раз в секунду меняются?
G>>Повысить гранулярность можно, тогда придется гораздо меньше перезагружать.
C>???
C>Повышаем гранулярность — и перегружаем всю "гранулу" при её изменении. Только объём увеличится.
Не тупи. Высокая гранулярность — более "мелкие" гранулы.
Re[55]: Фреймфорк для разработки Веб и десктоп-приложений на
От: Cyberax Марс  
Дата: 02.10.09 16:09
Оценка:
Здравствуйте, gandjustas, Вы писали:

C>>А данные всё равно будут подниматься перед выдачей их клиенту. Так что однофигственно.

G>Да ну? Клиенту для отображени ясовсем немного данных надо.
Опять же говорю — не немного.

C>>Ничуть. Особенно приятно, что количество таблиц примерно утраивается, ну и для ACLей ещё нужно имитировать "наследование", которое в БД нормальными средствами не делается.

G>Я говорю про таблицу для эффективных acl. Это будет 2-3 таблицы на всю базу.
Как на них констрейнты повесить?

C>>Я уже ходил этим путём: http://www.rsdn.ru/forum/db/2396453.flat.aspx
Автор: Cyberax
Дата: 06.03.07

G> Это совсем не тот путь.
Именно тот. По-другому не получается.

C>>С задержкой, минимально ограниченной латентностью сети. К примеру, если пользователей порядка 2000 и у каждого из них по 3 адреса — запрос уже будет выполняться ощутимое время. А ещё учитываем время на передачу результатов. На практике оно весьма тормозно получается.

G>Я че-то туплю. Данные уже есть на клиенте (в этой самой таблице), так что все будет моментально работать, не переживай.
В таблице могут быть не совсем все данные.

G>>>И часто меняется ACL сильно родительской записи? И какова глубина иерархий?

C>>5-10 элементов. В паре вырожденных случаев около 50.
G>Ну это совсем немного.
Более чем.

C>>В общем, очень и очень хрупкое решение.

G>Это потому что ты не умеешь его готовить.
Умею. Оно уже было так сделано. Передалал.

C>>Во-во. И ACLи тоже. И запросы. И можно ли всё это сделать на MySQL с его странным языком триггеров и SP? А как быть с транзакциями —

G>Ну не пиши по MySQL, одной беслатной БД в арсенале вполне достаточно.
G>Если программа работает с любой БД, то или она очень простая, или не использует возможностей БД и греет воздух.
Это просто с твоим архаичным подходом с кашей непонятно каких триггеров, UDF, кэширующих таблиц, странных кэшей, непонятных батчей так не получается. А с современными ORM — всё просто и без проблем делается.

C>>Спрашивается: ну и где наглядность L/ORM остаётся-то? Как обычно — только в теории?

G>Наглядности станет больше — станет меньше императивного кода.
Ага. Триггеры — это у нас уже не императивный подход?

C>>Не-не. Это и я могу. Ты мне сделай так, чтоб оно список товаров выводило в том виде, в котором я его написал.

G>Большая разница чтоли?
G>
G>var q = from p in db.Products        
G>        select {Product = p.Name, Groups = p.Groups.OrderBy(g => g.Wheight).Select(g => g.Name)};
G>

G>А потом склеиваешь строки.
Опять неверно. Нужно найти все _комбинации_ групп.

Вот ровно та же проблема: http://www.rsdn.ru/forum/db/2682769.flat.aspx
Автор: Flying Dutchman
Дата: 05.10.07


C>>Не знаю, может мне везёт, но у меня почему-то большинство таких отчётов.

G>Тебе везет или ты что-то не так делаешь.
G>Ингда выгоднее хранить дельты и использовать indexed\materialized view.
А мне не надо делать никаких видов под отдельные запросы, ничего. В БД хранятся ТОЛЬКО данные и НИКАКОЙ логики.

Single Responsibility Principle, однако.

C>>Скажи это Гуглу, создателям Couch DB и языка K.

G>Couch DB — из другой оперы, там данные частично-структурированные.
И что?

G>>>Вот только некоторые простые для императивной обработки вещи в SQL потребуют correlated subquery и офигенную сложность выполнения.

C>>Необязательно. Я могу взять нужные данные и руками по ним запустить обработку. На нормальном Turing-complete языке.
G>Ну собственно тебе никто не мешает это сделать. Ты можешь посчитать аггрегаты один раз и хранить их.
И обновлять их ВСЕ при каждом изменении. Даже если часть аггрегатов нужна раз в пятилетку.

G>>>Ты знаешь как кеширование в HTTP работает?

C>>"last modified" _на_ _что_?
G>На запрос.
На какой?

Ты видел поле с расписанием на скриншоте? Так вот, он зависит что-то около от 200 таблиц. Другой вид данных зависит от примерно такого же числа таблиц, но чуть-чуть других.

ЧТО мы будем слушать-то?

C>>Повышаем гранулярность — и перегружаем всю "гранулу" при её изменении. Только объём увеличится.

G>Не тупи. Высокая гранулярность — более "мелкие" гранулы.
А, ну ладно. Тогда проблемы с зависимостями. Скажем, пользователя надо показывать "недоступным", если он в это время запланировал meeting. Планирование meeting'ов и показ расписания — в очень разных частях БД.

Так что если мы слушаем только
Sapienti sat!
Re[6]: Фреймфорк для разработки Веб и десктоп-приложений на
От: SHEMA  
Дата: 03.10.09 05:41
Оценка:
Здравствуйте, yoriсk.kiev.ua, Вы писали:

YKU>Повторюсь: менять дизайн — это копейки. Если только вы не юзабелист/дизайнер интерфейсов... Но тогда сидите в Blend и работайте там, он специально для этого и предназначен.

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

YKU>То ли дело зоопарк яваскриптов, который не компилится, непонятно как тестируется имеет внутри три-четыре ветки под разные броузеры.

Все уже сделано за вас — prototype/jquery/extjs/другая по вкусу библиотека вам в руки.

YKU>Вообще, у вас ИМХО с юзабилити какие-то напряги. Клиент не должен ничего копи-пейстить.

Смотря какой клиент, смотря с какой информацией работает. Нет никаких напрягов — просто упомянул одним из достоинств HTMLя то, что с ним нештатно доступны дополнительные функции, к которым пользователь привык и уже воспринимает как должное. Попробуйте выделить фрагмент в броузере и кликнуть правой кнопкой мыши — вот вам печать, перевод, сохранить, избранное, поиск, експорт + всякие там акселераторы (IE8) на выбор и т.д.
С SL большинство функций и приятных фенечек броузера становится недоступной (совсем не значит что невостребованной!).
Вам все ето не надо? Все ето можно сделать на SL? сомневаюсь, но флаг вам в руки

YKU>Вы всё скинули в кучу.

Зато у вас никакой кучи и нет. Да, с SL вы пишите только на одном языке и ето большой плюс, но етим вы и ограничены. Песочница Silverlight-а еще по-детски мала (поздравляю, в последней версии появился диалог SaveAs, ради интереса пробегитесь по форумам посмотрите какие воркароунды до етого предлагались...). Если вы чуствуете себя в ней комфортно — прекрасно, рад за вас и ваших пользователей. Я же пока воспользуюсь той функциональностью и богаством выбора, который предоставляет современный web, НЕ ИСКЛЮЧАЯ возможности реализации каких-то элементов на SL. И ето намного выгоднее позиция и для продукта и для его пользователей, чем постоянно спотыкаться, локти кусать и жить в ожидании — ну когдааааа же Microsoft ето сделает и то доделает...
Re[56]: Фреймфорк для разработки Веб и десктоп-приложений на
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 03.10.09 17:50
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>Здравствуйте, gandjustas, Вы писали:


C>>>А данные всё равно будут подниматься перед выдачей их клиенту. Так что однофигственно.

G>>Да ну? Клиенту для отображени ясовсем немного данных надо.
C>Опять же говорю — не немного.
То что ты показал на скриншоте требует не более 1 мб. А при умном подходе и того меньше.

C>>>Я уже ходил этим путём: http://www.rsdn.ru/forum/db/2396453.flat.aspx
Автор: Cyberax
Дата: 06.03.07

G>> Это совсем не тот путь.
C>Именно тот. По-другому не получается.
Соболезную. Но все равно не тот путь.

C>>>С задержкой, минимально ограниченной латентностью сети. К примеру, если пользователей порядка 2000 и у каждого из них по 3 адреса — запрос уже будет выполняться ощутимое время. А ещё учитываем время на передачу результатов. На практике оно весьма тормозно получается.

G>>Я че-то туплю. Данные уже есть на клиенте (в этой самой таблице), так что все будет моментально работать, не переживай.
C>В таблице могут быть не совсем все данные.
А зачем искать по данным, которые визуально не отображаются?

C>>>В общем, очень и очень хрупкое решение.

G>>Это потому что ты не умеешь его готовить.
C>Умею. Оно уже было так сделано. Передалал.
Если получилось очень хрупкое решение — значит не умеешь.
Весь веб так работает. Посмотри на сервисы гугла.

C>>>Во-во. И ACLи тоже. И запросы. И можно ли всё это сделать на MySQL с его странным языком триггеров и SP? А как быть с транзакциями —

G>>Ну не пиши по MySQL, одной беслатной БД в арсенале вполне достаточно.
G>>Если программа работает с любой БД, то или она очень простая, или не использует возможностей БД и греет воздух.
C>Это просто с твоим архаичным подходом с кашей непонятно каких триггеров, UDF, кэширующих таблиц, странных кэшей, непонятных батчей так не получается. А с современными ORM — всё просто и без проблем делается.
Не надо придавать эмоциональную окраску техническим вопросом. Подучись немного и триггеры, UDF и кеширующие таблицы станут для тебя вполне нормальными.
А в современными ORM все что удвлось тебе сделать — приложение, которому для старта требуется 30 метров выкачать.
При таком раскладе легче remote desktop использовать.

C>>>Спрашивается: ну и где наглядность L/ORM остаётся-то? Как обычно — только в теории?

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

G>>>>Вот только некоторые простые для императивной обработки вещи в SQL потребуют correlated subquery и офигенную сложность выполнения.

C>>>Необязательно. Я могу взять нужные данные и руками по ним запустить обработку. На нормальном Turing-complete языке.
G>>Ну собственно тебе никто не мешает это сделать. Ты можешь посчитать аггрегаты один раз и хранить их.
C>И обновлять их ВСЕ при каждом изменении. Даже если часть аггрегатов нужна раз в пятилетку.
А с чего ты взял что все обновлять надо? Ты же знаешь конкретные изменения, вот и обновляй зименившиеся аггрегаты.
И это все равно будет дешевле, чем пересчитывть аггрегаты при запросах.

G>>>>Ты знаешь как кеширование в HTTP работает?

C>>>"last modified" _на_ _что_?
G>>На запрос.
C>На какой?
На любой.

C>Ты видел поле с расписанием на скриншоте? Так вот, он зависит что-то около от 200 таблиц. Другой вид данных зависит от примерно такого же числа таблиц, но чуть-чуть других.

Да хоть от 1000.

C>ЧТО мы будем слушать-то?

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

C>>>Повышаем гранулярность — и перегружаем всю "гранулу" при её изменении. Только объём увеличится.

G>>Не тупи. Высокая гранулярность — более "мелкие" гранулы.
C>А, ну ладно. Тогда проблемы с зависимостями. Скажем, пользователя надо показывать "недоступным", если он в это время запланировал meeting. Планирование meeting'ов и показ расписания — в очень разных частях БД.
См выше.
Re[57]: Фреймфорк для разработки Веб и десктоп-приложений на
От: Cyberax Марс  
Дата: 03.10.09 19:14
Оценка:
Здравствуйте, gandjustas, Вы писали:

C>>Опять же говорю — не немного.

G>То что ты показал на скриншоте требует не более 1 мб. А при умном подходе и того меньше.
Угу. А потом roundtrip на каждый щелчок.

G>>>Я че-то туплю. Данные уже есть на клиенте (в этой самой таблице), так что все будет моментально работать, не переживай.

C>>В таблице могут быть не совсем все данные.
G>А зачем искать по данным, которые визуально не отображаются?
Чтобы отобразить их.

C>>Умею. Оно уже было так сделано. Передалал.

G>Если получилось очень хрупкое решение — значит не умеешь.
G>Весь веб так работает. Посмотри на сервисы гугла.
У Гугла очень простые сервисы, которые обслуживает кластер из сотен тысяч машин.

Вдобавок, часть приложений у них таки по моей схеме работает. К примеру, GMail c Google Gears (который в offline работает, да). Или их электронная таблица — они там отправляют на сервер только лог измений, а почти все расчёты идут на клиенте (вот ведь, никто не сказал кретинам оттуда, что проще каждый click на сервер отправлять!).

Так что мимо.

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

G>Не надо придавать эмоциональную окраску техническим вопросом. Подучись немного и триггеры, UDF и кеширующие таблицы станут для тебя вполне нормальными.
Не, до такого состояния разума я не дойду. Я видел в кого превращаются профессиональные DBA, спасибо.

G>А в современными ORM все что удвлось тебе сделать — приложение, которому для старта требуется 30 метров выкачать.

Не 30 Мб, я же уже сказал это. Меньше 5Мб — около 30 секунд на медленном соединении.

А после начальной загрузки можно и с модема работать, кстати. Без всяких проблем ВООБЩЕ. Реально спасло пару раз, когда из каналов связи был только тормозной и дорогой GPRS.

G>При таком раскладе легче remote desktop использовать.

Не проще.

G>>>Наглядности станет больше — станет меньше императивного кода.

C>>Ага. Триггеры — это у нас уже не императивный подход?
G>Нет, с чего бы?
Да, с того бы.

G>Триггеры это просто функции, которые будут вызываться неявно. Внутри уже пишешь как захочешь.

Угу, именно. Это процедуры, которые запускаются при модификации данных. В них ничерта нет от реляционности — это просто вариант AOP.

C>>И обновлять их ВСЕ при каждом изменении. Даже если часть аггрегатов нужна раз в пятилетку.

G>А с чего ты взял что все обновлять надо? Ты же знаешь конкретные изменения, вот и обновляй зименившиеся аггрегаты.
Нет, я не знаю конкретные изменения.

G>И это все равно будет дешевле, чем пересчитывть аггрегаты при запросах.

Не будет.

G>>>>>Ты знаешь как кеширование в HTTP работает?

C>>>>"last modified" _на_ _что_?
G>>>На запрос.
C>>На какой?
G>На любой.
В том числе, и на запрос "выбери мне первое число, которое не представимо в виде суммы двух простых чисел"?

C>>Ты видел поле с расписанием на скриншоте? Так вот, он зависит что-то около от 200 таблиц. Другой вид данных зависит от примерно такого же числа таблиц, но чуть-чуть других.

G>Да хоть от 1000.
Ну да. Чего мелочиться, пусть хоть миллион будет!

C>>ЧТО мы будем слушать-то?

G>Ты же заешь какие действия толькователя повлияют на таблицу, вот и пусть эти действия вызывают обновления last modified для таблицы.
НЕТ, я НЕ ЗНАЮ какие действия толькователя повлияют на таблицу.

Более того, МНЕ ЭТО НЕ НУЖНО знать. А вот тебе придётся руками отслеживать ВСЕ неявные связи, иначе появятся возможности получения неконсистентной информации?

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

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

G>Незачем на клиента тащить всю схему данных.

Почему?
Sapienti sat!
Re[58]: Фреймфорк для разработки Веб и десктоп-приложений на
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 03.10.09 20:38
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>Здравствуйте, gandjustas, Вы писали:


C>>>Опять же говорю — не немного.

G>>То что ты показал на скриншоте требует не более 1 мб. А при умном подходе и того меньше.
C>Угу. А потом roundtrip на каждый щелчок.
Это не так страшно, тем более при кешировании результатов.

C>>>Умею. Оно уже было так сделано. Передалал.

G>>Если получилось очень хрупкое решение — значит не умеешь.
G>>Весь веб так работает. Посмотри на сервисы гугла.
C>У Гугла очень простые сервисы, которые обслуживает кластер из сотен тысяч машин.
Заметил такую тенденцию на формуме — неудачные технические решения оправдываются сложностью задачи и наоборот удачные решения объявляют чуть ли не тривиальными вещами.
Даю руку на отсечение что любой из гугловых сервисов сложнее того что пишешь ты.

C>Вдобавок, часть приложений у них таки по моей схеме работает. К примеру, GMail c Google Gears (который в offline работает, да). Или их электронная таблица — они там отправляют на сервер только лог измений, а почти все расчёты идут на клиенте (вот ведь, никто не сказал кретинам оттуда, что проще каждый click на сервер отправлять!).

рассчеты на клиенте абсолютно ортогональны тому что тут обсуждается.


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

G>>Не надо придавать эмоциональную окраску техническим вопросом. Подучись немного и триггеры, UDF и кеширующие таблицы станут для тебя вполне нормальными.
C>Не, до такого состояния разума я не дойду. Я видел в кого превращаются профессиональные DBA, спасибо.
Меньше эмоций, разум чище будет.

G>>А в современными ORM все что удвлось тебе сделать — приложение, которому для старта требуется 30 метров выкачать.

C>Не 30 Мб, я же уже сказал это. Меньше 5Мб — около 30 секунд на медленном соединении.
Ого, хорошее у тебя медленное соединение. У меня ADSL в лучшие времена не так быстро работал.

G>>>>Наглядности станет больше — станет меньше императивного кода.

C>>>Ага. Триггеры — это у нас уже не императивный подход?
G>>Нет, с чего бы?
C>Да, с того бы.
Ну так обоснуй.

G>>Триггеры это просто функции, которые будут вызываться неявно. Внутри уже пишешь как захочешь.

C>Угу, именно. Это процедуры, которые запускаются при модификации данных. В них ничерта нет от реляционности — это просто вариант AOP.
А чем aop противоречит реляцонности?
Это вообще разные категории.

C>>>И обновлять их ВСЕ при каждом изменении. Даже если часть аггрегатов нужна раз в пятилетку.

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

G>>И это все равно будет дешевле, чем пересчитывть аггрегаты при запросах.

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

G>>>>>>Ты знаешь как кеширование в HTTP работает?

C>>>>>"last modified" _на_ _что_?
G>>>>На запрос.
C>>>На какой?
G>>На любой.
C>В том числе, и на запрос "выбери мне первое число, которое не представимо в виде суммы двух простых чисел"?
Конечно, а чем он хуже других?
Только имеет ли смысл вообще запрашивать что-либо в таком случае?

C>>>ЧТО мы будем слушать-то?

G>>Ты же заешь какие действия толькователя повлияют на таблицу, вот и пусть эти действия вызывают обновления last modified для таблицы.
C>НЕТ, я НЕ ЗНАЮ какие действия толькователя повлияют на таблицу.
Это я уже понял.

C>Более того, МНЕ ЭТО НЕ НУЖНО знать. А вот тебе придётся руками отслеживать ВСЕ неявные связи, иначе появятся возможности получения неконсистентной информации?

Я не создаю неявных связей, у меня все связи явные.

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

И с чего они висеть там останутся?

C>Стоит ли говорить, что у меня ещё и ВСЁ транзакционно-безопасно и гарантирован строгий порядок доставки событий?

И что тебе с этого? Длинее и толще?

G>>Незачем на клиента тащить всю схему данных.

C>Почему?
Потому что это лишний расход трафика и бесполезное нагревание воздуха серверной.
Re[59]: Фреймфорк для разработки Веб и десктоп-приложений на
От: Cyberax Марс  
Дата: 04.10.09 16:39
Оценка:
Здравствуйте, gandjustas, Вы писали:

C>>Угу. А потом roundtrip на каждый щелчок.

G>Это не так страшно, тем более при кешировании результатов.
1) Что кэшировать-то? Вот я нажал на ячейку — и мне надо показать подробные детали для неё. Шансы что я нажму на неё второй раз — не особо велики.
2) Как инвалидировать будем-с?

C>>У Гугла очень простые сервисы, которые обслуживает кластер из сотен тысяч машин.

G>Заметил такую тенденцию на формуме — неудачные технические решения оправдываются сложностью задачи и наоборот удачные решения объявляют чуть ли не тривиальными вещами.
G>Даю руку на отсечение что любой из гугловых сервисов сложнее того что пишешь ты.
Давай.

C>>Вдобавок, часть приложений у них таки по моей схеме работает. К примеру, GMail c Google Gears (который в offline работает, да). Или их электронная таблица — они там отправляют на сервер только лог измений, а почти все расчёты идут на клиенте (вот ведь, никто не сказал кретинам оттуда, что проще каждый click на сервер отправлять!).

G>рассчеты на клиенте абсолютно ортогональны тому что тут обсуждается.
Ничуть. Вообще, GMail работает ровно так же, как и мой код. С той лишь разницей, что они вместо H/ORM используют какое-то своё кластерное хранилище.

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

C>>Не 30 Мб, я же уже сказал это. Меньше 5Мб — около 30 секунд на медленном соединении.

G>Ого, хорошее у тебя медленное соединение. У меня ADSL в лучшие времена не так быстро работал.
Это где-то скорость 1.5Мбит. Действительно, не совсем медленное.

G>>>Триггеры это просто функции, которые будут вызываться неявно. Внутри уже пишешь как захочешь.

C>>Угу, именно. Это процедуры, которые запускаются при модификации данных. В них ничерта нет от реляционности — это просто вариант AOP.
G>А чем aop противоречит реляцонности?
Вообще-то, да. Он к ней неприменим. Реляционная алгебра — это просто алгебра работы с множествами, которая позволяет делать гибкие структурированные хранилища.

Хранимые процедуры, триггеры, CTE — уже не имеют никакого отношения к реляционной алгебре. Соответственно, глупо утверждать что программа с большим числом хранимок и триггеров более "реляционна", чем программа с H/ORM.

Пропоненты L/ORM именно так пока и делают.

G>>>А с чего ты взял что все обновлять надо? Ты же знаешь конкретные изменения, вот и обновляй зименившиеся аггрегаты.

C>>Нет, я не знаю конкретные изменения.
G>Такого не бывает. Ты же программу пишешь и обрабатываешь конкретные действия пользователей, которые соответствуют конкретным сценариям работы системы, которые приводят к конкретным изменениям данных.
Ещё как бывает со сложными моделями. У меня сейчас более тысячи разных операций. Для каждой операции в твоём подходе необходимо знать как она повлияет на всё остальное.

Может ты не работал с большими и сложными моделями?

G>Будет. Кроме того с точки зрения пользователя повысится производительность.

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

C>>>>На какой?

G>>>На любой.
C>>В том числе, и на запрос "выбери мне первое число, которое не представимо в виде суммы двух простых чисел"?
G>Конечно, а чем он хуже других?
Нууу...

G>Только имеет ли смысл вообще запрашивать что-либо в таком случае?

А вот надо. Как делать будем?

C>>Более того, МНЕ ЭТО НЕ НУЖНО знать. А вот тебе придётся руками отслеживать ВСЕ неявные связи, иначе появятся возможности получения неконсистентной информации?

G>Я не создаю неявных связей, у меня все связи явные.
Я говорю не про FK. Я уже привёл пример, когда изменение одного кусочка данных повляет на другой, не связанный напрямую с ним.

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

G>И с чего они висеть там останутся?
А не прошёл HTTP-запрос. Пакетик потерялся, и он ждёт retransmit'а. Или файрвол решил задержать ответ до проверки нет ли в нём вирусов.

Оба случая вполне реальные.

C>>Стоит ли говорить, что у меня ещё и ВСЁ транзакционно-безопасно и гарантирован строгий порядок доставки событий?

G> И что тебе с этого? Длинее и толще?
Угу.

G>>>Незачем на клиента тащить всю схему данных.

C>>Почему?
G>Потому что это лишний расход трафика и бесполезное нагревание воздуха серверной.
Нет. Лишний расход траффика — у тебя. У меня сейчас дневной расход на приложение — около 10Мб. 5Мб на начальную загрузку (надо бы её оптимизировать...), а дальше считанные байты на трансляцию изменений.

Т.е. оно реально может использоваться на модеме.

Для твоей модели оно недостижимо.
Sapienti sat!
Re[60]: Фреймфорк для разработки Веб и десктоп-приложений на
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 05.10.09 05:04
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>Здравствуйте, gandjustas, Вы писали:


C>>>Угу. А потом roundtrip на каждый щелчок.

G>>Это не так страшно, тем более при кешировании результатов.
C>1) Что кэшировать-то? Вот я нажал на ячейку — и мне надо показать подробные детали для неё. Шансы что я нажму на неё второй раз — не особо велики.
Вот подробные детали и кешируй. Даже если второй раз запрошено никогда не будет это не даст заметного оверхеда. Причем кеш ответов не вносит оверхед в отличе от кеширования данных.

C>2) Как инвалидировать будем-с?

last modified

C>>>Вдобавок, часть приложений у них таки по моей схеме работает. К примеру, GMail c Google Gears (который в offline работает, да). Или их электронная таблица — они там отправляют на сервер только лог измений, а почти все расчёты идут на клиенте (вот ведь, никто не сказал кретинам оттуда, что проще каждый click на сервер отправлять!).

G>>рассчеты на клиенте абсолютно ортогональны тому что тут обсуждается.
C>Ничуть. Вообще, GMail работает ровно так же, как и мой код. С той лишь разницей, что они вместо H/ORM используют какое-то своё кластерное хранилище.
С чего ты взял? Исходники видел?

C>Там ровно так же на клиенте хранится кэш данных, с которым работает JavaScript-код. GMail ровно так же как и я вместо прямых запросов "дай данные для этой ячейки" использует подход "загрузить и положить в кэш данные", которые уже и отобржаются.

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

C>>>Не 30 Мб, я же уже сказал это. Меньше 5Мб — около 30 секунд на медленном соединении.

G>>Ого, хорошее у тебя медленное соединение. У меня ADSL в лучшие времена не так быстро работал.
C>Это где-то скорость 1.5Мбит. Действительно, не совсем медленное.
Интересно, откуда латентность в 200 мс на таких каналах?


C>Хранимые процедуры, триггеры, CTE — уже не имеют никакого отношения к реляционной алгебре. Соответственно, глупо утверждать что программа с большим числом хранимок и триггеров более "реляционна", чем программа с H/ORM.

Как раз можно, томому что теже триггеры и CTE работают именно с реляционными данными, тогда как H/ORM хочет сделать вид что работа идет с объектами.


G>>>>А с чего ты взял что все обновлять надо? Ты же знаешь конкретные изменения, вот и обновляй зименившиеся аггрегаты.

C>>>Нет, я не знаю конкретные изменения.
G>>Такого не бывает. Ты же программу пишешь и обрабатываешь конкретные действия пользователей, которые соответствуют конкретным сценариям работы системы, которые приводят к конкретным изменениям данных.
C>Ещё как бывает со сложными моделями. У меня сейчас более тысячи разных операций. Для каждой операции в твоём подходе необходимо знать как она повлияет на всё остальное.
Не знаю как тебе, а мне не удавалось писать программы в которых я не знаю что происходит.
И для каждого сценария я могу сказать к каким изменениям он приводит.

C>Может ты не работал с большими и сложными моделями?

Работал

G>>Будет. Кроме того с точки зрения пользователя повысится производительность.

G>>Пользователь желая увидеть данные готов ждать гораздо меньше, чем при желании данные изменить.
G>>Например заходя на сайт хочется видеть страницу сразу, а постя сообщение на форум подождать пару секунд — впнолне терпимо.
C>Ты не учитываешь, что некоторые изменения должны делаються очень быстро. Если координатор, который должен распределить пару тысяч смен, должен по 10 секунд ждать на каждую операцию — он придёт к тебе домой и тебя застрелит.
Ну да, выдумывание небылиц — хороший способ обоснования свой позиции, с чего ты взял 10 секунд?
Даже если взять того же оператора и представить что пересчет аггрегатов в запросе выполняется в 100 раз быстрее 0.1 секунду, то на отображение 10000 записей ему придется ждать около 20 минут. И это прижедтся испытать каждому пользователю, который попытается просмотреть расписание.


G>>Только имеет ли смысл вообще запрашивать что-либо в таком случае?

C>А вот надо. Как делать будем?


C>>>Более того, МНЕ ЭТО НЕ НУЖНО знать. А вот тебе придётся руками отслеживать ВСЕ неявные связи, иначе появятся возможности получения неконсистентной информации?

G>>Я не создаю неявных связей, у меня все связи явные.
C>Я говорю не про FK. Я уже привёл пример, когда изменение одного кусочка данных повляет на другой, не связанный напрямую с ним.
И что? Ты создавая программу не знаешь какие действия на какие данные повлияют?

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

G>>И с чего они висеть там останутся?
C>А не прошёл HTTP-запрос. Пакетик потерялся, и он ждёт retransmit'а. Или файрвол решил задержать ответ до проверки нет ли в нём вирусов.
Этона каталах, которые по 1,5 мбит выдают? Сам в это веришь?

C>Оба случая вполне реальные.

Ну встретить динозавра тоже вполне реально, даже с вероятностью отличной от нуля.


G>>>>Незачем на клиента тащить всю схему данных.

C>>>Почему?
G>>Потому что это лишний расход трафика и бесполезное нагревание воздуха серверной.
C>Нет. Лишний расход траффика — у тебя. У меня сейчас дневной расход на приложение — около 10Мб. 5Мб на начальную загрузку (надо бы её оптимизировать...), а дальше считанные байты на трансляцию изменений.

А в моем подходе не будет начальной загрузки и теже 5 метров будут растянуты по времени. И потом тоже будут "считанные байты" на изменения.

C>Т.е. оно реально может использоваться на модеме.


Я плакал

C>Для твоей модели оно недостижимо.

Ну я как раз через GPRS часто в интернете сижу. Если бы мне кто-нибудь предложил скачать 5 метров просто чтобы начать пользоваться программой, то я бы сразу послал такой сервис.

Короче хватит практиковаться в выдумывании небылиц. Адекватного описания преимуществ твоего подхода не видно, а все что есть вполне делается и без h\orm.
Re[61]: Фреймфорк для разработки Веб и десктоп-приложений на
От: Cyberax Марс  
Дата: 05.10.09 13:19
Оценка:
Здравствуйте, gandjustas, Вы писали:

C>>1) Что кэшировать-то? Вот я нажал на ячейку — и мне надо показать подробные детали для неё. Шансы что я нажму на неё второй раз — не особо велики.

G>Вот подробные детали и кешируй. Даже если второй раз запрошено никогда не будет это не даст заметного оверхеда. Причем кеш ответов не вносит оверхед в отличе от кеширования данных.
Торможение в первый раз — уже неприемлимо.

C>>2) Как инвалидировать будем-с?

G>last modified
Это требует _каждый_ _раз_ делать запрос на сервер при нажатии на ячейку. Пофиг что оно вернёт "304 Not Modified" — всё равно нужен отдельный запрос.

C>>Ничуть. Вообще, GMail работает ровно так же, как и мой код. С той лишь разницей, что они вместо H/ORM используют какое-то своё кластерное хранилище.

G>С чего ты взял? Исходники видел?
Нет. Презентации о его архитектуре.

C>>Там ровно так же на клиенте хранится кэш данных, с которым работает JavaScript-код. GMail ровно так же как и я вместо прямых запросов "дай данные для этой ячейки" использует подход "загрузить и положить в кэш данные", которые уже и отобржаются.

G>Это всегда так будет. Отличие в том, что GMail получает данные необходимые для отображения, а ты тянешь на клиента модель из базы.
Мимо. GMail точно так же загружает сразу больше данных, чем видно. Просто с EMail'ом всё просто.

А вот их приложение с электронной таблицей вообще почти всё на клиенте работает.

G>>>Ого, хорошее у тебя медленное соединение. У меня ADSL в лучшие времена не так быстро работал.

C>>Это где-то скорость 1.5Мбит. Действительно, не совсем медленное.
G>Интересно, откуда латентность в 200 мс на таких каналах?
Из-за конечной скорости света, глюкодромных ADSL и промежуточных хостов. Латентность имеет мало отношения к пропускной способности канала.

C>>Хранимые процедуры, триггеры, CTE — уже не имеют никакого отношения к реляционной алгебре. Соответственно, глупо утверждать что программа с большим числом хранимок и триггеров более "реляционна", чем программа с H/ORM.

G>Как раз можно, томому что теже триггеры и CTE работают именно с реляционными данными, тогда как H/ORM хочет сделать вид что работа идет с объектами.
Нет, H/ORM работает с объектным представлением реляционных данных.

Сам по себе H/ORM так же "реляционен" как и голый SQL.

C>>Ещё как бывает со сложными моделями. У меня сейчас более тысячи разных операций. Для каждой операции в твоём подходе необходимо знать как она повлияет на всё остальное.

G>Не знаю как тебе, а мне не удавалось писать программы в которых я не знаю что происходит.
Ты знаешь, когда у тебя в программе на C# запускается GC?

Вот и мне неинтересно знать.

G>И для каждого сценария я могу сказать к каким изменениям он приводит.

Я тоже. Если специально посмотреть. Но зачем?

C>>Ты не учитываешь, что некоторые изменения должны делаються очень быстро. Если координатор, который должен распределить пару тысяч смен, должен по 10 секунд ждать на каждую операцию — он придёт к тебе домой и тебя застрелит.

G>Ну да, выдумывание небылиц — хороший способ обоснования свой позиции, с чего ты взял 10 секунд?
Даже пара секунд — уже много. Уже даже доли секунды — слишком много.

G>Даже если взять того же оператора и представить что пересчет аггрегатов в запросе выполняется в 100 раз быстрее 0.1 секунду, то на отображение 10000 записей ему придется ждать около 20 минут. И это прижедтся испытать каждому пользователю, который попытается просмотреть расписание.

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

C>>Я говорю не про FK. Я уже привёл пример, когда изменение одного кусочка данных повляет на другой, не связанный напрямую с ним.

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

C>>А не прошёл HTTP-запрос. Пакетик потерялся, и он ждёт retransmit'а. Или файрвол решил задержать ответ до проверки нет ли в нём вирусов.

G>Этона каталах, которые по 1,5 мбит выдают? Сам в это веришь?
Я же говорю — случаи реальные. Точнее, достоверно случившиеся. Вот буквально вчера пользователь пожаловался, что файл из системы документ-менеджмента в приложении не могут закачать. Оказалось, что излишне прыткий антивирус перехватил обращение, и не отдавал последний байтик пока не проверит всё тело (защищённое HTTPS — чего он там сканировал?). Чем вызывал таймаут в приложении.

C>>Нет. Лишний расход траффика — у тебя. У меня сейчас дневной расход на приложение — около 10Мб. 5Мб на начальную загрузку (надо бы её оптимизировать...), а дальше считанные байты на трансляцию изменений.

G>
G>А в моем подходе не будет начальной загрузки и теже 5 метров будут растянуты по времени. И потом тоже будут "считанные байты" на изменения.
Не будут. У тебя загрузка одного вида займёт в лучшем случае килобайт 500. А их переключают кучу десятков раз в день.

C>>Т.е. оно реально может использоваться на модеме.

G>
G>Я плакал
Плачь. Требование реально.

C>>Для твоей модели оно недостижимо.

G>Ну я как раз через GPRS часто в интернете сижу. Если бы мне кто-нибудь предложил скачать 5 метров просто чтобы начать пользоваться программой, то я бы сразу послал такой сервис.
А твой сервис с торможением по минуте на _каждое_ действие пошлют ещё дальше.

G>Короче хватит практиковаться в выдумывании небылиц. Адекватного описания преимуществ твоего подхода не видно, а все что есть вполне делается и без h\orm.

Ну да. Твой подход требует:
1) Большого расхода времени.
2) В 10-100 раз большего количества серверов.
3) Гораздо более сложного программирования — ручного отслеживания зависимостей.
4) Мешанины UDF, SP и прочих "радостей".
5) Зависимость от конкретной БД.
6) Не будет работать на модеме.
...


Зато у него один плюс — не будет использоваться H/ORM. Самому-то не смешно?
Sapienti sat!
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.