Оформление работы с БД в корпоративных приложениях - как?
От: Kazna4ey  
Дата: 22.09.07 10:08
Оценка: 4 (1) -1 :))) :))
Доброе время суток,

Я 2 года занимаюсь разработкой корпоративных (бизнес) приложений. Как вы знаете, очень большую часть в такого типа приложениях занимает работа с БД. И очень важно правильно ее оформить, потому что при разрастании проекта за несколько тысяч строк (по моему опыту примерно 10000 строк) появляются некоторые проблемы. Можно выделить 2 основные проблемы:

1) Изменение схемы БД. На каком-то уровне оно становится сложным или просто невозможным. Например мы хотим перенести какое-то поле в отдельную таблицу, а в оригинальном поле указывать ID строки из этой новой таблицы. Вполне реальная ситуация что это может понадобится. Но теперь мне приходится перелопачивать сотни запросов в программе и десятки хранимых процедур, а потом молиться что нигде не вывалится скрытый косяк.

2) Смена СУБД. No comments.

Понимаю, что способов оформления работы с БД может быть много. Это может быть тупое написание SQL-кода в обработчике кнопки, это может быть оформление отдельного класса, в котором этот код уже будет записан, это может быть тот же Query Object, и т.д. Вопрос в том какой метод наиболее эффективен и распространен при разработке корпоративных приложений среднего размера (под средним размером я понимаю пару десятков тысяч строк кода написанного вручную и БД из пары десятков таблиц)?

Опишу, как я оформляю работу с БД.

Если какое-то обращение к БД — единичное, т.е. запрос очень специфический и его вызов происходит только в одном месте программы, то я не отделяю его от кода формы, т.е. пишу его прямо в обработчике события или отдельным методом класса формы/контрола, например так:


    private void btnLink_Click(object sender, EventArgs e)
    {
        ...
        MySqlCommand command = new MySqlCommand("LinkSupPaymentToSupInvoice", conn);
        command.CommandType = CommandType.StoredProcedure;
        command.Parameters.Add("?SupInvoiceID_", MySqlDbType.Int32);
                command.Parameters.Add("?SupTransactionsID_", MySqlDbType.Int32).Value = SupTransactionsID;
                for (int i = 0; i < SelectedRows.Length; i++)
                {
                    command.Parameters["?SupInvoiceID_"].Value = Convert.ToInt32(View.GetRowCellValue(SelectedRows[i], ID));
                    command.ExecuteNonQuery();
                }
        ...
    }


Пока писал пример, возник попутный вопрос:
Насколько нужно/ненужно использовать хранимые процедуры/функции? Лично мне это решение зачастую кажется более удобным по нескольким причинам: читабельность кода в программе (просто видим имя процедуры а не длинный SQL запрос и сразу все понимаем), простота изменения (если нужно внести изменения, зачастую изменяем только ХП на сервере а не изменяем что-то в нескольких местах в программе где она используется), ну и для меня не очень важный фактор — производительность.

Ладно, отвлекся, идем дальше.

Если запрос или его модификация должен вызываться из нескольких мест в программе, то я его оформляю в виде статического метода в классе типа CommonFuncs:

    public static double GetPartPrice(int ManufacturerID, int SupplierID, string PartN, MySqlConnection conn)
    {
        try
        {
            MySqlCommand command = new MySqlCommand("GetPartPrice", conn);
            command.CommandType = System.Data.CommandType.StoredProcedure;
            command.Parameters.Add("?ManufacturerID_", MySqlDbType.Int32).Value = ManufacturerID;
            command.Parameters.Add("?SupplierID_", MySqlDbType.Int32).Value = SupplierID;
            command.Parameters.Add("?PartN_", MySqlDbType.VarChar).Value = PartN;
            command.Parameters.Add("?Result", MySqlDbType.Double).Direction = System.Data.ParameterDirection.ReturnValue;
            command.ExecuteNonQuery();
            return Convert.ToDouble(command.Parameters["?Result"].Value);
        }
        catch (Exception ex)
        {
            common.ShowException("An error occurred while trying to get part price from the database.\n\n" +
            "Debug info:\ncommon.cs, GetPartPrice()\n", ex.Message);
            return 0;
        }
    }


Если работа происходит с таблицей (всмысле гридом) обычно стараюсь работать через SelectCommand, UpdateCommand и т.д. класса SqlDataAdapter, типа так:


    ...
    adapterNotScanned.SelectCommand = db.BarcodeSystem.CreateDataAdapterSelectCommand(conn);
    adapterNotScanned.SelectCommand.Parameters.Add("?IsScanned", MySqlDbType.Bit).Value = false;
    adapterNotScanned.SelectCommand.Parameters.Add("?IsPacked", MySqlDbType.Bit).Value = false;
    adapterNotScanned.UpdateCommand = db.BarcodeSystem.NotScannedUpdateCommand(conn);
    adapterNotScanned.TableMappings.Add("parts", "partsNotScanned");
    ...

    // В классе db.BarcodeSystem все выглядит типа так:
    public static MySqlCommand CreateDataAdapterSelectCommand(MySqlConnection conn)
    {
        string strSQL;
        strSQL = "SELECT blablabla FROM parts WHERE Customer = ?Customer AND OrderDebited = true AND " + 
        "OrderInvoiced = false AND IsScanned = ?IsScanned AND IsPacked = ?IsPacked ORDER BY ManufacturerID, PartN";
        MySqlCommand cmd = new MySqlCommand(strSQL, conn);
        return cmd;
    }


Вот в общем-то и все. Так я делаю работу с БД.
Думаю, что мой вопрос и поднятая тема очень важны, и будут очень полезны большому количеству начинающих и средних программистов.
Так что... Направьте на путь истинный?

Заранее большое спасибо. С уважением.
Re: Оформление работы с БД в корпоративных приложениях - как
От: Gollum Россия  
Дата: 22.09.07 10:14
Оценка:
Здравствуйте, Kazna4ey, Вы писали:

K> Я 2 года занимаюсь разработкой корпоративных (бизнес) приложений. Как вы знаете, очень большую часть в такого типа приложениях занимает работа с БД.


Живой пример — Business Logic Toolkit
И начальник заставы поймет меня, и беспечный рыбак простит
Eugene Agafonov on the .NET

Re: Оформление работы с БД в корпоративных приложениях - как
От: adontz Грузия http://adontz.wordpress.com/
Дата: 22.09.07 13:30
Оценка:
Здравствуйте, Kazna4ey, Вы писали:

K>1) Изменение схемы БД. На каком-то уровне оно становится сложным или просто невозможным. Например мы хотим перенести какое-то поле в отдельную таблицу, а в оригинальном поле указывать ID строки из этой новой таблицы. Вполне реальная ситуация что это может понадобится. Но теперь мне приходится перелопачивать сотни запросов в программе и десятки хранимых процедур, а потом молиться что нигде не вывалится скрытый косяк.

K>2) Смена СУБД. No comments.

Это решается введением специального Data Access Layer, находящегося "под" Business Logic Layer и предоставляющего последнему интерфейс в терминах Business Objects (иногда Data Transfer Objects, если логика Business Objects вынесена во внешние манипуляторы).

В этом случае изменение схемы БД, самой БД и т.д. во-первых, локализованно в пределах DAL, а во-вторых, как следствие во-первых, тестирование DAL необходимо и достаточно для тесрирования целостности схемы БД.
Тестирование БД задача, вообще говоря, премерзкая, но если приложение действительно корпоративное, весьма неоходимая. Сложность тестирования DAL заключается не только в выделении test cases, но и подготовке исходных данных. Нередко, для того чтобы протестировать некоторый запрос, необходимо заполнить кучу таблиц.
A journey of a thousand miles must begin with a single step © Lau Tsu
Re: Оформление работы с БД в корпоративных приложениях - как
От: Kazna4ey  
Дата: 22.09.07 13:34
Оценка: :)
Забыл сразу написать:

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

Заранее спасибо!
Re: Оформление работы с БД в корпоративных приложениях - как
От: Aviator  
Дата: 23.09.07 13:49
Оценка: +1
Здравствуйте, Kazna4ey, Вы писали:

K>Доброе время суток,


K> Я 2 года занимаюсь разработкой корпоративных (бизнес) приложений. Как вы знаете, очень большую часть в такого типа приложениях занимает работа с БД. И очень важно правильно ее оформить, потому что при разрастании проекта за несколько тысяч строк (по моему опыту примерно 10000 строк) появляются некоторые проблемы. Можно выделить 2 основные проблемы:


Две вещи звучат странно. Во-первых, меня удивляло зачем считать количесттво строк кода. Во — вторых, пишете "бизнес приложения" два года и задаёте такие странные вопросы.

Писать sql запросы в обработчиках событий на форме — это мягко говоря не очень правильно. Можно явно выделить логику работы с СУБД в отдельный набор классов, т.е. слой. Например

public class DataAccessLayer {
   public IList<Order> GetOrdersForDate(DateTime date) {
   }

   public IList<Order> GetOrdersByCustomer(Customer customer) {
   }
}


Фактически у вас такая структура где-то была. А вообще для корпоративных приложений сейчас можно использовать ORM, например Hibernate или iBattis, в зависимости от конкретники задачи. Последний хорошо использоват ьв случае большого количества legacy кода на sql. В случае применения ORM data access objects можно не применять и рассматривать ORM как абстракцию от специфики СУБД. Данный вопрос неодназнеачен и далеко не все согласны отказываться от DAO, только недавно большая дискуссия по сабжу была.

Что ксасается использования хранимок, то тут сколько противников столько же и сторонников. Минусом хранимок явлются как минимум: сложность поддержки, меньшая масштабируемость, зависимость от конкретной СУБД. Для меня этого достаточно , что бы от них отказаться.
Re[2]: Оформление работы с БД в корпоративных приложениях -
От: adontz Грузия http://adontz.wordpress.com/
Дата: 23.09.07 14:12
Оценка:
Здравствуйте, Aviator, Вы писали:

A>Минусом хранимок явлются как минимум: сложность поддержки, меньшая масштабируемость, зависимость от конкретной СУБД.


Это минус по сравнению с чем? По сравнению с вписанными в код SQL запросами?!
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[3]: Оформление работы с БД в корпоративных приложениях -
От: Aviator  
Дата: 23.09.07 19:23
Оценка:
Здравствуйте, adontz, Вы писали:

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


A>>Минусом хранимок явлются как минимум: сложность поддержки, меньшая масштабируемость, зависимость от конкретной СУБД.

A>Это минус по сравнению с чем? По сравнению с вписанными в код SQL запросами?!
По сравнению с вариантом без привлечения хранимых процедур.
Re[4]: Оформление работы с БД в корпоративных приложениях -
От: adontz Грузия http://adontz.wordpress.com/
Дата: 23.09.07 19:53
Оценка: +1 -1
Здравствуйте, Aviator, Вы писали:

A>>>Минусом хранимок явлются как минимум: сложность поддержки, меньшая масштабируемость, зависимость от конкретной СУБД.

A>>Это минус по сравнению с чем? По сравнению с вписанными в код SQL запросами?!
A>По сравнению с вариантом без привлечения хранимых процедур.

