понедельник, 30 января 2012 г.

Блокировки транзакций

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

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

Зачем это надо? Транзакцию надо открыть, совершить ее операции и закрыть - COMMIT (транзакция фиксируется) или ROLLBACK (транзакция откатывается).. Допустим, вы переводите весь свой капитал с одной карточки на другую. Выглядит это "внутри" системы как несколько операций:

delete from счет1  where счет = счет 1
insert into счет2  values ('сумма')

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

Но! К каким эффектам может привести параллельная работа двух транзакций?

1 эффект: "Потерянная запись"


Есть некий счет А, на котором лежит 500 у.е.
Кассир 1 (К1 на рисунке) списал с него 300 у.е. Обозначим его действия красными стрелками. Списал 300 - на выходе получает 200.
Кассир 2 (К2) тоже решил обратиться к этому же счету, и записал туда 300 у.е., пока К1 еще не успел закрыть свою транзакцию.
Итог - мы "потеряли запись" первого кассира, ведь на выходе у нас А = 800, хотя должно быть 500. "Кто последний вписал результат - того и тапки". Получается так.

То, что кассир списал 300 у.е., для системы означает начало транзакции (первая стрелка), выполнение действия


update таблицаСчетов  set суммаСчета= '200' where счет = счет 1

И закрытие транзации - вторая красная стрелка.

Второй кассир выполняет операцию: 

update таблицаСчетов  set суммаСчета = '800'where счет = счет 1

Начало и конец которой указаны зелеными стрелками.

2 эффект: "Грязное чтение"


Есть некий счет А, на котором лежит 500 у.е.
Кассир 1 списал с него 300 у.е. Обозначим его действия красными стрелками. Списал 300. Потом передумал и сделал откат - на выходе остались те же 500 у.е.
Кассиру 2 (К2) понадобилась информация по этому счету и он ее считал до того, как К1 закрыл свою транзакцию.
Итог - второй кассир считал неверную сумму, построил неверный отчет/отказал в визе платежеспособному гражданину и тд.


3 эффект: "Повторимое чтение"

 


Есть некие данные.
Кассир 1 строит отчет. Операции идут последовательно для каждой колонки. Система считала данные, записала в первую колонку (например, взяв минимум от них).
Обозначим получение данных зеленым цветом, а изменение - красным.
Кассир 2 влез в эту таблицу данных и изменил некоторые счета в ней.
У кассира 1 продолжается построение отчета. И во вторую колонку система считывает уже новые данные.
Итог - отчет построен на основании разных данных.

4 эффект: "Фантомы"

 


Есть некие данные.
Кассир 1 строит отчет. Операции идут последовательно для каждой колонки. Система считала данные, записала в первую колонку (например, взяв минимум от них).
Обозначим получение данных зеленым цветом, а изменение - красным.
Кассир 2 влез в эту таблицу данных и добавил новые счета/удалил некоторые старые.
У кассира 1 продолжается построение отчета. И во вторую колонку система считывает уже новые данные.
Итог - отчет построен на основании разных данных.

Разница между 3-им и 4-ым эффектами в том, что в одном случае данные изменяются, а во втором - добавляются/удаляются. То есть меняется еще и их количество.

Как бороться с этими проблемами? Чтобы избежать вышеприведенных эффектов, применяются блокировки. Способов реализации изоляции транзакции существует несколько. Основные - блокировочники и версионники. Рассмотрим блокировочники, обеспечивающих различную блокировку транзакций.

Условные обозначения:

"+" - начало блокировки (когда ее ставить)
"-" - конец блокировки (когда ее снимать)



1 эффект: "Потерянная запись"

Решение проблемы потери записи транзакции, которая была открыта первой - ставить эксклюзивную блокировку на запись на все время редактировании. Экслюзивная блокировка на записи может быть только одна, она запрещает все остальные блокировки => Кассир 2 не сможет внести своих изменений, пока Кассир 1 не закроет свою транзакцию.

 Т1 - транзакция первого кассира, начало и конец обозначены красными стрелками.
Такой уровень изоляции носит название READ UNCOMMITED

2 эффект: "Грязное чтение"


