четверг, 14 января 2010 г.

Существующие решения систем управления данными в формате XML – Часть1

1. Microsoft SQL Server

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

Microsoft SQL Server 2005 представляет собой платформу обработки данных, построенную вокруг ядра, обеспечивающего функциональность реляционной базы данных, а также большого набора сервисов, расширяющих эту функциональность. Ниже приведена схема платформы данных SQL Server 2005:

clip_image002[6]

Рисунок 1. Структура платформы данных SQL Server 2005

В SQL Server 2005 добавлены два новых компонента: SQL Server Management Studio (набор инструментов управления базами данных) и SQL Server Business Intelligence Development Studio (набор инструментов разработки приложений интеллектуальной обработки данных). Другие основные компоненты интеллектуальной обработки данных - Integration Services, Analysis Services OLAP, Analysis Services Data Mining и Reporting Services - в SQL Server 2005 значительно изменены и улучшены.

2. Реляционное хранилище данных

Ядро реляционной базы данных обеспечивает безопасные, надежные, масштабируемые, высокодоступные операции над реляционными данными и позволяет работать как со структурированными, так и с неструктурированными XML-данными. Ядро базы данных обеспечивает поддержку .NET CLR (возможность создания хранимых процедур, функций и триггеров на управляемом коде, а также определяемых пользователем типов и агрегатных функций) и расширений ADO.

Реляционное ядро БД хранит подробные записи о транзакциях, генерируемых системами оперативной обработки транзакций (online transaction processing (OLTP) systems), а также осуществляет оперативную аналитическую обработку данных (online analytical processing, OLAP) по запросу специализированных хранилищ данных. Реляционное ядро БД обеспечивает достоверность и защиту хранимых данных, отказоустойчивость, динамически оптимизирует производительность, а также налагает блокировки для реализации параллелизма.

Ядро реляционной базы данных SQL Server 2005 включает несколько интересных возможностей для создания и поддержки различных приложений с хранилищами данных.

Эти возможности включают:

  • Табличные секции, обеспечивающие быструю загрузку данных и упрощенную поддержку очень больших таблиц.
  • Простое создание сервера отчетности
  • Улучшения в Transact-SQL, включая новые типы данных и новые аналитические функции
  • Выполнение онлайновых операций над индексами
  • Гранулированные операции резервного копирования/восстановления
  • Быстрая инициализация файлов
3. SQL Server: поддержка XML

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

В SQL Server 2005 для решения подобных проблем был реализован новый внутренний тип данных. SQL Server 2000 позволяет хранить XML на сервере в виде текста в поле BLOB (Binary Large Objects – бинарные большие объекты), поэтому нет возможности работать с XML или ссылаться на XML на сервере. Для того чтобы работать с данными XML, мы должны были бы извлечь его на уровень приложения, затем воспользоваться стандартным анализатором XML или Document Object Model (DOM) - программным объектом для обработки документов XML. Microsoft SQL Server 2005 предоставляет принципиально новый подход к использованию XML. Введен новый тип данных XML. В этом типе используются методы query (), exist (), value (), nodes () и modify (), которые представляют собой подмножество спецификации XML Query (XQuery). XML-документ перестал быть чем-то неделимым. Благодаря новому типу данных механизм SQL Server понимает данные XML точно так же, как он понимает целые числа или строковые данные. Тип данных XML позволяет создавать как таблицы, которые хранят только XML, так и таблицы, которые хранят и XML, и реляционные данные. Эта гибкость позволяет получить максимальную отдачу от реляционной модели для структурированных данных и пополнить эти данные полуструктурированными данными XML.

Чтобы извлечь максимальную пользу из этой комбинации полуструктурированных и реляционных данных, внутренний тип данных SQL Server 2005 XML поддерживает несколько встроенных методов, позволяющих запрашивать и модифицировать данные XML. Эти методы воспринимают Xquery, новый стандартный язык консорциума World Wide Web Consortium (W3C), а также навигационный язык XPath 2.0 и язык модификации данных XML. Язык запросов XML, или XQuery, является развитым и гибким языком запросов над всеми типами данных XML. Он разрабатывался именно как язык запросов для иерархической среды XML и обеспечивает оптимальный поиск в такой среде. В языке манипуляции XML DML SQL Server 2005 XQuery расширен возможностями внесения изменения в данные. При этом учитываются все особенности XML, в частности, возможность использования схемы документа. Имеется возможность комбинировать запросы к методам типа данных XML со стандартным T-SQL, создавая запросы, которые возвращают и реляционные данные, и данные XML.

Для поддержки типа данных XML были добавлены ключевые слова для регистрации и управления схемами XML. Центральные инструменты для работы с XML, FOR XML и OPENXML расширены поддержкой типа данных XML, что позволяет делать запросы к части XML-документа и проверять, что документ соответствует схеме XML. Для большей структурированности или целостности XML-данных SQL Server позволяет связывать схему с конкретным столбцом XML. Если некоторая схема XML связана с некоторым столбцом XML, схема проверяет, правильно ли данные XML вставлены в поле. Но SQL Server 2005 поддерживает несколько схем, сгруппированных в коллекцию, что позволяет применять к столбцу XML разные схемы. Сервер будет проверять правильность всех входящих данных XML по всем схемам. Если XML верен с точки зрения любой из схем коллекции, он может быть сохранен в поле XML.

