(Возврат на основную страницу)

 

Содержание номера за Май 2009 год

SQL Server

Май 2009
№ 5 (101)

 

Editorial

Тони Дэвис

Ярмарочный столб

DB Design & Warehousing

Грегор Бороса

Получение сведений о ваших базах данных

Programming

Питер Фогель

Предотвращение конфликта на уровне записи за счет ограничения изменений

Разрешение конфликта на уровне данных с помощью оптимистичного параллелизма

Джо Селко

Ограничьте себя!

Other

Линчи Шиа

Что быстрее: SAN или напрямую подключаемое хранилище

Младен Прайдич

Планирование заданий в SQL Server Express

 

Ярмарочный столб

Тони Дэвис (Tony Davis)

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

Интересно посмотреть на столы и книжные шкафы ваших товарищей программистов, особенно старшего поколения. В некоторых случаях вы сможете найти издания, отражающие нормальное стремление разработчика развиваться, такие как «Строго функциональные структуры данных» («Purely Functi­onal Data Structures») и «Многопользовательское программирование для Windows» («Concurrent Prog­ramming in Windows»), а не «Как правильно использовать Post­it Notes».

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

При этом стремление перейти на управленческую должность вполне объяснимо. В нашей индустрии не любят нанимать программистов в возрасте, и у таких специалистов немного шансов получить продвижение. Вы становитесь старшим разработчиком после пяти лет карьеры, что означает возраст 26 лет, если вы успешно начали карьеру после окончания колледжа! Спустя еще несколько лет, если вы не начнете красить волосы и лгать о своем возрасте, вы начинаете более или менее сильно ощущать необходимость карабканья по смазанному салом ярмарочному столбу к туманной цели «стать менеджером». В результате, опыт практической работы уходит вместе со специалистами. Неудивительно, что в Европе потери от провалившихся ИТ­проектов достигают поражающих воображение 200 миллиардов долларов.

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

Хорошим программистам следует оставаться программистами, нам нужно поощрять их в этом и давать возможность развития и повышения квалификации. Они должны постоянно искать способы улучшения используемых алгоритмов, расширения масштабируемости приложений, оптимизации использования памяти и так далее. Вместо этого, многие программисты по необходимости стремятся овладеть новейшими методиками управления, стараются использовать в разговоре «горячие» термины и фразы типа «bottom line». А тем временем из восьми проектов семь заканчиваются провалом. Вот так.

Получение сведений о ваших базах данных

Грегор Бороса (Gregor Borosa)

DOWNLOAD

Введение

Время от времени большинство из нас получает задание «достать некие данные из некой базы данных». Не знаю, происходит ли это только со мной, но меня постоянно просят поработать с базами, о которых я ничего не знаю. Обычно я не имею никакой документации и никаких сведений о модели данных, принципах именования, вообще почти ничего. Обыкновенно у меня есть какая­то неопределенная информация о том, что я надеюсь найти, например, «все данные заказчика из нашей старой базы данных Интернет­магазина», и в этом случае я уже ожидаю обнаружить некие обычные связанные таблицы клиентов и заказов, как Customers, Companies, Countries, Orders и т. д. Тем не менее, среди таблиц и столбцов легко заблудиться.

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

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

Результаты, разумеется, очень сильно зависят от ситуации, но поскольку в таблице Items есть, как правило, столбцы с именем, вроде %item%, может иметь смысл проверить таблицы со схожими названиями. В процессе работы список таблиц­кандидатов будет исследован следующим образом: насколько они велики, какие столбцы содержат, сколько в них различных значений и т. д. Хотя установленные цифры не всегда стопроцентно точны, они достаточны для данной цели — а именно это и имеет сейчас значение. На завершающей стадии останется некоторая ручная работа, связанная с просмотром результатов, но не в огромном количестве.

Поскольку мы надеемся найти таблицы, занимающие центральное место в базе данных, где лежат все «хорошие данные», где много строк и у которых имеется множество зависимостей, мы можем предположить, что в таких таблицах будет, по меньшей мере, несколько столбцов со схожими названиями. Это хорошие кандидаты на рассмотрение. Если я вижу стандартную таблицу заказов (Orders), в ней, по всей вероятности, будет иметься столбец с названием, очень близким к [Customer No.] (номер клиента). Точно такое же название столбца затем, вероятно, будет использоваться где­нибудь в другом месте базы данных — везде, где важен заказчик. И это то, что мы ищем в первую очередь.

Предотвращение конфликта на уровне записи за счет ограничения изменений