Решение проблемы чтения неверных данных вследствие их изменения во время чтения - ставить разделяемую блокировку на чтение.
Разделяемая блокировка - обязательна => Кассир 2 не сможет прочитать данные, пока Кассир 1 не закроет свою транзакцию. Так как на записи уже стоит эксклюзивная блокировка и разделяемую поставить нельзя. Но при этом разделяемых блокировок на записи может быть несколько - чтение другими "лицами" она не запрещает.
 
Такой уровень изоляции носит название READ COMMITED

3 эффект: "Повторимое чтение"


Решение проблемы чтения неверных данных вследствие чтения одних и тех же данных, которые изменили между прочтением - ставить разделяемую блокировку на чтение, но не на время чтения, а до конца транзакции.
Разделяемая блокировка разрешает только наличие других разделяемых блокировок, поставить экслюзивную туда, где уже стоит разделяемая - нельзя => Кассир 2 не сможет изменить данные, пока Кассир 1 не закроет свою транзакцию.
 
Такой уровень изоляции носит название REPEATABLE READ

4 эффект: "Фантомы"


Решение проблемы чтения неверных данных вследствие чтения одних и тех же данных, которых стало больше/меньше между прочтением - ставить предикатную блокировку от начала чтения до конца транзакции.
Предикатная блокировка ставится на условие, а не на конкретную запись/таблицу данных. Если ограничиться разделяемой/экслюзивной, то нельзя будет изменить данные в таблице, но можно будет добавить новые.
Если же поставить блокировку на условие - нельзя => Кассир 2 не сможет изменить данные, пока Кассир 1 не закроет свою транзакцию.


Такой уровень изоляции носит название SERIALIZABLE

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

вторник, 24 января 2012 г.

Программирование для тестировщиков

Быть или не быть? Учиться или не учиться? Это, конечно, риторический вопрос, не хотели бы учиться, так и сидели бы в своем болоте прохождения по тест-плану. Ок, учиться, развиваться. Самому или на курсы пойти? А на какие курсы?

За все курсы не скажу, скажу только за те, что сама посетила. Итак, хотим автоматизировать, пошли на "Программирование для тестировщиков"! Курс сразу зацепил наличием домашних заданий, куда же без них, если хочешь и правда научиться?

Ходила я на пару тренингов для автоматизации... На один день - рассказали про инструмент и "До свидания!". Как вы думаете, много я помню с тех лекций? Ничего! Применить это сразу было нельзя, так как нас отправили на несколько тренингов по разным инструментам, выбирать, типа. В итоге я лично попала всего на парочку, неподготовленная (я замещала заболевших товарищей), вообще ничего не знающая про автоматизацию... Поавтоматизировали календарь, блокнот, гугл. Прикольно? Неа, потому что тренер писал это у себя, оно транслировалось на проектор, и ты или успевал вбивать код почти бездумно или сидел, осмысливал... Под косые взгляды окружающих :))

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

Поэтому и онлайн формат мне приглянулся - выкладываются записи, их можно прослушать, остановить, понять, осознать. Плюс домашнее задание. Это вам не пришли, послушали и ушли. Что увидели, запомнили на 10%, а что сами сделали - на 70%!

Но, учтите, ваш пыл может пропасть :))) Придется снова вспомнить студенчество и тратить на эту ненавистную домашку кучу времени. И азарт может быстро испариться. Или не быстро. Но в любом случае, первые ДЗ - клева, интересно, и тд. А потом может стать и обременительным, особенно, если работы много.

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

Кстати, читая чужие отзывы, я увидела там фразу "ууу, приходится при просмотре быструю скорость ставить". И все ходила и думала - а зачем? Все ж так удобно! Слушаешь себе запись, следишь за манипуляциями тренера, клац мышкой - остановил, сделал ровно тоже самое. Так прошелся по всей записи, и перечитываешь ДЗ - а что теперь тебе уже самому сделать надо?

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

То есть в три раза больше. А уж как обидно, когда просидел почти час, а посмотрел то - 15 минут!!! Ууууу, как медленно :((( А что делать? Пока увидишь, пока повторишь... Готовьтесь, ребятки :)

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

Но записи 10, последнего занятия, я очень ждала. Чтобы насладиться просмотром видео без остановок )))) Домашнего задания на него нет, а значит, можно не останавливаться каждую минуту, повторяя за тренером, чтобы позже, допиливая все ДЗ, разобраться подробнее.