Для улучшения производительности при наличии XML SQL Server 2005 позволяет создавать индексы по данным XML. Эти индексы работают так же, как стандартные индексы SQL Server и могут существенно увеличить производительность системы во время работы с XML-данными.

Внутренний тип данных XML в SQL Server 2005 позволяет создавать более качественные модели данных, имеющих структуру естественного происхождения. В реальной жизни никакой определенности нет; но сегодня, благодаря комбинированию XML и реляционных данных, мы имеем возможность учесть эту неизбежную неопределенность, что позволит системам более чутко реагировать на изменения и продлит их жизненный цикл. Теперь с содержимым XML-документа можно работать непосредственно, обращаясь к нему по правилам работы с XML-документом, выполнять поиск информации по правилам Xquery и, при этом, пользоваться всей мощью системы индексации SQL Server.

4. Перевод с реляционного языка в XML и наоборот

Реляционный язык – это язык кортежей (неупорядоченных множеств пар «ИмяРеквизита-ЗначениеРеквизита») и отношений (неупорядоченных множеств кортежей, имеющих одинаковый набор имен реквизитов). Внешним представлением сообщений на реляционном языке является набор двухмерных таблиц. Конкретное приложение, работающее с реляционными базами данных, делает разметку отношений, кортежей и значений в таблицы, строки (записи) и клетки (поля) и придает им некоторый внешний вид, обычно по опциональному выбору пользователя.

Внешним представлением сообщений на языке XML является набор реальных документов (и электронных, и бумажных), визуализация которых происходит при помощи универсального браузера (например, Internet Explorer 5) на основании XSL и CSS.

Перевод сообщений с реляционного языка на XML синтаксически не однозначен. Для иллюстрации рассмотрим простой пример, состоящий из 3 отношений, 5 реквизитов и 5 кортежей

clip_image003

Рисунок 2. Пример реляционных данных

В простейшем и наиболее компактном варианте получается следующая конструкция (вариант 1):

<DataBase>

<Tab1 A=”a1” C=”c1”/>

<Tab2 B=”b1” D=”d1”/>

<Tab2 B=”b2” D=”d2”/>

<Tab3 A=”a1” B=”b1” E=”e1”/>

<Tab3 A=”a1” B=”b2” E=”e2”/>

</DataBase>

Ее недостатком является неоднородность представления кортежей и значений, что, например, осложняет отображение расширенных реляционных моделей. Если значения оформлять также в виде тегов, то получим следующее (вариант 2):

<DataBase>

<Tab1><A>a1</A><C>c1</C></Tab1>

<Tab2><B>b1</B><D>d1</D></Tab2>

<Tab2><B>b2</B><D>d2</D></Tab2>

<Tab3><A>a1</A><B>b1</B><E>e1</E></Tab3>

<Tab3><A>a1</A><B>b2</B><E>e2</E></Tab3>

</DataBase>

Оба варианта используют двухуровневую вложенность XML-узлов, с помощью которой устанавливаются направленные связи кортеж-значение.

Направленные связи от записей Tab1 к записям Tab3 и от записей Tab2 к записям Tab3 (Tab3 обычно называют таблицей-связкой для реализации связей типа «многие-ко-многим») указываются одинаковыми значениями ключевых реквизитов A и B. В языке XML связи обычно указываются явно путем вложения тегов друг в друга и путем применения ссылок. Это позволяет в нашем примере убрать ссылочные ключи в Tab3 и установить ссылки на одного родителя путем вложения тега Tab3 в Tab2 и на второго родителя (Tab1) с помощью атрибутов Id и Ref (вариант 3):

<DataBase>

<Tab1 Id=”#1”>

<A>a1</A>

<C>c1</C>

</Tab1>

<Tab2>

<B>b1</B>

<D>d1</D>

<Tab3 Ref1=”#1”>

<E>e1</E></Tab3>

</Tab2>

<Tab2>

<B>b2</B>

<D>d2</D>

<Tab3 Ref1=”#1”>

<E>e2</E></Tab3>

</Tab2>

</DataBase>

Для того чтобы выполнить обратную операцию – привести произвольные XML-данные к реляционным – в первую очередь их необходимо преобразовать к одному из описанных выше вариантов. Для примера возьмем вариант 3.

1. Для каждого тега (в общем виде) вынесем все атрибуты, кроме Id и Ref, и все фрагменты текста в отдельные вложенные теги. Получится следующая структура:

<ИмяУзла Id=”Указатель” Ref1=”Указатель” Ref2=”Указатель”...>

<ИмяАтр1> Значение </ИмяАтр1>

<ИмяАтр2> Значение </ИмяАтр2>...

<ИмяТекста1> Только текст </ИмяТекста1>

<ИмяТекста2> Только текст </ИмяТекста2>

... Только вложенные теги

</ИмяУзла>

2. Реляционные данные хранятся в неупорядоченном виде, а данные XML в упорядоченном. Если в порядке следования атрибутов, фрагментов текста и вложенных тегов заложен смысл, то его, возможно, следует сохранить путем добавления к этой структуре специального вложенного тега, содержащего эту информацию.

3. Узлы предпоследнего уровня иерархии, которым соответствуют кортежи, не могут содержать одноименные вложенные теги – эта ситуация должна быть преобразована. Грубо говоря, в реляционной таблице клетка не может быть разделена на части. Кроме того, если она и может быть пустой, то уж никак не может отсутствовать. Поэтому, необходимо учесть разницу между отсутствующим и пустым тегом последнего уровня.