Питер Фогель (Peter Vogel)

Существует программный код, которым можно воспользоваться, чтобы не допустить перезаписи внесенных изменений данными из источника данных ASP.NET DataSource.

Чуть­чуть программирования, и вы можете избавиться от тех проблем, которые создают источники данных ASP.NET DataSource в том случае, когда двое обращаются к одной и той же записи.

Хорошо, хорошо, много программирования.

Представьте себе, что Сью и Лу одновременно извлекают запись из таблицы Customer. Сью вносит изменения в поле LastName и сохраняет свою версию записи. Прискорбно, но вслед за этим Лу уничтожает внесенное ею изменение, модифицировав поле CustomerCredit перед тем, как сохранить свою версию записи. К сожалению, изменение, внесенное Сью в поле LastName, теперь потеряно, потому что, сохраняя запись Лу, источник данных ASP.NET DataSource обеспечил обновление всех остальных полей в этой записи теми данными, которые извлек Лу перед тем, как свое обновление выполнила Сью. Нехорошо.

Избежать возникновения такой проблемы нетрудно: если бы Лу нужно было обновить одно только поле CustomerCredit, измененное им самим, тогда он не перезаписал бы данные в поле LastName, измененном Сью. Добиться этого можно написав собственный программный код для процедуры обновления.

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

Разрешение конфликта на уровне данных с помощью оптимистичного параллелизма

Питер Фогель (Peter Vogel)

Для большинства таблиц модель оптимистичного параллелизма (optimistic concurrency) не срабатывает. Однако Питер демонстрирует, как можно изменить ситуацию.

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

В предыдущей статье из этой рубрики («Предотвращение конфликта на уровне записи за счет ограничения изменений») я описал проблему, возникающую в том случае, когда в веб­приложении два пользователя обращаются к одной и той же записи; и предположил, что ее можно решить, если обновлять только те поля записи, которые были изменены. Элемент управления источниками данных ASP.NET DataSource предлагает встроенное решение, которое называется «Оптимистичный параллелизм» («Optimistic Concurrency»). К сожалению, в версиях ASP.NET 2.0/3.5 это решение чаще всего не работает.

Ограничьте себя!

Джо Селко (Joe Celko)

В своей первой статье Джо Селко раскрывает тайну использования ограничений (constraint) и указывает на то, что этот механизм является важным компонентом языка SQL, обеспечивающим отличный способ гарантировать единообразное, в одном месте, однократное применение бизнес-правил. Почти каждый программист баз данных найдет в этой статье что-то новое и полезное.

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

После того как я не один десяток лет потратил на обучение языку SQL и написание книг о нем, у меня сложилось твердое убеждение: тому, кто в состоянии перестроить свой образ мыслей и переключиться с процедурного программирования и последовательных файлов на декларативное программирование и множества, язык SQL и моделирование данных даются много, много легче. Это — прозрение, почти равноценное тому, как для процедурного программиста внезапно обретает смысл рекурсия. Если по своему «происхождению» вы являетесь LISP­программистом, замените в последнем предложении «рекурсию» на «итерацию».

Часть этого прозрения — осознание того, что языки DDL (Data Declaration Language — язык объявления данных), DML (Data Manipulation Language — язык манипулирования данными) и DCL (Data Control Lan­guage — язык управления данными) являются важными составляющими языка SQL, а не отдельными, обособленными языками. В этой статье речь идет о языке DDL, но чем совершеннее язык DDL, тем совершеннее языки DML и DCL. Если бизнес­правило сформулировано на языке DDL, способ его выполнения унифицирован, оно выполняется в одном месте, один раз. Вам не надо возлагать надежды на то, что  каждое приложение и каждое предложение языка DML правильно выполнят все правила. Вы не должны рассчитывать, что изменение в правилах приведет к необходимости вносить коррективы в сотне или даже тысяче мест в системе.

Что быстрее: SAN или напрямую подключаемое хранилище

Линчи Шиа (Linchi Shea)

Следует ли мне размещать файлы базы данных в сети хранения данных (SAN) или в напрямую подключаемом хранилище? Это часто задаваемый вопрос. Он постоянно возникает в открытых группах новостей, почтовых списках рассылки и при личных встречах с заказчиками, проявляющими интерес к производительности баз данных.

Какая SAN?