ИМХО ХП напротив проще поддерживать потому что:
  • ХП пишет тот же, кто разработал схему БД, а значит ХП лучше учитывают наличие или отсутствие индексов. прикладной же программист вставляющий в свой код SQL запросы в лучшем случае прочитал названия таблиц и столбцов.
  • ХП позволяют держать в БД не только данные, но и код управления данными, обеспечивая их целостность (группировку запросов в транзакции и т.п.) на уровне хранения. Естественно, гораздо лучше когда это делает разработчик БД, а не прикладной программист знающий только имена таблиц и столбцов. Кроме того, использование ХП позволяем автоматически тестировать самый низкоуровневый код работы с данными. Это особенно актуально при изменении схемы (добавлении столбца, а то и таблицы). Так же, тестируя ХП на объёмах данных разных порядков можно делать косвенные выводы об асимптоте скорости работы без ручного разбора планов исполнения SQL запросов и прогнозировать наличие узких мест до того как кто-то в них застрял.
  • Прикладной программист знающий только имена таблиц и столбцов не миф. Во-первых, имея уже готовую (постоянно меняющуюся!) БД узнать всё остальное может быть проблемно, во-вторых просто лень.

    Про масштабируемость не понял к чему было. Как использование ХП уменьшает масштабируемость системы? Очень интересно послушать, желательно с примерами.

    Зависимость от конкретной СУБД будет всегда. Дело даже не в синтаксических различиях диалектов SQL, а в разном объёме предоставляемой функциональности. Система не может быть независимой от СУБД на уровне DAL. Это ИМХО миф и утопия.
  • A journey of a thousand miles must begin with a single step © Lau Tsu
    Re[5]: Оформление работы с БД в корпоративных приложениях -
    От: Cyberax Марс  
    Дата: 23.09.07 20:03
    Оценка:
    Здравствуйте, adontz, Вы писали:

    A>
  • ХП пишет тот же, кто разработал схему БД, а значит ХП лучше учитывают наличие или отсутствие индексов. прикладной же программист вставляющий в свой код SQL запросы в лучшем случае прочитал названия таблиц и столбцов.
    А откуда программист узнает названия ХП, порядок их вызова и какие параметры им передавать?

    A>
  • ХП позволяют держать в БД не только данные, но и код управления данными, обеспечивая их целостность (группировку запросов в транзакции и т.п.) на уровне хранения. Естественно, гораздо лучше когда это делает разработчик БД, а не прикладной программист знающий только имена таблиц и столбцов.
    Целостность лучше всего обеспечивать на уровне приложения с помощью интуитивно-понятных для пользователя способов. К примеру, на форме необходимые поля должны быть подсвечены и кнопка "OK" должна блокироваться, если они не заполнены. Это намного понятнее, чем сообщение "Error 2422934: Foreign key constraint violation".

    БД тут должна работать в качестве "последнего рубежа" обороны — если невалидные данные все-таки прорвались, то хотя бы целостность данных в базе у нас сохранится. Для такой валидации прекрасно подходят триггеры и разные системы валидации в БД.

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

    Со слоем DAL все точно так же.

    A>
  • Прикладной программист знающий только имена таблиц и столбцов не миф. Во-первых, имея уже готовую (постоянно меняющуюся!) БД узнать всё остальное может быть проблемно, во-вторых просто лень.
    Вот поэтому и нужен слой DAL, который изолирует "прикладного программиста" от знания деталей базы данных и дает намного более понятный и приятный объектный интерфейс. Ну и создание DAL можно существенно автоматизировать с помощью ORM.
  • Sapienti sat!
    Re[6]: Оформление работы с БД в корпоративных приложениях -
    От: adontz Грузия http://adontz.wordpress.com/
    Дата: 23.09.07 20:21
    Оценка: +1
    Здравствуйте, Cyberax, Вы писали:

    A>>
  • ХП пишет тот же, кто разработал схему БД, а значит ХП лучше учитывают наличие или отсутствие индексов. прикладной же программист вставляющий в свой код SQL запросы в лучшем случае прочитал названия таблиц и столбцов.
    C>А откуда программист узнает названия ХП, порядок их вызова и какие параметры им передавать?

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

    Информация о пользователях хранится к таблице Users. Таблица Users содержит столбцы ID, Login, Password, FirstName, LastName. Индексированными являются столбцы ID, Login и Password.


    Для доступа к данным о пользователях следует спользовать следующие ХП:

    GetUserByCredential(Login, Password)
    Возвращает ID, Login, FirstName, LastName

    GetUserByID(ID)
    Возвращает ID, Login, FirstName, LastName

    AddUser(ID, Login, Password, FirstName, LastName)
    Добавляет пользователя

    ChangeUserPassword(Login, OldPassword, NewPassword)
    Меняет пароль пользователя

    SetUserFirstName(ID, FirstName)
    Задаёт имя пользователя

    SetUserLastName(ID, LastName)
    Задаёт фамилию пользователя


    Программист пользующийся ХП из второго состояния не в состоянии напортачить. Программист пользующийся первым вариантом вполне может отмочить что-то вроде
    UPDATE Users SET Password=NewPassword WHERE FirstName='John' AND LastName='Smith'

    A>>
  • ХП позволяют держать в БД не только данные, но и код управления данными, обеспечивая их целостность (группировку запросов в транзакции и т.п.) на уровне хранения. Естественно, гораздо лучше когда это делает разработчик БД, а не прикладной программист знающий только имена таблиц и столбцов.
    C>Целостность лучше всего обеспечивать на уровне приложения с помощью интуитивно-понятных для пользователя способов. К примеру, на форме необходимые поля должны быть подсвечены и кнопка "OK" должна блокироваться, если они не заполнены. Это намного понятнее, чем сообщение "Error 2422934: Foreign key constraint violation".
    C>БД тут должна работать в качестве "последнего рубежа" обороны — если невалидные данные все-таки прорвались, то хотя бы целостность данных в базе у нас сохранится. Для такой валидации прекрасно подходят триггеры и разные системы валидации в БД.

    Я был бы благодарен, если бы ты не только писал, но и читал. Твой ответ абсолютно не в тему. Перечитай моё сообщение ещё раз, особенно отрывок

    обеспечивая их целостность (группировку запросов в транзакции и т.п.)

    Ты считаешь, что группировку в транзакции надо делать на уровне обработчика событий кнопки ОК?!

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


    C>Со слоем DAL все точно так же.


    Наличие слоя DAL абсолютно перпендикулярно. Тут обсуждаются примущества наличия ХП перед их отсутвием и напротив. DAL может существовать и отсутствовать и в том и в другом случае.

    A>>
  • Прикладной программист знающий только имена таблиц и столбцов не миф. Во-первых, имея уже готовую (постоянно меняющуюся!) БД узнать всё остальное может быть проблемно, во-вторых просто лень.
    C>Вот поэтому и нужен слой DAL, который изолирует "прикладного программиста" от знания деталей базы данных и дает намного более понятный и приятный объектный интерфейс. Ну и создание DAL можно существенно автоматизировать с помощью ORM.

    А кто напишет это DAL? Сам возьмётся?
  • A journey of a thousand miles must begin with a single step © Lau Tsu
    Re[5]: Оформление работы с БД в корпоративных приложениях -
    От: kuj  
    Дата: 23.09.07 21:00
    Оценка: 1 (1) +1
    Здравствуйте, adontz, Вы писали:

    A>>>>Минусом хранимок явлются как минимум: сложность поддержки, меньшая масштабируемость, зависимость от конкретной СУБД.

    A>>>Это минус по сравнению с чем? По сравнению с вписанными в код SQL запросами?!
    A>>По сравнению с вариантом без привлечения хранимых процедур.

    A>ИМХО ХП напротив проще поддерживать потому что:

    Вы когда-нибудь пытались поддерживать ХП? Я имею в виду более менее большие проекты, а не базы с парой десяткой табличек и 30-40 процедурами.

    A>
  • ХП пишет тот же, кто разработал схему БД, а значит ХП лучше учитывают наличие или отсутствие индексов. прикладной же программист вставляющий в свой код SQL запросы в лучшем случае прочитал названия таблиц и столбцов.
    В наше время все давно используют различные OR/M.

    A>
  • ХП позволяют держать в БД не только данные, но и код управления данными, обеспечивая их целостность (группировку запросов в транзакции и т.п.) на уровне хранения.
    Что чрезвычайно усложняет сопровождение такого проекта, т.к. ХП гораздо сложнее отлаживать и тестировать. О читабельности я вообще молчу.

    A>Естественно, гораздо лучше когда это делает разработчик БД, а не прикладной программист знающий только имена таблиц и столбцов.

    Потому и используют OR/M. Нету никаких таблиц. Нету никаких столбцов. Есть объекты DAL-уровня со свойствами. Есть соотвествующие объекты BLL уровня с бизнес логикой. Все связи минимальны благодаря IoC-контейнерам (Spring, Castle Windsor и т.п.). Код тщательно документируется. В наличии богатый IntelliSense инструментарий, фреймворки для тестирования типа nUnit с RhinoMocks, средства для автоматического создания документации, мощный отладчик, прекрасная читабельность кода, отсутствие привязки к конкретной БД и минимальная зависимость от схемы БД, высокая масштабируемость.

    A>Кроме того, использование ХП позволяем автоматически тестировать самый низкоуровневый код работы с данными.

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

    A>Зависимость от конкретной СУБД будет всегда. Дело даже не в синтаксических различиях диалектов SQL, а в разном объёме предоставляемой функциональности. Система не может быть независимой от СУБД на уровне DAL. Это ИМХО миф и утопия.

    Да? Какой кошмар...
    ... << RSDN@Home 1.2.0 alpha rev. 746>>
  • Re[7]: Оформление работы с БД в корпоративных приложениях -
    От: Cyberax Марс  
    Дата: 23.09.07 21:48
    Оценка: +1
    Здравствуйте, adontz, Вы писали:

    A>>>
  • ХП пишет тот же, кто разработал схему БД, а значит ХП лучше учитывают наличие или отсутствие индексов. прикладной же программист вставляющий в свой код SQL запросы в лучшем случае прочитал названия таблиц и столбцов.
    C>>А откуда программист узнает названия ХП, порядок их вызова и какие параметры им передавать?
    A>Если нет документации (кстати почему её нет?)
    А если есть документация по схеме, то откуда тогда программисты знающие только про колонки в базе?

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

    [skip]
    A>Программист пользующийся ХП из второго состояния не в состоянии напортачить.
    Жуть. У нас куча простых однострочных процедур ТОЛЬКО для одной простенькой сущности, даже без связей. Да еще и нет поддержки оптимистических блокировок.

    A>Программист пользующийся первым вариантом вполне может отмочить что-то вроде

    A>UPDATE Users SET Password=NewPassword WHERE FirstName='John' AND LastName='Smith'
    У меня было бы описано так:
    public class User 
    {
       private long id,version; //Вообще-то обычно они выделены в базовый класс
       @Column(length=64)
       private String firstName, lastName, login, password;
       
       //Добавим еще для интереса аудит.
       @Requisite(Role.SERVER)
       private List<UserAuditRecord> auditRecords;
    
       //getter'ы и setter'ы пропускаем по причине их тривиальности.
    }

    Усё.

    Прикладной программист работает с объектами, простые изменения он может персистить вот так:
    Session sess=...;
    User user=sess.get(User.class, userId);
    user.setFirstName("Vasja");
    sess.saveOrUpdate(user);


    А вот если он попробует так поменять auditRecords — получит в лоб исключением, так как для этого код должен явным образом взять роль "SERVER". Для реального User'а @Requisite будет стоять не на один метод, а на весь класс.

    Система еще обеспечит нам автоматическое оптимистическое версирование по полю version.

    C>>БД тут должна работать в качестве "последнего рубежа" обороны — если невалидные данные все-таки прорвались, то хотя бы целостность данных в базе у нас сохранится. Для такой валидации прекрасно подходят триггеры и разные системы валидации в БД.

    A>Я был бы благодарен, если бы ты не только писал, но и читал. Твой ответ абсолютно не в тему. Перечитай моё сообщение ещё раз, особенно отрывок
    A>

    A>обеспечивая их целостность (группировку запросов в транзакции и т.п.)

    A>Ты считаешь, что группировку в транзакции надо делать на уровне обработчика событий кнопки ОК?!
    Да, при открытии формы — начинаем бизнес-транзакцию с оптимистическим версированием, при коммите ее заканчиваем. Механизм работы с транзакциями в БД — отдаем на откуп middleware.

    Скажем, у меня это выглядит так:
    @Transactional(rollbackFor=Throwable.class)
    public class QCManagerBean implements QCManagerRemote
    {
        ...
        //Приостанавливает текущую транзакциию на время исполнения метода и начинает новую
        @Transactional(propagation=REQUIRES_NEW)
        public void businessMethod1(...)
        {
        }
    
        //Обязан выполняться внутри транзакции, но сам ее не начинает
        @Transactional(propagation=MANDATORY)
        public void businessMethod2(...)
        {
        }
    
        //Автоматически начинает транзакцию, если ее нет.
        public void businessMethod3(...)
        {
        }
    }


    И я вообще слабо понимаю что ты понимаешь под "группировкой в транзакции". Явный begin/commit из ХП? Так это вообще в морг.

    C>>Со слоем DAL все точно так же.

    A>Наличие слоя DAL абсолютно перпендикулярно. Тут обсуждаются примущества наличия ХП перед их отсутвием и напротив. DAL может существовать и отсутствовать и в том и в другом случае.
    Не перпендикулярно. Имея выделенный слой DAL и XP мы просто будем делать лишнюю работу. Скажем твой пример с пользователем можно точно так же сделать с помощью DAL'а в виде класса UserDAO, с которым и будет работать прикладной программист.

    Естественно, за работу с данными минуя DAL — бить ногами.

    C>>Вот поэтому и нужен слой DAL, который изолирует "прикладного программиста" от знания деталей базы данных и дает намного более понятный и приятный объектный интерфейс. Ну и создание DAL можно существенно автоматизировать с помощью ORM.

    A>А кто напишет это DAL? Сам возьмётся?
    Тот программист, который занимается интеграцией с БД. Только не надо сказок, что его нет.

    Я прекрасно видел реальные проекты, в которых типА-чистА-крутой-DBA делает все в хранимых процедурах. Обычно кончалось тем, что разработка замедлялась до улиточной скорости из-за того, что DBA приходилось одновременно делать работу от 10 человек (типа: "А мне нужна смена пароля по секретному вопросу!!", "А пароль — case sensetive?" и "Когда же добавят поле 'домен'??").
  • Sapienti sat!
    Re[6]: Оформление работы с БД в корпоративных приложениях -
    От: adontz Грузия http://adontz.wordpress.com/
    Дата: 23.09.07 21:54
    Оценка: 1 (1) -4 :)
    Здравствуйте, kuj, Вы писали:

    A>>ИМХО ХП напротив проще поддерживать потому что:

    kuj>Вы когда-нибудь пытались поддерживать ХП? Я имею в виду более менее большие проекты, а не базы с парой десяткой табличек и 30-40 процедурами.

    Поддержкой ХП занимаются программисты БД. Я не такой. Они на моей памяти не жаловались. Мне с ХП работать на порядки проще, чем изучать потроха конкретной схемы.

    A>>
  • ХП пишет тот же, кто разработал схему БД, а значит ХП лучше учитывают наличие или отсутствие индексов. прикладной же программист вставляющий в свой код SQL запросы в лучшем случае прочитал названия таблиц и столбцов.
    kuj>В наше время все давно используют различные OR/M.

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

    kuj>Что чрезвычайно усложняет сопровождение такого проекта, т.к. ХП гораздо сложнее отлаживать и тестировать. О читабельности я вообще молчу.


    Извини, ты с ХП работал вообще?

    kuj>Потому и используют OR/M. Нету никаких таблиц. Нету никаких столбцов. Есть объекты DAL-уровня со свойствами. Есть соотвествующие объекты BLL уровня с бизнес логикой. Все связи минимальны благодаря IoC-контейнерам (Spring, Castle Windsor и т.п.). Код тщательно документируется. В наличии богатый IntelliSense инструментарий, фреймворки для тестирования типа nUnit с RhinoMocks, средства для автоматического создания документации, мощный отладчик, прекрасная читабельность кода, отсутствие привязки к конкретной БД и минимальная зависимость от схемы БД, высокая масштабируемость.


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

    Именно тот факт, что ORM являясь очень удобными средствами никак не контроллирующим разработчика и приводит к отказу от ORM в действительно крупных проектах. Когда знакомишься с Hiberbnate первая мысль это ВАУ, потом начинают закрадываться сомнения, а чуть позже задаёшь на форуме вопрос "А без HQL можно?" потому что учёт специфики схемы БД не локализован, а разбросан по проекту. Когда БД растёт вместе с проектом и эта специфика меняется начинаются странные падения производительности "хотя совсем недавно всё работало". Получаем мину замедленного действия. Единственное известно мне исключение — это BLT, но там просто функциональности недостаточно чтоб мины делать (хотя в том что BLT делает, она на высоте).

    A>>Кроме того, использование ХП позволяем автоматически тестировать самый низкоуровневый код работы с данными.

    kuj>Наоборот не позволяет автоматически тестировать. Нет, конечно можно писать тесты для тестирования хранимых процедур, но они редко могут быть полными.

    Смотря что делают хранимые процедуры. Конечно, если у тебя реализация вида 1запрос-1ХП, то пользы и от ХП мало и от их тестирования.

    A>>Зависимость от конкретной СУБД будет всегда. Дело даже не в синтаксических различиях диалектов SQL, а в разном объёме предоставляемой функциональности. Система не может быть независимой от СУБД на уровне DAL. Это ИМХО миф и утопия.

    kuj>Да? Какой кошмар...

    Если тебе не совсем плевать на производительность, то да. Ты писал приложение, которое должно работать на MSSQL И MySQL? Это очень разные СУБД с разными заскоками. То что бегало на одной, на другой показывало просто УЖАСНУЮ производительность. Например в MySQL нет типа GUID, и если пойти на поводу у лени и хранить GUID'ы в строках, то получим падение производительности в разы. Разбиение на 4 int работало на ура, но никакая ORM не смогла это отобразить, что впрочем и не удивительно.

    На самом деле нет никаких великих ORM и OODBMS. Есть реляционные БД со строгой математической теорией от которых никуда не деться именно в связи с огромной строгой математической теорией. Есть традиция ОО программирования от которйо тоже никуда не деться. а ещё есть маркетологи регулярно сулящие чему-нибудь смерть (RDBMS are dead, апплодисместы, хвала новым героям, бабки с Google AdSence ибо скандальное привлекает) и пытающиеся продать очередную серебрянную пулю. Нет ещё такого средства, которое бы эффективно отобразило хранящуюся в памяти объектную модель на данные в РСУБД без пинков и тычков. Когда надоедает пинать и тыкать, наступает просветление и просто делаешь всё руками. Ну или существенную часть.
  • A journey of a thousand miles must begin with a single step © Lau Tsu
    Re[8]: Оформление работы с БД в корпоративных приложениях -
    От: adontz Грузия http://adontz.wordpress.com/
    Дата: 23.09.07 22:11
    Оценка: -1 :)
    Здравствуйте, Cyberax, Вы писали:

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


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

    C>Жуть. У нас куча простых однострочных процедур ТОЛЬКО для одной простенькой сущности, даже без связей. Да еще и нет поддержки оптимистических блокировок.


    Эти операции тебе понадобятся в любом случае. Никаких лишних сущностей тут нет.

    C>
    C>public class User 
    C>{
    C>   private long id,version; //Вообще-то обычно они выделены в базовый класс
    C>   @Column(length=64)
    C>   private String firstName, lastName, login, password;
       
    C>   //Добавим еще для интереса аудит.
    C>   @Requisite(Role.SERVER)
    C>   private List<UserAuditRecord> auditRecords;
    
    C>   //getter'ы и setter'ы пропускаем по причине их тривиальности.
    C>}
    C>

    C>Усё.

    Круто, кто это напишет? Даю намёк, разработчик БД знает только SQL (во всяком случае ему не платят за написание DAL или каких-либо обёрток). Это ситуация в которой я работал не один раз, мне дают голую БД (справедливости ради надо заметить очень хорошо продуманную), над которой надо что-то строить сверху.

    C>Да, при открытии формы — начинаем бизнес-транзакцию с оптимистическим версированием, при коммите ее заканчиваем. Механизм работы с транзакциями в БД — отдаем на откуп middleware.


    Это совсем другая транзакция, не надо путать тёплое с мягким. Если например, надо статью из категории "Разное" перенести в категорию "Юмор", то разумно на уровне БД в виде ХП реализовать MoveArticle объединяющую DELETE И INSERT в транзакцию, чтобы статья не подвисла без категории (и не оказалась сразу в двух). А вот уже в бизнес-транзакции можешь объединить массовый перенос статей в нечто болеее высокоуровневое, но INSERT И DELETE должны быть объеденены на уровне БД.

    C>И я вообще слабо понимаю что ты понимаешь под "группировкой в транзакции".


    Да.

    C>Явный begin/commit из ХП? Так это вообще в морг.


    Здрасьте.

    C>Не перпендикулярно. Имея выделенный слой DAL и XP мы просто будем делать лишнюю работу. Скажем твой пример с пользователем можно точно так же сделать с помощью DAL'а в виде класса UserDAO, с которым и будет работать прикладной программист.

    C>Естественно, за работу с данными минуя DAL — бить ногами.

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

    A>>А кто напишет это DAL? Сам возьмётся?

    C>Тот программист, который занимается интеграцией с БД. Только не надо сказок, что его нет.

    Он есть, но это не тот, который разрабатывает БД. И интеграция с БД далеко не основная его работа. Будешь удивлён, но программистов используют согласно языкам, а не задачам. Задача простая — хранить данные, но разделена на две части: DAL на C++/C#/Java/etc. и DB на SQL. Делают их два разных человека, причём тот кто пишет DAL пишёт не только его и читать с утра до вечера хинты SQL'щика (которые то ещё должен написать) на тему "туда не ходи, сюда ходи" как правило достаточно утомительно. Гораздо эффективнее выдать интерфейс БД в виде ХП, которые сами всё расскажут о том как и что можно делать и не дадут сделать "не так".

    C>Я прекрасно видел реальные проекты, в которых типА-чистА-крутой-DBA делает все в хранимых процедурах. Обычно кончалось тем, что разработка замедлялась до улиточной скорости из-за того, что DBA приходилось одновременно делать работу от 10 человек (типа: "А мне нужна смена пароля по секретному вопросу!!", "А пароль — case sensetive?" и "Когда же добавят поле 'домен'??").


    Извини, это проблема написания ТЗ и управления разработкой, а не ХП Будет ли пароль case sensitive и будет ли смена пароля по секретному вопросу решается usability специалистами, а не разработчиком БД и уазывается в ТЗ. Остальные читают.
    Представь себе DAL для той же задачи хранящий всё в текстовых файлах (никаких ХП). Абсолютно та же ситуация наблюдалась бы. Это отсутствие чёткого ТЗ и только.
    A journey of a thousand miles must begin with a single step © Lau Tsu
    Re[9]: Оформление работы с БД в корпоративных приложениях -
    От: Cyberax Марс  
    Дата: 23.09.07 22:43
    Оценка: +2
    Здравствуйте, adontz, Вы писали:

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

    A>Потому что если есть возможность совершить ошибку, ты хоть миллион предупреждений повесь, всё равно найдётся дурак, который её совершит.
    В том числе и DBA в ХП, а эту ошибку потом будут долго отлаживать тупые прикладные пользователи, которые ни разу в жизни не написали ни одного запроса.

    C>>Жуть. У нас куча простых однострочных процедур ТОЛЬКО для одной простенькой сущности, даже без связей. Да еще и нет поддержки оптимистических блокировок.

    A>Эти операции тебе понадобятся в любом случае. Никаких лишних сущностей тут нет.
    Есть. Я могу выкинуть кучу ручного труда с помощью разных автоматических байндеров и валидаторов.

    [skip]
    C>>Усё.
    A>Круто, кто это напишет? Даю намёк, разработчик БД знает только SQL (во всяком случае ему не платят за написание DAL или каких-либо обёрток). Это ситуация в которой я работал не один раз, мне дают голую БД (справедливости ради надо заметить очень хорошо продуманную), над которой надо что-то строить сверху.
    Если DBA знает только SQL — то он не сможет понять ТЗ, написаное аналитиком. Так что возможны два варианта:
    1. Аналитик дает задание девелоперам, те рисуют черновую схему базы данных (я это делаю прямо в коде, из которого автоматически строится схема). Эта схема с комментариями отдается DBA, который ее оптимизирует (расставляет нужные индексы, ставит дополнительные проверки, может денормализует что-нибудь). Оптимизированая схема отдается обратно девелоперам, которые подправляют под нее код (обычно требуется править совсем немного).
    2. Аналитик дает задание DBA. DBA рисует схему и отдает ее программистам. Программисты по схеме строят DAL.

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

    C>>Да, при открытии формы — начинаем бизнес-транзакцию с оптимистическим версированием, при коммите ее заканчиваем. Механизм работы с транзакциями в БД — отдаем на откуп middleware.

    A>Это совсем другая транзакция, не надо путать тёплое с мягким. Если например, надо статью из категории "Разное" перенести в категорию "Юмор", то разумно на уровне БД в виде ХП реализовать MoveArticle объединяющую DELETE И INSERT в транзакцию, чтобы статья не подвисла без категории (и не оказалась сразу в двух). А вот уже в бизнес-транзакции можешь объединить массовый перенос статей в нечто болеее высокоуровневое, но INSERT И DELETE должны быть объеденены на уровне БД.
    Хороший пример. А если у нас нет операции MoveArticle? Как ты в случае БД

    C>>И я вообще слабо понимаю что ты понимаешь под "группировкой в транзакции".

    A>Да.
    C>>Явный begin/commit из ХП? Так это вообще в морг.
    A>Здрасьте.
    Досвиданья.

    C>>Естественно, за работу с данными минуя DAL — бить ногами.

    A>DAL и SQL пишут разные люди. Это не два раза одна и та же работа (хотя согласен, что ХП во многом посторяют DAL), это контракт вызова между разными модулями, написанными разными людьми.
    Процедуры DAL в виде selectByLogin/updatePassword замечательно пишут обычные программисты, точнее это все замечательно автоматизируется. Если их переложить на DBA — то он просто завязнет в куче мелких запросов (видел такое собственными глазами далеко не раз), да еще и проблемы с версированием БД начнутся.

    На откуп DBA остаются только оптимизации сложных запросов и всякие сложные операции, требующие временных таблиц, километровых запросов и кувырков с переворотами. Вот тут, кстати, ХП как раз вполне подходят.

    A>>>А кто напишет это DAL? Сам возьмётся?

    C>>Тот программист, который занимается интеграцией с БД. Только не надо сказок, что его нет.
    A>Он есть, но это не тот, который разрабатывает БД. И интеграция с БД далеко не основная его работа. Будешь удивлён, но программистов используют согласно языкам, а не задачам. Задача простая — хранить данные, но разделена на две части: DAL на C++/C#/Java/etc. и DB на SQL.
    Вот чувствую, что оба делают лишнюю работу.

    A>Делают их два разных человека, причём тот кто пишет DAL пишёт не только его и читать с утра до вечера хинты SQL'щика (которые то ещё должен написать) на тему "туда не ходи, сюда ходи" как правило достаточно утомительно. Гораздо эффективнее выдать интерфейс БД в виде ХП, которые сами всё расскажут о том как и что можно делать и не дадут сделать "не так".

    Вот ты мне привел пример с XP для операций с User'ом. Не вижу там ни одного нетривиального SQL-оператора, который не смогу написать бы даже студент. Зачем тогда заставлять высококвалифицированного DBA заниматься этой ерундой?

    C>>Я прекрасно видел реальные проекты, в которых типА-чистА-крутой-DBA делает все в хранимых процедурах. Обычно кончалось тем, что разработка замедлялась до улиточной скорости из-за того, что DBA приходилось одновременно делать работу от 10 человек (типа: "А мне нужна смена пароля по секретному вопросу!!", "А пароль — case sensetive?" и "Когда же добавят поле 'домен'??").

    A>Извини, это проблема написания ТЗ и управления разработкой, а не ХП Будет ли пароль case sensitive и будет ли смена пароля по секретному вопросу решается usability специалистами, а не разработчиком БД и уазывается в ТЗ. Остальные читают.
    Так решается. Вот в середине проекта юзабилист и решил — надо добавить возможность восстановления по секретному вопросу.

    A>Представь себе DAL для той же задачи хранящий всё в текстовых файлах (никаких ХП). Абсолютно та же ситуация наблюдалась бы. Это отсутствие чёткого ТЗ и только.

    Дело в том, что в таком случае программисты сами смогли бы добавить нужные вещи в DAL и в свои DB. А к DBA потом просто отправить изменения в схеме на review и оптимизацию.

    А если мы даем программистам писать/править свои ХП — то тогда они уже у нас скорее всего не полные идиоты, неспособные понять даже простого SQL UPDATE.
    Sapienti sat!
    Re[10]: Оформление работы с БД в корпоративных приложениях -
    От: adontz Грузия http://adontz.wordpress.com/
    Дата: 23.09.07 23:13
    Оценка: -2 :)
    Здравствуйте, Cyberax, Вы писали:

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

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

    Извини, мы не об опечатках. Я ни разу не видел, чтобы разработчик БД сам написал SELECT с кривым планом для БД разработанной им же. Он значит притворяется разработчиком БД если так.

    A>>Эти операции тебе понадобятся в любом случае. Никаких лишних сущностей тут нет.

    C>Есть. Я могу выкинуть кучу ручного труда с помощью разных автоматических байндеров и валидаторов.

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

    C>Если DBA знает только SQL — то он не сможет понять ТЗ, написаное аналитиком. Так что возможны два варианта:


    Вполне сможет, если оно написано на уровне Entity-Relations.

    C>1. Аналитик дает задание девелоперам, те рисуют черновую схему базы данных (я это делаю прямо в коде, из которого автоматически строится схема). Эта схема с комментариями отдается DBA, который ее оптимизирует (расставляет нужные индексы, ставит дополнительные проверки, может денормализует что-нибудь). Оптимизированая схема отдается обратно девелоперам, которые подправляют под нее код (обычно требуется править совсем немного).


    Это порочная практика. Рядовой разработчик никогда не сможет придумать действительно удачную схему хранения данных в БД. DBA должен плясать не от объектной модели, а от ER-диаграммы. В описанном тобой сценарии DAL скорее всего выродится, так как БД будет отображать иерархию объектов, а не хранимые данные. Подкрутить индексы и денормализовать чего-нибудь это далеко не самое главное в разработке схемы. Есть данные которые в реляционную модель, порой, просто не укладываются как есть и их надо преобразовывать до неузнаваемости.

    C>2. Аналитик дает задание DBA. DBA рисует схему и отдает ее программистам. Программисты по схеме строят DAL.


    Хороший сценарий, мой любимый. Я получаю качественный продукт от человека, не сбитого с толку чьими-то неуместными ОО-идеями.

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


    Нет, я всегда по мере возможности настаиваю чтобы БД разрабатывалась в первую очередь.

    A>>Это совсем другая транзакция, не надо путать тёплое с мягким. Если например, надо статью из категории "Разное" перенести в категорию "Юмор", то разумно на уровне БД в виде ХП реализовать MoveArticle объединяющую DELETE И INSERT в транзакцию, чтобы статья не подвисла без категории (и не оказалась сразу в двух). А вот уже в бизнес-транзакции можешь объединить массовый перенос статей в нечто болеее высокоуровневое, но INSERT И DELETE должны быть объеденены на уровне БД.

    C>Хороший пример. А если у нас нет операции MoveArticle? Как ты в случае БД

    Ты кажется не дописал вопрос. Во всяком случае он выглядит недописанным.

    C>Процедуры DAL в виде selectByLogin/updatePassword замечательно пишут обычные программисты, точнее это все замечательно автоматизируется. Если их переложить на DBA — то он просто завязнет в куче мелких запросов (видел такое собственными глазами далеко не раз), да еще и проблемы с версированием БД начнутся.


    ХЗ, у меня не завязают. Мои выносливее?

    C>На откуп DBA остаются только оптимизации сложных запросов и всякие сложные операции, требующие временных таблиц, километровых запросов и кувырков с переворотами. Вот тут, кстати, ХП как раз вполне подходят.


    Это DBA-лентяи какие-то. Напрограммил то, что было самому интересно, а на остальное плюнул, путь негры пашут Безответственно Почему именно — ниже (пометил знаком %).

    C>Вот ты мне привел пример с XP для операций с User'ом. Не вижу там ни одного нетривиального SQL-оператора, который не смогу написать бы даже студент. Зачем тогда заставлять высококвалифицированного DBA заниматься этой ерундой?


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

    C>А если мы даем программистам писать/править свои ХП — то тогда они уже у нас скорее всего не полные идиоты, неспособные понять даже простого SQL UPDATE.


    % (пометка, которую ты ждал)
    Проблема в том, что этот простой SQL UPDATE в деномализованной для чего-то там БД может разрушить целостность данных. DBA знает (помнит, записал, пометил для себя крестиком на пальце) что таблица денормализована и что обновив тут, надо ещё подкрутить там (кстати опять транзакция уровня БД, без неё никак). Рядовой программист этого не знает и может напортачить. А раз может, значит обязательно напортачит. Считай это законом Мерфи.

    DBA не тормозит разработку как ты пытаешь представить, он не злой дядя-тормозун. Просто изменения большой системы с сохраненим её согласованности это конечно же куда более сложный и длительный процесс, чем написание "с нуля" как надо. Да, добавить столбец в таблицу оставив все запросы целостными может оказатся не просто. Но пусть этим занимается один человек, а иначе будут "сюрпризы".
    A journey of a thousand miles must begin with a single step © Lau Tsu
    Re[7]: Оформление работы с БД в корпоративных приложениях -
    От: Aviator  
    Дата: 24.09.07 05:41
    Оценка: +1 :)
    Здравствуйте, adontz, Вы писали:
    Поддерживать код SQL проще? Не смешите мои тапочки. Если у вас сидит один монстр который с уцтра до вечера фигачит запросы и у которого в голове лежит вся схема базы со всеми хранимками, то я понимаю почему Вы так говорите. А теперь предположитеЮ, что проходят годы, код меняется, дописывается новый. В один прекрасный день происходит непредвиденная ситуация — Ваши монстры SQL уходят, а новым надо уйму времени, что бы осознать какие хранимки что делают и как внести изменение, не поломав что то в другом конце системы. Не говоря уж о том, что бизнес логика должна оперировать понятиями бизнес логиками а не "математическими основами БД". А уж если в один прекрасный день вам предложат мигрировать с MS SQL на Oracle то Вы совсем расстроитесь.
    Re[8]: Оформление работы с БД в корпоративных приложениях -
    От: ilvi Россия  
    Дата: 24.09.07 06:19
    Оценка: +1 -1
    Очень странно видеть такую полемику, напоминает религиозные войны программистов на билдере и визуал си. Одним удобно пользоваться неким конструктором, который от них "прячет" (упрощает — кому как нравится) некоторые вещи; другим приятнее сделать всю черновую работу самим и быть увереными, что они не потеряли в производительности и контролируют процесс. В данном случае одни привыкли при работе с базой пользоваться промежуточными автоматизироваными средствами и думают, что это лучший вариант потому что привыкли работать имено в этом русле, другие также привыкли работать через хранимки и считают это вполе нормальным, и работа у них построенна изходя из этой особенности. Если работа организована грамотно, то можно работать в соответсвии с обоими идеями. Если где-то есть просчеты, то в любом случае будут проблемы, какой путь невыбери.
    З.Ы.
    Странно видеть возглассы о том, что большую бд с кучей хранимок тяжело поддерживать... Хочется задать вопрос, а большой проект с кучей разнородных классов легко подерживать?
    Re[9]: Оформление работы с БД в корпоративных приложениях -
    От: Aviator  
    Дата: 24.09.07 07:44
    Оценка: +1 -1
    Здравствуйте, ilvi, Вы писали:

    I>Странно видеть возглассы о том, что большую бд с кучей хранимок тяжело поддерживать... Хочется задать вопрос, а большой проект с кучей разнородных классов легко подерживать?


    Код с классами подвергается чёткому структурированию и рефакторингу. Скрипты sql по своей природе плохочитаемы и не особо структурируются.
    Re: Оформление работы с БД в корпоративных приложениях - как
    От: Нахлобуч Великобритания https://hglabhq.com
    Дата: 24.09.07 07:47
    Оценка:
    Здравствуйте, Kazna4ey, Вы писали:

    K>1) Изменение схемы БД...


    Уже сказали. Либо ORM, либо еще что-то, но обязательно выделенный слой доступа к данным.

    K>2) Смена СУБД. No comments.


    Это все теория. На практике, например, перейти с SQL Server на Oracle довольно непросто.

    K>Вопрос в том какой метод наиболее эффективен и распространен при разработке корпоративных приложений среднего размера (под средним размером я понимаю пару десятков тысяч строк кода написанного вручную и БД из пары десятков таблиц)?


    Написание большой части таких запросов прекрасно автоматизируется.

    K>Если какое-то обращение к БД — единичное, т.е. запрос очень специфический и его вызов происходит только в одном месте программы, то я не отделяю его от кода формы, т.е. пишу его прямо в обработчике события или отдельным методом класса формы/контрола, например так:


    Обрывать руки

    K>Пока писал пример, возник попутный вопрос:

    K>Насколько нужно/ненужно использовать хранимые процедуры/функции?

    Лично мое ХО -- я в общем случае против.

    K>Если запрос или его модификация должен вызываться из нескольких мест в программе, то я его оформляю в виде статического метода в классе типа CommonFuncs:


    Класс CommonFuncs, я так понимаю, раздувается до совешенно неприличных объемов? Плохо. Статические методы тоже плохо. Хотя бы потому, что код, их использущий, очень тяжело тестировать.

    K>Если работа происходит с таблицей (всмысле гридом) обычно стараюсь работать через SelectCommand, UpdateCommand и т.д. класса SqlDataAdapter, типа так:


            strSQL = "SELECT blablabla FROM parts WHERE Customer = ?Customer AND OrderDebited = true AND " + 
            "OrderInvoiced = false AND IsScanned = ?IsScanned AND IsPacked = ?IsPacked ORDER BY ManufacturerID, PartN";


    Про запросы в коде см. пункт 1.
    ... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
    HgLab: Mercurial Server and Repository Management for Windows
    Подождите ...
    Wait...
    Пока на собственное сообщение не было ответов, его можно удалить.