4. Узлы последнего уровня иерархии, которым соответствуют значения реквизитов, не могут содержать ссылочных атрибутов Id и Ref, так как в реляционных данных связи по ключам существуют только на уровне кортежей.

Преобразование варианта 3 в вариант 2 происходит путем включения ключевых тегов, в качестве которых, в общем случае, удобно использовать суррогатные ключи.

Как видно из рассмотренного примера, если данные размещать как текст и «размечать» их именами тегов, а атрибуты использовать только для ссылок, то получается весьма однородная структура, синтаксически несколько более широкая, чем реляционная.

Как писать unit-тесты для тестирования DAL

Unit-тесты для тестирования DAL (которые в свою очередь чаще работают с наборами данных типа DataSet чем с ДатаРидерамиJ ) – применяются …. Редко. Чаще с помощью unit-тестов тестируются пригодные для тестирования классы бизнес-логики. Все остальное, в т.ч. DAL и даже пользовательский интерфейс протестировать можно, но требует как некоторых дополнительных усилий на стороне тестов, так и разработки с учетом возможности последующего Unit-тестирования. ( Testability).

При разработки юнит-тестов важно чтобы код выполняющий тестирование был много надежнее (а следовательно и много проще) кода под тестом. Иначе вряд ли гаечным ключом получится огранить алмаз. :)

В данном случае нужно:

Проводить тесты на предсказуемом наборе данных. Т.е. каждый [Setup] / [Teardown] база должна переходить в одно заранее известное состояние. Т.е содержать известный заранее набор данных.

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

Удобнее всего было бы написать что-то типа

DBAssert(“имяБазы.Табличка.Колонка”, “id = 2”, 1500); - т.е. воспользоваться готовым плагином к NUnit умеющим самостоятельно зачитывать данные из базы.

К сожалению я пока не слышала чтобы кто-то спортировал такую вещь и под .Net / NUnit. Можно посмотреть на www.nuinit.org / www.sf.net– если такая библиотечка уже доступна, соответственно используйте.

Если нет – то у нас два варианта. Один из них идейно неверен, другой имеет явно избыточную трудоемкость. Хотя именно второй вариант правилен по правилам.

1. Использовать наши же методы, нашего же компонента которые возвращают значения из базы если такие есть. Плюсы – не надо писать дополнительного кода. Минусы – необходимо НЕЗАВИСИМО проверять каждый метод компонента. Иначе ошибка в методе вытаскивающем данные – повлияет на результаты проверки метода меняющего данные. Юнит тесты ( в идеале :) настраиваются выполняться автоматически, предположим каждую ночь, а результаты их работы (т.е найденные ошибки) получают все члены команды с утра( в идеале – девелопер ответственный за этот метод + Лид только). Потому ложные срабатывания unit-тестов это плохо. Кроме того, ошибка в методе получения информации может так (не)удачно дополнять ошибку в методе изменения, что вы получаете ‘положительный’ результат ‘проверки’ - что явно не есть хорошо.

2. Создать код в юнит-тесте (используя ADO.NET) который обращался бы в базу и сравнивал бы значения. Если он получится хорошим/надежным можно и стоит его выделить в библиотечку которую так всем не хватает. По сравнению с готовой ИСКОМОЙ библиотекой – ваша явно будет менее оттестирована. Т.е. сама utilitu библиотека может содержать ошибки, потому лучше найти готовую и поддерживаемую.

Конкретно по Нашему вопросу: для проверки функции возвращающей набор данных, нам (в идеале ) нужно некое дополнение к NUnit умеющее сравнивать набор данных полученных из метода с какими то предопределенными значениями (предположим в текстовом файле). Почему готовая (поддерживаемая/проверенная) библиотека – смотри выше. Если ее нет – можно или написать самостоятельно ( оцените трудоемкость - или просто захардкодить проверки в тест.

Можно посмотреть еще, что такое http://en.wikipedia.org/wiki/Mock_Object,

но в данном случае нам это НЕ подойдет, т.к. такие объекты используются как раз вместо DAL, который мы как раз в нашей задаче должны разработать и протестировать.

ЗЫ Unit-test это суть СКРИПТ понятный как кодеру теста так и разработчику теста. Разработчик теста НЕ обязан быть программистом. Его ключевое умение – определить необходимый и достаточный в данном случае набор тестов. Потому:

А) комментарии что же мы проверяем – над каждым тестом

Б) сам код теста – простая проверка с захардкоденными значениями, что-то из серии

Assert(MyComponent.Sum(2,2), 4) // Просто хардкоднная проверка что 2+2 = 4 .. без попытки написать что-то сложное

В) все проверки выполняются над системой в известном состоянии. Не следует предполагать что предыдущий тест перевел систему в нужное состояние. Надо гарантировать нахождение системы в подходящем состоянии ( [Setup] , [Teardown] )

Г) Ложное срабатывание теста это ПЛОХО. Как и ложное несрабатывание естественно ;-) Потому обратите внимание, красным должен быть тест если тестируемый метод содержит ошибку, но ЖЕЛТЫМ если тест просто не удалось провести.

Д) Исключения: Иногда с помощью unit-тест делают SmokeTest – суть которого хаотичный или лучше сложно навернутый перебор комбинаций данных, именно с целью найти ошибку случайными данными. Это отдельная задача.

