Автор работы: Пользователь скрыл имя, 23 Сентября 2011 в 22:30, статья
Проблема «потери соответствия» (impedance mismatch) между языками программирования и системами баз данных обсуждается в сообществе баз данных на протяжении всей моей профессиональной жизни. Попытки решения этой проблемы породили направления языков программирования баз данных, объектно-ориентированных и, отчасти, объектно-реляционных баз данных.
В некоторых
языках, таких как C++ и C#, допускается
определение пользовательских типов
данных, которые соответствуют
Статическая типизация является распространенным средством, используемым для повышения надежности и производительности как в языках программирования, так и в базах данных. В языках программирования статическая типизация используется для проверки программ до их запуска – чтобы убедиться в том, что во время выполнения к данным будут применяться только допустимые операции. Статическая типизация может улучшать производительность, поскольку эти проверки можно не производить во время выполнения. Она также способствует модульным разработкам, поскольку клиенты и серверы могут писаться и проверяться на основе строго определенных интерфейсов. В базе данных обычно выполняется проверка запросов на предмет отсутствия ошибок типов до компиляции запросов.
Критерий статической
типизации отличается от критериев
отображения данных и интерпретации null-значений.
Это связано с тем, что статическая типизация
не является свойством данных; это свойство
системы, управляющей данными, и способ
интерпретации ею программ или запросов.
Таким образом, статическая типизация
является мета-аспектом, применимым к
другим критериям. Например, отображение
данных может производиться во время выполнения,
а может статически проверяться. В нашей
оценке статическая типизация является
дополнительным измерением оцен
Пространство
решений интеграции языков программирования
и баз данных можно охарактеризовать
двумя экстремумами: ортогональ
void printInfo(String prefix) {
for (Employee e in db.allEmployees() )
if ( e.name.startsWith(prefix) && e.salary > e.manager.salary ) {
print( e.name );
print( e.salary );
print( e.department.name );
}
}
Рис. 2. Печать информации о служащих
Ортогональная
персистентность является естественным
расширением традиционного
Программы, манипулирующие персистентными данными, выглядят подобно обычным программам. В предположении, что db является корнем персистентности, содержащим коллекцию служащих, в примере на рис. 2 находятся все служащие, фамилии которых начинаются с заданного префикса, и зарплата которых превышает зарплату их менеджера. Затем печатаются фамилия служащего, его заработная плата и название отдела.
К числу примеров
систем с ортогональной
В большинстве
объектно-ориентированных баз
Основной альтернативой ортогональной персистемности и ее историческим предшественником является выполнение запросов, написанных на специализированном языке запросов. Основным преимуществом явного выполнения запросов является то, что программист имеет возможность непосредственного взаимодействия с сервером базы данных.
string empQuery = “SELECT e.name, e.salary, d.name as deptName”
+ “FROM (Employee e INNER JOIN Department d ON d.ID = e.department)”
+ “INNER JOIN Employee m ON m.ID = e.manager”
+ “WHERE e.name LIKE ? AND e.salary > m.salary”
Connection conn = DriverManager.getConnection(..
PreparedStatement stmt = con.prepareStatement(empQuery)
stmt.setString(1, prefix + “%”);
ResultSet rs = stmt.executeQuery(empQuery);
while ( rs.next() ) {
print( rs.getString(“name”) );
print( rs.getDecimal(“salary”) );
print( rs.getString(“deptName”) );
}
Рис. 3. Явное выполнение запроса с использованием JDBC
Встраиваемые запросы. Явные запросы могут встраиваться в язык программирования или обрабатываться препроцессором [27]. К числу примеров относится SQLJ [8]. Встраиваемый SQL обеспечивает статически типизированный подход к явному выполнению запросов. Как обсуждается в разд. 7, одним из существенных недостатков встраивания является отсутствие поддержки динамических запросов. Другой проблемой является то, что изменение синтаксиса языка программирования обычно приводит к нарушению работы средств рефакторинга, интегрированных сред разработки (Integrated Development Environment, IDE) и CASE-средств.
Интерфейсы уровня вызова. Доминирующим механизмом явного выполнения запросов являетсяинтерфейс уровня вызовов (call level interface, CLI) [28], обеспечивающий языку программирования доступ к серверу баз данных на основе стандартизованного API [28, 24]. Ключевой характеристикой CLI является возможность выполнения запросов и команд базы данных, представленных в виде строк или других структур данных времени выполнения [26]. На рис. 3 показано, как запрос с рис. 2 может быть выполнен с использованием JDBC [24].
В большинстве
систем с ортогональной
Интерфейсам уровня
вызовов свойственен ряд
Несмотря на наличие этих проблем, во многих проектах по разработке коммерческого программного обеспечения используются интерфейсы уровня вызова для эффективного использования оптимизаторов запросов баз данных и сокращения коммуникационных задержек с целью повышения общей производительности системы.
Для приложений, работающих с большими объемами данных, важно оптимизировать доступ к данным. Адекватная стратегия выполнения запроса часто может оказаться на несколько порядков быстрее прямолинейной стратегии [41].
В примерах этого раздела представлены распространенные оптимизации запросов, но с точки зрения языка программирования. Для обеспечения более глубокого анализа решений мы разделяем понятияпоиска и навигации. Это приблизительно соответствует разделам WHERE и SELECT в языке SQL: поиск относится к выбору подмножества интересующих пользователя объектов, а навигация используется для обработки результатов поиска. Это различие является важным, поскольку во многих решениях одно из этих понятий поддерживается лучше другого.
Первой проблемой является оптимизация поиска. В простой программе, показанной на рис. 1, тратится время, пропорциональной числу служащих, хотя лишь для немногих из них фамилия будет начинаться с заданного префикса. Для улучшения этого алгоритма могут применяться традиционные методы оптимизации баз данных, основанные на использовании индекса. Это может существенно сократить время выполнение, которое станет пропорциональным числу служащих с фамилиями, соответствующими первому условию.
Явные индексы (P1). Распространенным методом является изменение порядка подопераций, таких как итерирование и проверка условия. Так, оптимизатор запросов может использовать индекс для вычисления множества идентификаторов записей, удовлетворяющих условию, а затем найти соответствующие данные путем поиска этих идентификаторов во втором индексе. Этот аспект плана иллюстрируется на рис. 4, где эта оптимизация применяется к исходному Java-коду.
Проверка префикса реализуется путем поиска по индексу: метод match возвращает итератор над множеством элементов индекса, соответствующих первому условию. Затем для нахождения данных о служащих используется эффективный индекс, отображающий идентификаторы записей в значения записей. Если большинство фамилий не начинается с заданного префикса, этот метод будет гораздо эффективнее линейного поиска. Явное программирование с использованием индексов поддерживается в Exodus [13] и Ontos [40].
void printInfo(String prefix) {
for (IndexItem l in employeeNameIndex.match(“S”)) {
Employee e = employeeID_Index.lookup(l.ID);
if
(e.salary > managerID_Index.lookup(e.
print( e.name );
print( e.salary );
Department d = departmentID_Index.lookup(e.
print( d.name );
}
}
}
Рис. 4. Оптимизированная выдача на печать информации о служащих
Если такие оптимизации должны выполняться вручную, производительность программиста существенно понижается, поскольку даже при незначительном изменении исходного неоптимизированного кода, например, при добавлении в оператор if дополнительного условия, может потребоваться значительное переписывание оптимизированного кода.
Информация о работе Интеграция языков программирования с базами данных: в чем состоит проблема?