Термин «сеть хранения данных» (Storage Area Net­workSAN) может подразумевать две различные вещи. Для профессионалов сферы хранения данных он может принимать узкое значение коммутирующей матрицы (набор комутаторов — по версии TechNet) между хост­серверами (основными серверами) и применяться к сложным дисковым массивам, хранящим данные на самом деле. Для большинства остальных людей, тем не менее, разница между коммутирующей матрицей и дисковыми массивами очень невелика. Они, скорее, представляют матрицу и дисковые массивы — в сущности, все выше физического диска и за пределами хост­сервера —составной частью SAN. В данной статье принята именно эта наиболее распространенная точка зрения.

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

Во­первых, SAN — это не монолитная сущность. Если взять в качестве примера SAN на базе коммутирующей матрицы с оптоволоконными каналами, путь ввода­вывода, являющийся рассматриваемой частью SAN, начинается с адаптеров главной шины (host bus adapter HBA) и проходит вплоть до оконечных дисковых носителей дискового массива. Аппаратные компоненты пути ввода­вывода обычно включают в состав коммутаторы (переключатели), линии связи между коммутаторами, внешние адаптеры, кэш дискового массива и процессоры, дисковые контроллеры и носители на дисковых накопителях. Кроме того, на этом пути имеются уровни программного обеспечения , включающие различные драйверы, аппаратно реализованное программное обеспечение (микропрограммы, прошивки) и прикладные программные интерфейсы (API). Каждый компонент на пути ввода­вывода имеет потенциальную возможность значительно изменить характеристики производительности накопителя, предоставляемого из SAN.

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

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

Что имеется в виду под «быстрее»?

Чтобы задавать вопрос о том, что быстрее, вы должны ясно представлять, что вы под «быстрее» понимаете. Как правило, вы можете использовать три ключевых показателя для измерения производительности пути дискового ввода­вывода:

•    количество операций ввода­вывода в секунду (IOps);

•    мегабайт в секунду (MBps);

•    задержка отклика.

Показатель IOps измеряет, какое количество запросов путь дискового ввода­вывода может выполнить в секунду. Для конкретного пути дискового ввода­вывода данная метрика, как правило, находится в обратном пропорциональном соотношении к размеру запросов ввода­вывода. То есть чем больше запросы ввода­вывода, тем ниже IOps. Это интуитивно понятно. Как­никак, для обработки 256­килобайтного запроса требуется больше времени, чем для 8­килобайтного.

MBps измеряет, сколько данных может быть прокачано через путь дискового ввода­вывода. Если смотреть на путь ввода­вывода как на трубопровод, MBps оценивает, насколько этот трубопровод большой и какое давление он может выдержать. Таким образом, чем больше трубопровод и чем с большим давлением он может иметь дело, тем больше мегабайт данных он может пропустить. Для конкретного пути ввода­вывода показатель MBps находится в прямой пропорциональной зависимости к размеру запросов ввода­вывода. То есть чем крупнее запросы ввода­вывода, тем выше MBps. Более крупные операции ввода­вывода дают лучшую пропускную способность, поскольку они несут меньшие временные потери при поиске по диску, чем небольшие операции ввода­вывода.

Обратите внимание, что для запросов ввода­вывода фиксированного размера блока, MBps — это просто размер блока, взятый IOps раз, в мегабайтах.

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

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

Но какое все это имеет отношение к вопросу о том, что быстрее — SAN или напрямую подключаемое хранилище? Что ж, эти три показателя четко определяют то, что подразумевается под «быстрее». Поэтому, когда вы говорите, что одно быстрее другого, вы должны в явной форме указать, на какой критерий ссылаетесь.

Давайте исследуем вопрос, рассмотрев три эти меры производительности, а начнем с задержки ввода­вывода.

Планирование заданий в SQL Server Express

Младен Прайдич (Mladen Prajdiс)

DOWNLOAD

Как все мы знаем, SQL Server 2005 Express — это очень мощное бесплатное издание SQL Server 2005. Тем не менее оно не содержит службы агента SQL Server. И поэтому планирование заданий невозможно. Таким образом, если мы хотим этим заняться, то вынуждены установить бесплатный или коммерческий продукт производства третьей стороны. Это не всегда позволено в силу политики безопасности многих хостинговых компаний и, следовательно, представляет проблему. Возможно, нам требуется запланировать ежедневное резервное копирование, переиндексацию базы данных, обновление статистики и т. п. Вот почему мне захотелось иметь решение, реализованное только на SQL Server 2005 Express и не зависящее от компании, предоставляющей хостинг. И, разумеется, таковое, основанное на нашем старом друге, — компоненте Service Broker, существует. 

(Возврат на основную страницу)

Hosted by uCoz