Вернемся к курсу. Если пройтись по анкете, которую нам еще не присылали, поэтому взятую отсюда:

Тренер!

Компетентность тренера - разумеется, без сомнений, иначе бы я туда и не пошла :) Мне повезло, я успела послушать Алексея на Конфетке - хорошо объясняет, "надо брать" (с)

Согласна с отзывом "тренер, как обычный человек, все в голове держать не может. Но знает как и где БЫСТРО найти ответ" - вот это тоже мастерство. Если у меня над душой стоят, я могу просто от волнения даже элементарную вещь забыть.

Регламент (насколько хорошо тренер управляет ходом событий и временем) - Тут все хорошо, что было задумано - все было сделано. И сделано много! И всего-лишь за 1.5 часа :)

Риторика, текст (что тренер говорит) и речь (как тренер говорит) - Алексей хороший оратор. Голос не замогильно - умирающий, так что не засыпаешь от него

Экспертиза (как тренер отвечает на вопросы) - тренер ответил не на все вопросы)))))
Да! Как отобразить task-и в Task-ах, я так и не услышала :))) И что за мистика там с Джеймсом (почтовый сервер), что у Алексея все работает без доп настроек, а у части людей с форума - только с ними, ответа пока нет. И я, например, его искать не буду :)) Вот как столкнусь с почтой по работе... Тогда да.

Онлайн-тренинг

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

Насколько полно раскрыта тема - вот тут сложнее... В принципе, дано очень много самого разного материала. Это хороший старт для новичка - можно идти и начинать автоматизировать свое приложение. Но. Не знаю, например, хелперы для работы с базой данных нам просто ДАЛИ. Мы их не писали, нам их дали. Хочешь больше - иди изучай SQL, видимо. Аналогично с mail - хелпером. Оно, конечно, пробежались по его методам в самом уроке, но... Когда у тебя есть готовая вещь... Далеко не каждый будет сидеть и вникать :) А если вникать - придется копать глубоко... Что такое вообще соединение, транзакция и тд?

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

Насколько интересно подан материал - тут претензий нет. Хотя, согласна, не хватает картинок, диаграмм, который можно было бы открыть "потом". Когда уже успел забыть. Не выискивать в видео, а посмотреть на схему...

Другое

Организационные вопросы - вначале все было хорошо, письма на почту шли и тд.
Потом возникали небольшие косяки, как оценка в 8 из 100, а не из 10. К концу курса стали сбоить письма, это было грустнее - например, проверил тренер 5 дз, а мне одно оповещение всего пришло :((( Тренеру не все оповещения приходили, в итоге народ в скайпе волнуется - почему не проверили? А тренер даже и не знал, что люди выложили это ДЗ...

Оправдались ли Ваши ожидания? - сложно сказать, ведь когда я регистрировалась на курс, мои ожидания были - научиться с нуля. Но до начала курса я уже начала изучать автоматизацию с нуля, и многое мне было знакомо, кроме работы с базой, с фтп... Но эти темы были не сильно раскрыты, только показано "да, так тоже можно", но на них и ДЗ то было "повторить действия в классе", не было простора для фантазии, а, значит, и для косяков ))))

А пока сам шишки не набьешь - мало чему научишься. Скопипастив код из видео, мало что запомнишь... Так что... Курс сам по себе хороший, много полезного дал. В конце концов, 23 ДЗ не прошли бесследно :) Над некоторыми чуть ли не днями приходилось сидеть. И я получила нужные мне навыки. Хотя изначальные ожидания были другие, им было не суждено оправдаться еще до начала обучения :)

Это как сейчас - записалась на курсы по SQL, а половину уже сама узнала. Нууу... Не совсем сама :)))

Общее впечатление - хорошее!

Начало эмоций насчет данного курса я уже писала здесь.
Резюмируя, даже с учетом того, что какие-то основы я уже и так знала... Новое тоже было. И даже не только всякие джеймс хелперы, которые "повтори, как было в классе и успокойся", но, например, конфигурационный файл, чтение тестовых данных из файлы, неплохая разминка по циклам, а уж по дебагу... Это, кстати, главный инструмент разработчика, в том числе и разработчика автотестов :))) Так что весьма полезное умение...

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