Варианты:

1. Можно в тесте тоже создать datreader, читать те же данные, и сравнивать. Но тогда тест и функция выполняют одинаковые действия и смысл проверки теряется.

Не факт. Если второй datreader гарантированно читает данные правильно ( например проверено применением некого гипотетического DBNetUnit ) сотнями разработчиков – то таким точным протестированным инструментом легко найти ошибки в компоненте. Если же такого инструмента нет – то все равно вероятность ошибки и в коде будет существенно меньше, чем только в коде. Но как Вы правильно заметили увеличение трудоемкости в двое – при не 100%-ном результате оправдано далеко не всегда. Но бывает и оправдано:

http://www.n-admin.com/n37-871.html

2.Забить в тест как бы наперед известные данные и сравнивать с возвращаемыми. Но тогда, если значения в базе изменятся, проверка не пройдет.

В базе должны быть точно известные значения. Тест происходит на эталонной базе. Если эталонная база содержит ерунду вместо ожидаемых тестов - проблемы специалиста по автоматизации и конфигурированию тестов. Разработчик тестов пишет их в уверенности в корректности базы – и этим не парится :)

Есть ли еще какие-нибудь варианты?

среда, 13 января 2010 г.

10 вопросов на понимание ADO.NET

1)Что такое Dataset и зачем он нужен, а в каких случаях его использовать нецелесообразно?

Объект поддерживает копии записей из базы данных без соединения. Он сохраняет записи из таблицы (или множества таблиц) в памяти, не поддерживая постоянного соединения с сервером.

DataSet потребляет больше памяти, чем DataReader, поэтому если памяти недостаточно, то лучше использовать DataReader. DayaReader работает быстрее с одним пользователем, но если база многопользовательская, то в совокупности получиться медленнее из-за открытого соединения, и лучше тогда использовать DataSet. Если нам не нужнавозможность записи изменений в находящийся в памяти кэш, и не нужен индексированный доступ к произвольной строке в произвольный момент времени и между чтениями строк не будет слишком много длительных вычислений – тогда целесообразнее использовать DataReader, он даст прирост в производительности.

2)В каких случаях Вы будете использовать DataReader, в каких DataSet?

Объект DataSet используется для выполнения следующих действий.

  • Удаленное взаимодействие уровней и веб-служб XML.
  • Динамическое взаимодействие с данными, например связывание с элементом управления форм Windows Forms или сочетание данных из нескольких источников.
  • Локальное кэширование данных приложения.
  • Иерархическое XML-представление реляционных данных, например XSL-преобразования или язык XML-путей.
  • Расширенная обработка данных после отключения от источника данных.

Если функциональность объекта DataSet не используется в приложении, можно повысить производительность, включив вместо него в приложение объект DataReader, получающий данные в режиме чтения.

3)Что такое Typed Dataset, достоинства и недостатки?

Достоинства:

  • Читаемость кода. Для обращения к таблицам и полям типизированного DataSet можно использовать типизированные методы и свойства
  • Проверка типов при компиляции. Неправильные имена таблиц и полей обнаруживаются на этапе компиляции, а не выполнения.

Недостатки:

  • Проблемы расширения. Если схема базы данных изменена, то, возможно, для поддержки новой схемы потребуется заново генерировать типизированный класс DataSet. При повторной генерации может понадобиться внесение изменений в любой специализированный код, содержащийся в типизированном DataSet. Сборку, содержащую типизированный DataSet, придется заново развертывать во всех клиентских приложениях.
  • Создание экземпляров. Создать экземпляр типа оператором new нельзя.
  • Наследование. Ваш типизированный DataSet наследуется от базового DataSet, что не позволяет использовать другие базовые классы.

4)Что такое Disconnected модель доступа к данным?

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

5)Что такое DiffGramm, для чего применяется?

DiffGramm-документ содержит всю информацию о данных объекта DataSet , включая первоначальное и текущее значение строк. Эти сведения можно использовать для проведения слияния объектов Dataset или обновления базы данных.

Для идентификации изменений в DataSet существует метод GetChanges, который предоставляет удобный способ выборки изменений в виде DataSet или

DataTable той же структуры, что и исходный DataSet или DataTable. Однако ADO.NET

предоставляет еще один удобный механизм четкой идентификации изменений в DataSet или

DataTable с помощью средства diffgram.

Diffgram — это всего лишь XML-представление автономного кэша с узлом, который четко

идентифицирует выполненные изменения. Когда изменения извлечены в виде мини-объекта DataSet той же структуры, что и исходный DataSet, можно использовать второй метод — Merge — чтобы занести эти изменения в находящийся в другом месте существующий DataSet.

6)Как отобразить в DataGrid лишь те записи DataTable1, которые были изменены(Modified) и значение поля ID которых меньше 20? Приведите фрагмент кода.

dataSet1 = testDataSet.GetChanges();if (dataSet1 == null) return;this.bindingSource1.DataSource = this.dataSet1;

this.bindingSource1.DataMember = "Animals";

dataGridView1.DataSource = bindingSource1;

dataGridView1.Refresh();

7) Что такое отношение Многие ко Многим? Как реализовать такое отношение в БазеДанных. Как реализовать это отношение в DataSet?

