Здравствуйте, IT, Вы писали:
N>>Какие есть ORM для С++, пригодные для использования? В частности интересует поддерживающие sqlite. IT>Зачем ORM для C++? Добрался до буфера резалтсета, преобразовал его к нужной структуре и готово. ORM — это изобретение управляемых сред, потому что в них криво реализован прямой доступ к памяти.
Уже есть такое А если просто отображать объекты напрямую на дисковые файлы — то вообще...
Sapienti sat!
Re[28]: Оформление работы с БД в корпоративных приложениях -
Здравствуйте, Cyberax, Вы писали: C>Ну а потом эту очередь можно анализировать — определить сколько в какой момент на каждом локе было contender'ов, время ожидания и т.п.
А, ну то есть фактически профилируем время ожидания на различных объектах.
Там еще по-хорошему невредно следить за тем, кто лок в это время держит.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[29]: Оформление работы с БД в корпоративных приложениях -
Здравствуйте, Sinclair, Вы писали:
C>>Ну а потом эту очередь можно анализировать — определить сколько в какой момент на каждом локе было contender'ов, время ожидания и т.п. S>А, ну то есть фактически профилируем время ожидания на различных объектах. S>Там еще по-хорошему невредно следить за тем, кто лок в это время держит.
Так это тоже можно из этой очереди вычислить, если я не ошибаюсь. Естественно, в очередь также надо записывать идентификатор лока и потока.
Определение "кто держит" имеет смысл, если это сделать работающим в режиме "online" в отладчике. В принципе, это тоже не очень сложно.
Вообще, можно действительно продукт такой сделать — если интересно можно в почте продолжить.
Sapienti sat!
Re[6]: Оформление работы с БД в корпоративных приложениях -
Здравствуйте, kuj, Вы писали: A>>Плюс коллекции хибернета нарушают PI. kuj>Не совсем понял. Разъясните пожалуйста.
Very Important Note: If the <key> column of a <one-to-many> association is declared NOT NULL, NHibernate may cause constraint violations when it creates or updates the association. To prevent this problem, you must use a bidirectional association with the many valued end (the set or bag) marked as inverse="true". See the discussion of bidirectional associations later in this chapter.
Вынуждены использовать коллекции хибернета вместо стандартных.
Re[19]: Оформление работы с БД в корпоративных приложениях -
Здравствуйте, Aviator, Вы писали:
A>>>Плюс коллекции хибернета нарушают PI. kuj>>Не совсем понял. Разъясните пожалуйста.
A>Very Important Note: If the <key> column of a <one-to-many> association is declared NOT NULL, NHibernate may cause constraint violations when it creates or updates the association. To prevent this problem, you must use a bidirectional association with the many valued end (the set or bag) marked as inverse="true". See the discussion of bidirectional associations later in this chapter. A>
A>Вынуждены использовать коллекции хибернета вместо стандартных.
Э-э, а чем это мешает BLL? Ведь работаем-то все-равно через интерфейсы (IList, ICollections, etc). Или Вы не об этом, говоря, что нарушается PI?
... << RSDN@Home 1.2.0 alpha rev. 746>>
Re[20]: Оформление работы с БД в корпоративных приложениях -
Здравствуйте, kuj, Вы писали:
kuj>Разъясните подробнее пожалуйста.
Разъясняю подробнее: в каждой версии продукта мы вынуждены добавлять новые методы в API только для того, чтобы обработать новый класс запросов. Типа было GetUserByName(), теперь надо еще и GetUserByID(), FindUsersWhereNameLike(string namePart). А потом нужно еще и FindUsersWhereNameLike(string namePart, int pageSize, int pageNum, FieldName orderBy).
И это всё — практически без изменений модели данных; просто народу нужны разные view на наши данные.
Альтернатива — заставлять всех делать GetAllUsers() и потом самостоятельно сортировать/фильтровать — нереалистична в enterprize инсталляциях, где этих пользователей под сотню тыщ.
Получается какой-то экспоненциальный взрыв интерфейса сервиса на пустом месте.
Query Object в этом смысле — спасение. Но с ним нужен глаз да глаз, т.к. теряется преимущество compile-time валидации.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[21]: Оформление работы с БД в корпоративных приложениях -
Здравствуйте, Sinclair, Вы писали:
S>Получается какой-то экспоненциальный взрыв интерфейса сервиса на пустом месте. S>Query Object в этом смысле — спасение. Но с ним нужен глаз да глаз, т.к. теряется преимущество compile-time валидации.
А если механически разбить все эти GetUsersByBlah на несколько сервисов?
Sapienti sat!
Re[7]: Оформление работы с БД в корпоративных приложениях -
Здравствуйте, Kazna4ey, Вы писали:
bnk>>>Присоединяюсь к вопросу. bnk>>>Что вы человека всякой абстракцией да литературой грузите bnk>>>Ради бога, почему не привести понятные кусочки кода в 5-10 строк с каждого "уровня"? bnk>>>Можно же наверное в двух словах показать, как это выглядит У ВАС? bnk>>>
bnk>>>Это.. Как там... "Занятие включает рассказ, показ, тренировку", ага bnk>>>
MC>>Присоединяюсь. Очень интересно посмотреть как пишут люди с более высоким опытом.
K>А можно и я присоединюсь? 300 постов и НИ 1-го конкретного полного ответа на мои вопросы.
не считаю, что у меня более высокий опыт, пишу как понял из книг (сам просто интересуюсь темой)
по слоям:
1) Domain Model = Business Logic Layer = Model Layer
namespace Root.DomainLayer
{
// IDomainObject - layer supertype - держит общее поведение всех классов слояclass Order : IDomainObject
{
// поля
...
IDictionary<Product, int> Items
{
get
...
set
{
// проверка состояния заказа и присваивание - валидация
...
}
}
Money Price
{
get
{
// расчёт цены - бизнес-логика
...
}
}
// методы доступа к данным НЕ здесь!!
// остальное - binding, вызовы за пределы слоя - тоже не здесь.
}
}
2) интерфейс — Presentation layer
namespace Root.UI
{
// это одно из решений - вроде бы по паттерну Model-View-Controllerclass ShoppingCartForm : Form
{
//используется data binding свойств объекта к контролам.private Customer client;
// если нужно куда-то вставить дополнительный код для биндинга, можно к domain object применить паттерн Extension Object/Interfaceprivate CustomerController controller;
...
private btnOrder_Click(...)
{
controller.PlaceOrder(client);
}
}
class CustomerController
{
// возможна ссылка на Customer здесь, а не в форме, тогда это кажется Model-View-Presentervoid PlaceOrder(Customer client)
{
Order newOrder = ApplicationController.OrderService.Place(client);
// как-то открыть форму заказа с newOrder, хотя за оптимальность решения не уверен
...
}
}
}
контроллер введён хотя бы для того, чтобы выделить из представления взаимодействие с инфраструктурой приложения
3) Application Layer = Service Layer
namespace Root.ApplicationLayer
{
// Service Locator, для той же цели можно использовать какойнибудь контейнерclass ApplicationController
{
private IOrderProcessingService orderService;
// паттерн singletonprivate static ApplicationController instance;
private ApplicationController() { }
static void Configure()
{
instance = new ApplicationController();
// не знаю как
...
}
static IOrderProcessingService OrderService
{
get
{
return instance.orderService;
}
}
}
class OrderProcessingServiceImpl : IOrderProcessingService
{
IManager<Order> mapper = null;
...
Order Place(Customer client)
{
// здесь могут быть внешние вызовы, транзакции, вызовы бизнес-логики и обращения к DAL
Order order = new Order(client.Cart);
mapper.Save(order);
client.Orders.Add(order);
return order;
}
// остальные методы обработки заказов
...
}
// возможно этот класс в отдельной сборке Launcherclass Application
{
void Main(String[] args)
{
ApplicationController.Configure();
// сам последннее време пользую фреймворки Eclipse RCP и MS Composite UI Application Block с SCSF, так что если без них, то хождение по Use Case'ам (то есть упавляемый показ форм/view) придумывайте сами
....
}
}
}
4) DAL — паттерн Data Mapper
namespace Root.DataAccessLayer
{
// здесь методы доступа к даннымclass Manager<TDomainObject> where TDomainObject : IDomainObject
{
// Query - не знаю как он в Hibernate называетсяpublic Collection<TDomainObject> List(Query criteria)
{
// это тоже типа Hibernate, просто давно не ползовался забыл названия
session.Select(...
}
public void Save(TDomainObject data)
{
...
}
public bool Delete(ID arg)
{
...
}
}
}
основано на материалах martinfowler.com
критикуйте
Re[24]: Оформление работы с БД в корпоративных приложениях -
Здравствуйте, IT, Вы писали:
IT>И в чём проблема добавить ещё одно поле в таблицу?
Проблема существенная. Во-первых, это добавление цепной реакцией прокатывается по всем SQL запросам. Во-вторых, столбец надо добавить во множестве мест, то есть приходиться делать уже не просто инсталляции, а апдейтеры зовущие ALTER TABLE и тестировать не только инсталляцию продукта, но и апдейтеры на всех комбинациях версий продукта. Это нелинейно увеличивает объём тестирования.
Здравствуйте, Trean, Вы писали:
T>Ха-ха, так в ряде случаев такая структура — известный анти-паттерн, есть даже для нее название, но я к сожалению не могу припомнить его. Структура запросов с джойнами, агрегатами настолько усложняется, что ну его нафиг. Для системы к которой предъявляются требования по выскокой производительности — такая денормализованная структура bad practice. Вот для CMS какой-нибудь — нормально, так сделано в Alfresco CMS (кстати тоже через Hibernate).
Ты не понял, видимо. Доступ ко всем UserProperties одинаковый. То есть нет запроса вида
UPDATE UserProperties SET value='{0}' WHERE name='FirstName'
есть только запросы вида
UPDATE UserProperties SET value='{0}' WHERE name='{1}'
T>А я вот не согласен. О каком пользователе БД вы говорите? У меня бизнес-логика вообще не знает, повторяю ВООБЩЕ, об особенностях хранении объектов в базе, о запросах, это скрыто соответствующими классами DAL (в частности DAO) и маппингом который указывается декларативно! Какая длина поля в базе, в какую таблицу заносить и т.д. все это скрыто. Ваше решение привязывает вас к конкретному поставщику БД, а я свою программу могу использовать с MySQL, PostgreSQL (суперская вещь), Oracle и т.д. В 10% случаев надо что-то подкрутить в DAL и все. Вот не устроил меня MySQL в котором двуфазный коммит отсутствует, я с него переехал на постгре, и почти ничего подкручивать не надо.
Не привязывает, всё специфика остаётся в БД, наружу торчит только ХП. Даже DAL при переходе на другую БД не особо переписывается.
Здравствуйте, Sinclair, Вы писали:
S>Идея правильна, в реализации не уверен. S>Я имел опыт с системами, построенными подобным образом. Традиционно считается, что схему данных менять тяжелее, чем сами данные. S>Однако это далеко не всегда так; кроме того, "добавление колонок" далеко не всегда сводится только к полям в UI. Как только начнет появляться какая-то бизнес-логика вокруг этих полей, например foreign key или запросы по их содержимому, начинаются проблемы. Как на уровне БД так и на уровне маппинга. По сравнению с этими трудностями alter table add column покажется детским лепетом.
Ну вообще-то из примера вроде было видно, что группируются таким образом только то, над чем проводятся однотипные операции. Login и Password я не вынес. Во-первых, это ударит по производительности, во-вторых, с ними проводится совсем другой набор операций.
Здравствуйте, IT, Вы писали:
A>>Подобные проблемы, я считаю разумным решать через ХП, скрывающие структуру БД. IT>ХП не лучший выбор в данном случае. Лучше такие вещи решать через view.
Я как-то не соображу чем View в поддержке проще ХП если и там и тут запрос.
Здравствуйте, adontz, Вы писали:
IT>>И в чём проблема добавить ещё одно поле в таблицу?
A>Проблема существенная. Во-первых, это добавление цепной реакцией прокатывается по всем SQL запросам. Во-вторых, столбец надо добавить во множестве мест, то есть приходиться делать уже не просто инсталляции, а апдейтеры зовущие ALTER TABLE и тестировать не только инсталляцию продукта, но и апдейтеры на всех комбинациях версий продукта. Это нелинейно увеличивает объём тестирования.
Думаю, тогда тебе лучше всего создать одну таблицу, где будет тип сушности, ID, имя поля и значение. Проблем вообще никаких не будет.
... << RSDN@Home 1.2.0 alpha rev. 771>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[25]: Оформление работы с БД в корпоративных приложениях -
Здравствуйте, IT, Вы писали:
IT>>>И в чём проблема добавить ещё одно поле в таблицу?
A>>Проблема существенная. Во-первых, это добавление цепной реакцией прокатывается по всем SQL запросам. Во-вторых, столбец надо добавить во множестве мест, то есть приходиться делать уже не просто инсталляции, а апдейтеры зовущие ALTER TABLE и тестировать не только инсталляцию продукта, но и апдейтеры на всех комбинациях версий продукта. Это нелинейно увеличивает объём тестирования.
IT>Думаю, тогда тебе лучше всего создать одну таблицу, где будет тип сушности, ID, имя поля и значение. Проблем вообще никаких не будет.
Кстати, IMHO, это было бы весьма здорово, но на больших объемах данных это к сожалению будет крайне неэффективно...
А так для небольших объемов — самое оно. Идеология "ID, имя поля и значение" — IMHO вообще рульный подход.
Обеспечивает замечательную гибкость при минимальном количестве гемороя (при добавлении новых "фич").
Но если уж отказываемся от такого подхода и делаем в несколько связанных таблиц то внешние
ключи хранить в виде "имя — значение" — это конечно будет полный бред,
для них будет проще (и правильнее) добавлять колонку..
Re[27]: Оформление работы с БД в корпоративных приложениях -
Здравствуйте, bnk, Вы писали:
IT>>Думаю, тогда тебе лучше всего создать одну таблицу, где будет тип сушности, ID, имя поля и значение. Проблем вообще никаких не будет.
bnk>Кстати, IMHO, это было бы весьма здорово
Берёшь свой любой запрос в котором хотя бы три таблицы и десяток полей и переписываешь его по такой схеме. Потом смотришь здорово это или нет.
... << RSDN@Home 1.2.0 alpha rev. 771>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[28]: Оформление работы с БД в корпоративных приложениях -
Здравствуйте, IT, Вы писали:
IT>>>Думаю, тогда тебе лучше всего создать одну таблицу, где будет тип сушности, ID, имя поля и значение. Проблем вообще никаких не будет.
bnk>>Кстати, IMHO, это было бы весьма здорово
IT>Берёшь свой любой запрос в котором хотя бы три таблицы и десяток полей и переписываешь его по такой схеме. Потом смотришь здорово это или нет.
Ну дак мы же говорим про ОДНУ таблицу. Понятно что для нескольких это (в лоб) не сработает.
Я же специально оговорился про внешние ключи и т.п.
Идея в том что вот это:
| ID | NAME | VALUE |
---------------------
| 1 | A | X |
| 1 | B | X |
| 2 | A | Y |
| 2 | B | Y |
"лучше" (гибче, "удобнее в апгрейде") чем вот это:
| ID | A | B |
--------------
| 1 | X | X |
| 2 | Y | Y |
Хотя очевидно тормознутее.
Re[25]: Оформление работы с БД в корпоративных приложениях -
Здравствуйте, adontz, Вы писали:
A>Здравствуйте, Trean, Вы писали:
T>>Ха-ха, так в ряде случаев такая структура — известный анти-паттерн, есть даже для нее название, но я к сожалению не могу припомнить его. Структура запросов с джойнами, агрегатами настолько усложняется, что ну его нафиг. Для системы к которой предъявляются требования по выскокой производительности — такая денормализованная структура bad practice. Вот для CMS какой-нибудь — нормально, так сделано в Alfresco CMS (кстати тоже через Hibernate).
A>Ты не понял, видимо. Доступ ко всем UserProperties одинаковый. То есть нет запроса вида A>UPDATE UserProperties SET value='{0}' WHERE name='FirstName' A>есть только запросы вида A>UPDATE UserProperties SET value='{0}' WHERE name='{1}'
Я не про это. Сколько надо update statements, чтобы изменить разом несколько свойств пользователя? Или как будет выглядеть запрос поиска пользователя, имеющего заданные свойства, например, имя, фамилию, телефон.
T>>А я вот не согласен. О каком пользователе БД вы говорите? У меня бизнес-логика вообще не знает, повторяю ВООБЩЕ, об особенностях хранении объектов в базе, о запросах, это скрыто соответствующими классами DAL (в частности DAO) и маппингом который указывается декларативно! Какая длина поля в базе, в какую таблицу заносить и т.д. все это скрыто. Ваше решение привязывает вас к конкретному поставщику БД, а я свою программу могу использовать с MySQL, PostgreSQL (суперская вещь), Oracle и т.д. В 10% случаев надо что-то подкрутить в DAL и все. Вот не устроил меня MySQL в котором двуфазный коммит отсутствует, я с него переехал на постгре, и почти ничего подкручивать не надо.
A>Не привязывает, всё специфика остаётся в БД, наружу торчит только ХП. Даже DAL при переходе на другую БД не особо переписывается.
А что синтаксис хранимок oracle и mssql настолько одинаков? Кроме того, как реализовать запросы с переменным кол-вом параметров через ХП? Прописывать все возможные варианты? Последний раз (года так 3 назад), когда я интересовался как это сделать в MSSQl в форумах было написано, что сделать это можно только через грязный хак с массивами, и врядли это портабельное решение. Избежать привязки клиента к конкретной базе оградившись лишь забором из ХП — невозможно. View, как тут выше писали, вот это действительно хорошее решение в ряде случаев, особо что касается Read-Only View.
Когда-нибудь у меня дойдут руки написать небольшой тестик и сравнить скорость выполнения бизнес-логики в ХП и скажем в C или Java. Человек долго работавший с MSSQL, сказал, что на удивление, тот же код переписанный на С оказался быстрее эквивалентного кода на ХП даже с footprint вызванным необходимостью передавать данные клиенту БД на обработку.
Re[29]: Оформление работы с БД в корпоративных приложениях -