понедельник, 23 января 2012 г.

SQL. Группировка результатов

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

Как выполняется группировка? С помощью следующих команд:

group by (измерение 1, измерение 2) - по перечисленным измерениям
group by rollup (измерение 1, измерение 2) - по перечисленным измерениям с итоговыми строками
group by cube (измерение 1, измерение 2) - по всем комбинациям перечисленных измерений с итогами

Непонятно? Давайте на примере.

Связываем наши книги с еще одной таблицей - Publisher, издательство


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


Получили выборку значений. Группировка идет по указанным измерениям, справа налево.
То есть вначале для одного издательства (p.name) мы получили список всех жанров (g.name), потом для второго и тд.

NULL - это строка "Всего". Соответственно, по издательству "Wrox" у нас есть книги с жанром "Стихи" и "Фантастика", и строка - "Всего".

Теперь сравним с выборкой вида cube



Теперь мы получили комбинации со строками "Всего" не только по сворачиваемому измерению, а вообще по всем - по каждому жанру и по каждому издательству, а также "Всего - Всего"

Все равно непонятно, зачем нам эти строки - NULL. Чтобы это понять, рассмотрим группировочные функции:

MIN
MAX
AVG (среднее)
COUNT
SUM
и тд

Выведем сумму по всем жанрам всех издательств


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

Если же мы хотим наложить ограничение на уже сгруппированные данные, то пишем функции не после оператора select, а после group by с помощью оператора having


Еще особенность записи операторов:
  • COUNT (ba.bookId) – ненулевые записи
  • COUNT (*) – все записи
Итого:

Последовательность операторов для запросов к БД (используются по мере необходимости):


select            - что выбираем
from              - откуда
where           - условие выборки
group by       - группируем результат
having          - сортируем сгруппированный результат
order by       - сортируем в алфавитном порядке или наоборот

суббота, 21 января 2012 г.

SQA Days 10, после просмотра видео

Чем заняться тестировщику в холодные зимние деньки всем знакомого новогоднего "отпуска"?
Помимо гуляний, разумеется :)

It-conf решил помочь нам в этом сложном вопросе, опубликовав видео всех секционных докладов.

Посмотрела я записи всех докладов, на которые не попала во время посещения конференции (кроме докладов по тестированию мобильных приложений и автоматизации тестирования), появились новые комментарии к ним...

1. Алексей Лянгузов


Первые 9 минут - организационная "вода" :((

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

Слайд "Пример жизненного цикла" я бы разбила с помощью анимации , а то включается слайд и оратора уже не хочется слушать, сидишь, разглядываешь кучу картинок на экране. И в корне неверное утверждение "я знаю, что инфы на слайдах много, я просто поменьше скажу, потом почитаете, посмотрите". Раздаточный материал не должен равняться самой презентации! А сама презентация без докладчика должна быть непонятной, иначе нафига оратор? :) 

*Я прям умная такая вся, еще бы на своем примере клева показала, как надо)))) 

пятница, 20 января 2012 г.

Дистанционное обучение в IT


Где набраться новых знаний в такой распространенной области, как IT?
Особенно, если тратить деньги не очень хочется...

Советую обратить внимание на огромный подарок от "Computer Sience" клубов. Почитать о нем можно здесь.

Что он включает?


Computer Science Center


Это наши новые друзья, совместный проект Школы анализа данных Яндекса, CS клуба, Академии современного программирования и ФМЛ №239. Занятия начались осенью 2011.
Это первые, вступительные курсы.

2011


Основы баз данных, Илья Тетерин
Основы математики, Александр Храбров
Основы C++, Евгений Линский
Основы Java, Георгий Корнеев
Алгоритмы и структуры данных, Александр Куликов
Обзорный курс по анализу данных, Юлия Киселёва
Вычислимость и логика, Дмитрий Ицыксон

Питерский Computer-Science клуб


Это наши старые друзья. Читайте прошлогодний пост об архиве других лет.

осень 2011


Компьютерная графика, В. А. Галинский
Модели веб-графов и их приложения А. М. Райгородский
Введение в комбинаторику слов, А. Э. Фрид
Computer Science семинар (осень 2011)