Такое отношение между двумя сущностями реализуется через таблицу - связку.
create table Items1(Item1ID int not null, ... , primary key Item1ID);
create table Items2(Item2ID int not null, ... , primary key Item2ID);
create table ItemLinks(Item1ID int not null, Item2ID int not null, ... , primary key (Item1ID, Item2ID));
впрочем, последнего primary key может и не быть - в случае если конкретные Item1 и Item2 могут быть связаны больше одного раза. Вообще, для полноты картины следовало бы в create table ItemLinks добавить
foreign key (Item1ID) references Items1(Item1ID),
foreign key (Item2ID) references Items2(Item2ID)

8) В чем разница между методами AcceptChanges и Update? Какой из них надо использовать в каком случае?

Метод UpDate позволяет передать в хранилище данных отложенные изменения, хранящиеся в объекте DataTable или DataSet.

Метод AcceptChanges Сохраняет все изменения, внесенные в класс DataSet после его загрузки или после последнего вызова метода AcceptChanges. Классы DataRow и DataTable также содержат методы AcceptChanges. Вызов метода AcceptChanges на уровне объекта DataTable приводит к вызову метода AcceptChanges для каждого объекта DataRow. Аналогично, вызов метода AcceptChanges для класса DataSet приводит к вызову метода AcceptChanges для каждой таблицы внутри класса DataSet. Таким образом существует несколько уровней, на каждом из которых можно вызвать этот метод. Если метод AcceptChanges вызван для класса DataSet, то его можно также вызвать для всех объектов низшего уровня (например таблицы и строки) одновременно.

Вызов метода AcceptChanges для класса DataSet завершает изменение любого объекта DataRow, находящегося в режиме изменения. Свойство RowState каждого объекта DataRow также изменяется: строки с типами Added и Modified получают тип Unchanged; строки с типом Deleted удаляются.

9) Опишите жизненный цикл DataRow: нарисуйте граф состояний, обьясните что означает то или иноне состояние.

(если это проще, то можно не рисовать, а описать словами)

Значение Detached означает, что запись не относится к объекту DataTable. После добавления ее статус изменяется на Added - теперь она существует в объекте DataTable, но ее нет в базе данных. Конечно, здесь мы не рассматривали взаимодействие с источником записей, но это же значение будет у записей, добавляемых в DataGrid после вывода данных из базы при наличии подключения. Вызывая метод AcceptChanges объекта DataTable, мы принимаем все изменения, поэтому статус DataRow изменяется на Unchanged - теперь запись считается "своей", она не была изменена после вызова метода. После вызова метода Delete запись помечается удаленной - она еще не полностью удалена, в случае отмены изменений статус будет восстановлен. Действительно, вызывая метод RejectChanges объекта DataTable, мы восстанавливаем запись до состояния Unchanged.

10) Для чего предназначен DataView?

Объекты – представители класса DataView НЕ ПРЕДНАЗНАЧЕНЫ для организации визуализации объектов DataTable.

Их назначение – простой последовательный доступ к строкам таблицы. Объекты DataView являются средством перебора записей таблицы. При обращении ЧЕРЕЗ объект DataView к таблице получают данные, которые хранятся в этой таблице.

DataView нельзя рассматривать как таблицу. DataView не может обеспечить представление таблиц. Также DataView не может обеспечить исключения и добавления столбцов. Таким образом, DataView НЕ является средством преобразования исходной информации, зафиксированной в таблице.

10 базовых вопросов по MS SQL Server

1. Какой командой (short cut) можно вызвать помощь HELP по синтаксису оператора SQL в Query Analyzer?

Выделить оператор и нажать Shift+F1

2. Как в Query Analyzer в открытом файле скрипта выполнить только часть последовательных команд?

Выделить нужные команды и нажать F5 или кнопку кнопку Execute Query.

3. После написания процедуры выяснилось, что она работает неправильно. Какие есть средства для устранения ошибок в работе процедуры?

Для обработки ошибок, возникающих во время исполнения процедур, используются коды возврата и функция @@ERROR.

1).Обработка пользовательских ошибок.

С помошью оператора RETURN можно вернуть значения для обработки ошибок.

Пример:

ALTER PROCEDURE exampleProc

AS

.....

IF(....проверка на возможность ошибки...)

RETURN(1)

ELSE

.....выполняем действия хранимой процедуры...

При вызове процедуры:

-- Добавляем переменную для хранения результирующего кода

DECLARE @r_code int

-- Запускаем процедуру и устанавливаем @r_code равной результату процедуры

EXECUTE @r_code = exampleProc

--Определяем значение @r_code и исполняем программу

IF @r_code = 0

.....

ELSE IF @r_code = 1

PRINT 'Ошибка номер ' + CONVERT(varchar(1),@r_code)

GO

2).Ошибки базы данных

При возникновении ошибки функция @@ERROR возвращает номер ошибки отличный от нуля.

Номера и описания ошибок хранятся в таблице master.dbo.sysmessages.

4. Что такое уровень изоляции транзакций и в каких случаях его надо регулировать для SQL Server?

Уровень, на котором транзакция готова к приёму несогласованных данных, называется уровнем изоляции. Уровень изоляции определяет степень изоляции одной транзакции

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

выполнения, но за это приходится расплачиваться согласованностью данных. Напротив,

более высокий уровень изоляции гарантирует согласованность данных, но при этом стра-

дает параллельное выполнение.

SQL Server поддерживает все четыре уровня изоляции:

READ UNCOMMITED – незавершенное чтение, или допустимо черновое чтение. По сути, для транзакции не устанавливается никакой блокировки, которая гарантировала бы целостность данных.

READ COMMITTED – завершенное чтение, при котором отсутствует черновое, "грязное" чтение.

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

REPEATABLE READ – повторяющееся чтение. Повторное чтение строки возвратит первоначально считанные данные, несмотря на любые обновления, произведенные другими пользователями до завершения транзакции.

SERIALIZABLE – сериализуемость. Чтение запрещено до завершения транзакции.

5. Что такое нормализация базы данных? Для чего это нужно и есть ли какие качественные характеристки нормализации?

Нормализация логической структуры базы данных осуществляется с использованием формальных методов разделения данных между несколькими связанными таблицами. Основные: в таблице должен быть идентификатор; в ней должны храниться сведения, относящиеся лишь к одному типу объектов; следует избегать столбцов, допускающих пустые значения; в таблице не должно быть повторяющихся значений или столбцов.

6. В T-SQL есть возможность написания запроса по результатам другого запроса, который упоминается в конструкции FROM. Продемонстрировать как это можно сделать. Для демонстрации использовать таблицу из базы Northwind.

Из всех продуктов выбираем названия напитков(ID=1) поставщика Exotic Liquids(ID=1) .

SELECT Beverages.ProductName

FROM (SELECT ProductName,SupplierID FROM Products

WHERE CategoryID=1) as Beverages

WHERE Beverages.SupplierID = 1;

7.1 Написать запрос при помощи оператора SELECT, который блокирует таблицу на чтение.
Для демонстрации этого использовать таблицу из базы Northwind. Применить в нем оператор WAITFOR для того, чтобы транзакция с этим запросом продолжалась назначенное время. Проверить, что блокировки действительно существуют при помощи другого запроса SELECT по той же таблице. Показать, что возникшая блокировка может быть обнаружена с помощью визуальных средств, предоставляемых SQL Server. Прислать скриншот это view, который показывает наличие проблем с блокировками.

SET TRANSACTION ISOLATION LEVEL READ COMMITTED

BEGIN TRAN

SELECT * FROM Categories WITH (TABLOCKX)

WAITFOR DELAY '00:00:10'

COMMIT TRAN

Для обнаружения блокировок на уровне таблицы можно использовать программу SQL Server Profiler, системные хранимые процедуры sp_lock и sp_who, а также окно Current Activity программы SQL Server Enterprise Manager.

lock1

7.2 Написать второй запрос - SELECT по той же таблице, но чтобы он работал в любом случае - не ждал окончания блокировки всей таблицы.

SELECT * FROM Categories WITH (NOLOCK)

8. Работа с utility Profiler - показать как можно отследить все запросы только к определенной базе. Для проверки использовать запросы к базе Northwind.

SQL Profiler ->File-> New Trace -> вкладка Events-> добавить TSQL->вкладка Filters-> раскрыть узел DatabaseName-> выбрать Like-> вписать Northwind->Run

9. Как организовать в БД поддержку отношения логических связей объектов многие ко многим на уровне таблиц БД?

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

10. В Query Analyzer есть возможность создавать объекты БД (функции, процедуры, таблицы и т.д.) при помощи шаблонов. Можно кратко описать как это можно сделать?

В Object Browser выбрать вкладку Templates .

Выбрать необходимый шаблон, он откроется в новом окне.

В меню Edit выбрать Replace Template Parameters.

Установить нужные значения параметров.

Нажать Replace All.

Нажать кнопку Execute Query.

Электронная цифровая подпись, алгоритм RSA

I. Введение

Электронная цифровая подпись (ЭЦП)— реквизит электронного документа, предназначенный для удостоверения источника данных и защиты данного электронного документа от подделки.

Общая схема

Схема электронной подписи обычно включает в себя:

  • алгоритм генерации ключевых пар пользователя;
  • функцию вычисления подписи;
  • функцию проверки подписи.

Функция вычисления подписи на основе документа и секретного ключа пользователя вычисляет собственно подпись. В зависимости от алгоритма функция вычисления подписи может быть детерминированной или вероятностной. Детерминированные функции всегда вычисляют одинаковую подпись по одинаковым входным данным. Вероятностные функции вносят в подпись элемент случайности, что усиливает криптостойкость алгоритмов ЭЦП. Однако, для вероятностных схем необходим надёжный источник случайности (либо аппаратный генератор шума, либо криптографически надёжный генератор псевдослучайных бит), что усложняет реализацию.

В настоящее время детерминированые схемы практически не используются.

Функция проверки подписи проверяет, соответствует ли данная подпись данному документу и открытому ключу пользователя. Открытый ключ пользователя доступен всем, так что любой может проверить подпись под данным документом.

Поскольку подписываемые документы — переменной (и достаточно большой) длины, в схемах ЭЦП зачастую подпись ставится не на сам документ, а на его хэш. Для вычисления хэша используются криптографические хэш-функции, что гарантирует выявление изменений документа при проверке подписи. Хэш-функции не являются частью алгоритма ЭЦП, поэтому в схеме может быть использована любая надёжная хэш-функция.

Защищённость

Цифровая подпись обеспечивает:

  • Удостоверение источника документа. В зависимости от деталей определения документа могут быть подписаны такие поля, как «автор», «внесённые изменения», «метка времени» и т. д.
  • Защиту от изменений документа. При любом случайном или преднамеренном изменении документа (или подписи) изменится хэш, следовательно, подпись станет недействительной.
  • Невозможность отказа от авторства. Так как создать корректную подпись можно лишь, зная закрытый ключ, а он известен только владельцу, то владелец не может отказаться от своей подписи под документом.