2010-2011


Линейное программирование, М. А. Бабенко
Квантовые алгоритмы: возможности и ограничения М. Н. Вялый
Параметризованные алгоритмы, Ф. Фомин
Системы типизации лямбда-исчисления, Д. Н. Москвин
Computer Science семинар (весна 2011)
Компьютерное зрение и библиотека OpenCV, В. Л. Ерухимов
Анализ поисковых запросов, П. Браславский
Синхронизируемые автоматы, М. В. Волков
Program Analysis for Security, B. Livshits
Проблема изоморфизма графов, И. Н. Пономаренко
Онтология и представление знаний, Б. Ю. Конев
Семантическая классификация изображений, А. Конушин
Функциональное программирование, Е. Р. Кирпичёв
Теория сложности доказательств, Э. А. Гирш
Computer Science семинар (осень 2010)

И многое-многое другое. Выбирайте интересные для вас знания и изучайте, изучайте, изучайте...

Простые, понятные автотесты. Где почитать о том, как их создать?

Хотите писать простые и понятные автотесты, но не знаете, с чего начать?

Разумеется, об этом уже говорилось! Надо только ссылки знать :)

Если вы хотите пишать на PHP, то вам прямая дорога на Хабр.
О чем там вообще говорится? Есть такой проект, Codeception.

С ним тесты для ваших веб-приложений могут выглядеть так:

<?php
$I = new TestGuy($scenario);
$I->wantTo('create new blog post');
$I->amOnPage('/blog/posts');
$I->click('Create new post');
$I->fillField('Title','Codeception, a new way of testing!');
$I->fillField('Text','Codeception is new PHP full-stack testing framework.');
$I->click('Send');
$I->see('Congratulations, your post is successfully created!');

Таким образом, при минимальном знании английского языка, которому учат в школе, вы можете составлять тесты вида "Я заполняю... Я вижу...". А уже если вас, ко всему прочему, привлекает именно PHP, то эта статья - просто манна небесная! Попробуйте, возможно, автоматизация - это не так страшно :)

Codeception работает на трех китах:
— как тестовая среда используется PHPUnit.
— для приемочных тестов — Mink. За него огромная благодарность Константину Кудряшову everzet.
— и конечно же, Symfony Components. Они используются практически для всего. Особо стоит отметить BrowserKit, который используется для функциональных тестов.

Ну а если вы не знаете английского и хотите работать на С#, и при этом, опять же, хотите автоматизировать и иметь читабельные тесты, заходите на Автоконфетку. Я покажу, как написать тесты, которые смогут понять даже не-программисты

суббота, 14 января 2012 г.

Testing-by-contract VS defensive testing

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

До 12 лет - отказать в регистрации.
От 12 до 18 лет - дать доступ, но с ограничениями.
Больше 18 лет - полная регистрая, полный доступ к сайту.

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

Классы эквивалентности гласят, что нам нет смысла проверять все значения от 0 до 100 (бывают же долгожители). Мы можем взять по одному значению из каждого множества. Возьмем 5, 16 и 22. Все? Как насчет значений "10000", "-88", "%;№№"/"? Будем проверять?

Конечно же - "ДА!". Скажут многие. И будут по-своему правы.

Но знают ли они, что применяют именно "defensive testing"? Что есть и другой подход?

Далее идет вольный перевод Lee Copeland – “A Practitioner's Guide to Software Test Design”

Существует такой подход - design-by-contract. Под контрактом мы понимаем некие соглашения между частями, описывающими, что мы будем и не будем делать. В этом подходе методы описываются с помощью пред-условий и пост-условий. Пост-условие (post-condition) - это то, что модуль обещает сделать (открыть файл, сохранить значения, одобрить или отклонить регистрацию). Пред-условия (pre-condition) описывают требования к модулю, при которых он переходит в состояние, описываемое пост-условиями.

Например: функция, открывающая файл.
Post-condition: открыть файл
Pre-conditions: открываемый файл должен существовать, содержать нужное нам имя, быть "openable"...

Testing-by-contract основывается на философии design-by-contract. При использовании данного подхода мы пишем только те тест-кейсы, которые удовлетворяют нашим pre-condition. То есть на открытие файл мы НЕ пишем тест-кейс аля "файл не существует". Мы не создаем негативные кейсы, только позитивные.

У многих тестировщиков этот подход вызывает протест. Да еще какой! Как же так, а как же быть с некорректными условиями, а? Вы что?! Это очень важно!!

Да, важно! И для этого существует другой подход - defensive testing. Мы проверяем, что если условия удовлетворяют нашим pre-condition, то выполняет корретное пост-условие. Если же условия противоречат нашим pre-condition, то выдается корректное же сообщение об ошибке.

Таким образом, прежде чем ответить на поставленный вопрос: "Как насчет значений "10000", "-88", "%;№№"/"? Будем проверять?", вначале надо уточнить, а какой подход используется:

Если testing-by-contract - то ответ "Нет".
Если defensive testing - то ответ "Да".

А какой подход используете вы? :)
У меня первый подход вызывает протест. Как же так, забить на то, что вместо корректного сообщения об ошибке пользователь видит... Страшные вещи, порою... Тем более что пользователи довольно часто забивают неверные значения = им надо показывать корректные сообщения об ошибке. Иначе зачем им вообще нужна такая система, которая разваливается при каждом чихе? "Шаг влево, шаг вправо - расстрел" (с)

Нет, мы лучше обработаем возможные ошибки нормально - "Уважаемый юзер! Вам ну никак не может быть минус 93 года. Перепроверьте, пожалуйста, введенные вами данные и научитесь лгать поправдоподобнее. Спасибо за внимание, искренне ваш, Админ"

пятница, 13 января 2012 г.

SQL - join it! Запросы к БД

Итак, диаграмму Базы Данных мы создали.

Теперь надо к ней как-то обратиться. А прежде чем обращаться к БД, надо ее заполнить. Мы создали таблицы, но не заполнили их.

Исправляем недочет! Раскрываем свою базу данных - Tables - dbo.Author - правый щелчок - редактировать первые 200 значений.


Заполняем Фамилию и Имя, колонка id генерируется сама (так как мы все такие колонки сделали автоинкрементными)

По аналогии заполняем остальные таблицы - Book, BookAuthorship, Author.

Потом создаем запрос. File - New Query. Или нажимаем на кнопку в вытащенном меню

Открывается пустая страница.
Что мы хотим? Хотим вытащить все колонки из таблицы "Book".

Ок, пишем:

Создание схемы Базы Данных

Человек запоминает 10% услышанного, 20% увиденного и 70% того, что он сделал сам. А чтобы закрепить успех, необходимо научить других тому, что знаешь сам.
Правда, до учителей многим (мне, в частности) далеко, но можно хотя бы записать то, что узнал, для таких же новичков - пошагово. При написании текста внезапно понимаешь, что не все так просто и ты за сутки половину забыл :) Но я попробую закрепить новые знания.
Итак, основная задача - в автоматическом тесте при подготовке данных изменить базу, а не ползать через GUI.
Чтобы изменить базу, надо вначале понять, как нам к ней обращаться. Чтобы к ней обращаться, надо знать, как она строится.
Разберемся на примере базы книг. Мы хотим создать диаграмму Базу Данных имеющихся в наличии книг. У каждой книги есть какой-то жанр и какой-то автор.
Причем у каждой книги должен быть строго один жанр и один или несколько авторов.

Где будет создавать? В специальном приложении.

Устанавливаем и запускаем Microsoft SQL Management Studio.
Видим окно "Connect to Server", где мы можем выбрать тип и имя сервера, а также аутентификацию - выбираем Windows Authentication - Connect.
Слева появилось меню - Object Explorer.
Разворачиваем наш сервер - видим следующий список
Databases (правый клик) - New Database
Создаем базу книг -  Books.
Разворачиваем нашу базу.
Database Diagram - New Database Diagram
Когда мы рисуем диаграмму и добавляем туда таблицы, они появляются в разделе таблиц - повторяться нам не придется.
Когда мы создаем новую диаграмму, открывается пустое окно. Щелкаем правой кнопкой - New Table.
Начнем с книг. Называем таблицу Book (называть таблицы принято в единственном числе).
Заполняем ее, как на рисунке, только пока - без "ключика" слева от поля "id".