Возможны следующие угрозы цифровой подписи:

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

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

Тем не менее, возможны ещё такие угрозы системам цифровой подписи:

  • Злоумышленник, укравший закрытый ключ, может подписать любой документ от имени владельца ключа.
  • Злоумышленник может обманом заставить владельца подписать какой-либо документ, например используя протокол слепой подписи.
  • Злоумышленник может подменить открытый ключ владельца (см. управление ключами) на свой собственный, выдавая себя за него.
Алгоритмы ЭЦП
  • Американские стандарты электронной цифровой подписи: DSA, ECDSA
  • Российские стандарты электронной цифровой подписи: ГОСТ Р 34.10-94 (в настоящее время не действует), ГОСТ Р 34.10-2001
  • Украинский стандарт электронной цифровой подписи: ДСТУ 4145-2002
  • Стандарт PKCS#1 описывает, в частности, схему электронной цифровой подписи на основе алгоритма RSA
Управление ключами

Важной проблемой всей криптографии с открытым ключом, в том числе и систем ЭЦП, является управление открытыми ключами. Необходимо обеспечить доступ любого пользователя к подлинному открытому ключу любого другого пользователя, защитить эти ключи от подмены злоумышленником, а также организовать отзыв ключа в случае его компрометации.

Задача защиты ключей от подмены решается с помощью сертификатов. Сертификат позволяет удостоверить заключённые в нём данные о владельце и его открытый ключ подписью какого-либо доверенного лица. В централизованных системах сертификатов (например PKI) используются центры сертификации, поддерживаемые доверенными организациями. В децентрализованных системах (например PGP) путём перекрёстного подписывания сертификатов знакомых и доверенных людей каждым пользователем строится сеть доверия.

Управлением ключами занимаются центры распространения сертификатов. Обратившись к такому центру пользователь может получить сертификат какого-либо пользователя, а также проверить, не отозван ли ещё тот или иной открытый ключ.

Описание алгоритма RSA

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

История

Описание RSA было опубликовано в 1977 году Рональдом Ривестом (Ronald Linn Rivest), Ади Шамиром (Adi Shamir) и Леонардом Адлеманом (Leonard Adleman) из Массачусетского Технологического Института (MIT).

Британский математик Клиффорд Кокс (Clifford Cocks), работавший в центре правительственной связи (GCHQ) Великобритании, описал аналогичную систему в 1973 году во внутренних документах центра, но эта работа не была раскрыта до 1977 года и Райвест, Шамир и Адлеман разработали RSA независимо от работы Кокса.

В 1983 году MIT был выдан патент 4405829 США, срок действия которого истёк 21 сентября 2000 года.

Описание алгоритма

Безопасность алгоритма RSA основана на трудности задачи разложения на множители. Алгоритм использует два ключа — открытый (public) и секретный (private), вместе открытый и соответствующий ему секретный ключи образуют пару ключей (keypair). Открытый ключ не требуется сохранять в тайне, он используется для зашифрования данных. Если сообщение было зашифровано открытым ключом, то расшифровать его можно только соответствующим секретным ключом.

Генерация ключей

Для того, чтобы сгенерировать пару ключей выполняются следующие действия:

1. Выбираются два больших простых числа clip_image001и clip_image002

2. Вычисляется их произведение clip_image004

3. Вычисляется Функция Эйлера clip_image006

4. Выбирается целое clip_image008такое, что clip_image010и clip_image008[1]взаимно простое с clip_image011

5. С помощью расширенного алгоритма Евклида находится число clip_image012такое, что clip_image014

Число clip_image015называется модулем, а числа clip_image008[2]и clip_image012[1]— открытой и секретной экспонентами, соответственно. Пара чисел clip_image016является открытой частью ключа, а clip_image012[2]— секретной. Числа clip_image001[1]и clip_image002[1]после генерации пары ключей могут быть уничтожены, но ни в коем случае не должны быть раскрыты.

Зашифрование и расшифрование

Для того, чтобы зашифровать сообщение clip_image018вычисляется

clip_image019.

Число clip_image021и используется в качестве шифртекста. Для расшифрования нужно вычислить

clip_image022.

Нетрудно убедиться, что при расшифровании мы восстановим исходное сообщение:

clip_image023

Из условия

clip_image024

следует, что

clip_image026для некоторого целого clip_image027, следовательно

clip_image028

Согласно теореме Эйлера:

clip_image029,

поэтому

clip_image030

clip_image031

Некоторые особенности алгоритма

Генерация простых чисел

Для нахождения двух больших простых чисел clip_image001[2]и clip_image002[2], при генерации ключа, обычно используются вероятностные тесты чисел на простоту, которые позволяют быстро выявить и отбросить составные числа.

Для генерации clip_image001[3]и clip_image002[3]необходимо использовать криптографически надёжный генератор истинно случайных чисел. У нарушителя не должно быть возможности получить какую-либо информацию о значениях этих чисел.

clip_image001[4]и clip_image002[4]не должны быть слишком близки друг к другу, иначе можно будет их найти используя метод факторизации Ферма. Кроме того, необходимо выбирать «сильные» простые числа, чтобы нельзя было воспользоваться p-1 алгоритмом Полларда.