Что мы сделали? Мы сделали таблицу книг, сказав, что колонками у нее будут - id, название и описание. Имена колонкам дали.
Data Type - тип данных, id - число, поэтому int. С другой стороны, это не просто число. Id должно увеличиваться, желательно само. Это называется автоинкрементное поле - задаем начальное значение и инкремент, шаг, на который поле будет увеличиваться с каждой новой записью в базе.

Чтобы сделать id автоинкрементным, открываем свойства этой колонки.
View - Properties Window.
В свойствах нас интересует Identity Specification.
Разворачиваем пункт, говорим, что да - поле "самовозрастающее", ставим "Yes".
Указываем инкремент и Seed (начальное значение)


Название и описание - строки. Указываем им тип "nvarchar(50)" и ручками меняем число "50" на любое другое количество символов.
Allow Nulls - в этой колонке мы указываем, будет ли поле обязательным для заполнения. То есть если галка стоит - "вводить null разрешено", а "вводить null" = "не вводить ничего". Id и имя - обязательные поля, они есть у каждой книги. Описание можно оставить необязательным - ставим там галку.

Книги создали. Правый клик - New Table - Genre.

Что должно быть у жанра? Id и имя. Оба поля обязательны.
По аналогии создаем таблицу авторов:


Ок, таблицы есть. Теперь надо настроить связи между ними.
Как настраиваются связи? С помощью ключей. Почитать о них можно в вики, в строке "Ключи" приведенной таблички.
Нас интересуют:
1. PK - primary key, первичный ключ.
Он накладывается на всю таблицу, но мы можем выбрать одну или несколько колонок.
Выбираем одну колонку - ключ говорит о том, что каждое значение в ячейках этой колонки уникальное.
Выбираем несколько колонок - ключ говорит о том, что комбинации строк по колонкам уникальны.
2. FK - foreign key, внешний ключ.
Нужен для связки двух таблиц в разных соотношениях (1:1, 1:N, N:N)
Этот ключ указываем в "дочерней" таблице, то есть в той, которая ссылается.
Обозначим наши ключи. Для этого нам помогут следующие действия:
Set Primare key - назначить PK
Relationships - назначить FK

Во всех трех таблицах назначаем колонку "Id" первичным ключом - Set Primare key.
Слева от строки появятся ключи, как на картинках выше.

Разберемся со связями.
У одной книги может быть только один жанр.
Одному жанру может соответстветствовать много книг.
В таблице "Book" добавляем еще одну колонку - "genreId", значение int, поле обязательно для заполнения. Так как книга без жанра быть не может.
В таблице "Book" в колонке "genreId" открываем Relationships. В открывшемся окне при необходимости меняем название. Делается это в свойстве Identity - Name

Название заполняем по шаблону
FK_Таблица, которая ссылается_Таблица, на которую ссылаемся

Потом в основных свойствах выделяем "Спецификация таблиц и колонок", нажимаем на многоточие
Открылось окно, в котором слева мы указываем таблицу, на которую мы ссылаемся и ее первичный ключ

Мы говорим, что в колонку "genreId" таблицы "Book" передается значение "id" таблицы "Genre"
Сохраняем - видим связь между таблицами


Знак ключа говорит о том, что от этой таблицы мы берем одно значение, которое соответствует многим значениям другой таблицы, так как с ее стороны мы видим "бесконечность".
Это реализация 1:N или 1:1 (в этом случае внешний вид связи будет выглядеть как "ключик - ключик").
Чтобы реализовать связь N:N, нам понадобится ассоциативная таблица. Мы не можем сделать "бесконечность" к "бесконечности" напрямую, поэтому для такой связи таблиц мы создаем промежуточную таблицу, в которую обе исходные входят по указанному выше принципу "один ко многим".
New Table - BookAuthorship.
Комбинация идентификаторов "книга + автор" должна быть уникальными (ставим РК) и обязательными для заполнения
Тип данных bit возвращает значение "истина" при вводе 1 и "ложь" при вводе 0.
Relationships - создаем два внешних ключа. Которые сопоставляют:
"bookId" в таблице "BookAuthorship" с "id" в таблице "Book"
"аutorId" в таблице "BookAuthorship" с "id" в таблице "Autor"
Диаграмма готова!