Дополнение сообщений

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

· значения clip_image032и clip_image033дадут при зашифровании шифртексты 0 и 1 при любых значениях clip_image008[3]и clip_image015[1].

· при малом значении открытого показателя (clip_image035, например) возможна ситуация, когда окажется, что clip_image036. Тогда clip_image037, и нарушитель легко сможет восстановить исходное сообщение вычислив корень степени clip_image008[4]из clip_image021[1].

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

Для решения перечисленных проблем сообщения дополняются перед каждым зашифрованием некоторым случайным значением — солью. Дополнение выполняется таким образом, чтобы гарантировать, что clip_image039, clip_image041и clip_image042. Кроме того, поскольку сообщение дополняется случайными данными, то зашифровывая один и тот же открытый текст мы каждый раз будем получать другое значение шифртекста, что делает атаку с выбранным открытым текстом невозможной.

Выбор значения открытого показателя

RSA работает значительно медленнее симметричных алгоритмов. Для повышения скорости шифрования открытый показатель clip_image008[5]выбирается небольшим, обычно 3, 17 или 65537. Эти числа в двоичном виде содержат только по две единицы, что уменьшает число необходимых операций умножения при возведении в степень. Например, для возведения числа clip_image043в степень 17 нужно выполнить только 5 операций умножения:

clip_image045

clip_image046

clip_image047

clip_image048

clip_image049

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

Выбор значения секретного показателя

Значение секретного показателя clip_image012[3]должно быть достаточно большим. В 1990 году Михаэль Винер (Michael J. Wiener) показал, что если clip_image051и clip_image052, то имеется эффективный способ вычислить clip_image012[4]по clip_image015[2]и clip_image008[6]. Однако, если значение clip_image008[7]выбирается небольшим, то clip_image012[5]оказывается достаточно большим и проблемы не возникает.

Длина ключа

Число n должно иметь размер не меньше 512 бит. В настоящий момент система шифрования на основе RSA считается надёжной, начиная с размера N в 1024 бита.

Применение RSA

Система RSA используется для защиты программного обеспечения и в схемах цифровой подписи. Также она используется в открытой системе шифрования PGP.

Из-за низкой скорости шифрования (около 30 кбит/с при 512 битном ключе на процессоре 2 ГГц), сообщения обычно шифруют с помощью более производительных симметричных алгоритмов со случайным ключом (сеансовый ключ), а с помощью RSA шифруют лишь этот ключ.

II. Реализация

Для примера была реализована программа для цифрового подписания файлов и проверки подписей. Использовался алгоритм RSA и сертификаты X.509. Сертификат пользователя выбирается из хранилища сертификатов windows.

Цифровые подписи сохраняются в xml файле с именем <имя исходного файла>.sig.xml

clip_image054

Фрагменты кода

public class Signature

{

private X509Certificate2 certificate;

private DateTime date;

private byte[] signedHash;

public X509Certificate2 Certificate

{

get { return certificate; }

set { certificate = value; }

}

public DateTime Date

{

get { return date; }

set { date = value; }

}

public void Sign(string input, X509Certificate2 cert)

{

this.certificate = new X509Certificate2( cert);

date = DateTime.Now;

string stringToEncrypt = input + date.Ticks;

signedHash = ((RSACryptoServiceProvider)cert.PrivateKey).SignData(Utils.StringToBytes(stringToEncrypt),new MD5CryptoServiceProvider());

}

public bool IsValid(string input)

{

string stringToEncrypt = input + date.Ticks;

return ((RSACryptoServiceProvider)certificate.PublicKey.Key).VerifyData(Utils.StringToBytes(stringToEncrypt),new MD5CryptoServiceProvider(), signedHash);

}

public byte[] SignedHash

{

get { return signedHash; }

set { signedHash = value; }

}

}

void DisplaySignatureList()

{

FileSignatures fileSignatures = ReadSignatures(GetSignaturesFileName(fileNameTextBox.Text));

signatureListTextBox.Text = "";

foreach (Signature signaure in fileSignatures.Signaures)

{

string row = "";

row+= signaure.Certificate.Subject;

row+=" "+signaure.Date.ToString();

string hash = GetFileHash(fileNameTextBox.Text);

bool valid = signaure.IsValid(hash);

if (valid)

row = "v " + row;

else

row = "x " + row;

signatureListTextBox.Text += row+"\r\n";

}

}

III. Литература

  1. С.Бернет, С. Пейн : Криптография. Официальное руководство RSA Security – М. «Бином», 2002
  2. В. Зима : Безопасность глобальных сетевых технологий – «БХВ-Петербург», 2003
  3. Венбо Мао Современная криптография: теория и практика = Modern Cryptography: Theory and Practice. — М.: «Вильямс», 2005. — С. 768. ISBN 0-13-066943-1
  4. Нильс Фергюсон, Брюс Шнайер Практическая криптография : Practical Cryptography: Designing and Implementing Secure Cryptographic Systems. — М.: «Диалектика», 2004. — С. 432. ISBN 0-471-22357-3
  5. Шнайер, Брюс. Прикладная криптография. Протоколы, алгоритмы, исходные тексты на языке Си — М.: Издательство ТРИУМФ, 2002 — 816с.:ил. ISBN 5-89392-055-4
  6. http://ru.wikipedia.org/wiki/Категория:Криптография