(Возврат на основную страницу)
Editorial
Тони Дэвис
Ярмарочный столб
DB Design & Warehousing
Грегор Бороса
Получение сведений о ваших базах данных
Programming
Питер Фогель
Предотвращение конфликта на уровне записи за счет ограничения изменений
Разрешение конфликта на уровне данных с помощью оптимистичного параллелизма
Джо Селко
Ограничьте себя!
Other
Линчи Шиа
Что быстрее: SAN или напрямую подключаемое хранилище
Младен Прайдич
Планирование заданий в SQL Server Express
Ярмарочный столб
Программисты часто старомодны в вопросах самооценки. Они начинают свою карьеру, воображая ночные бдения над сложными алгоритмами, разработкой поражающих воображение приложений, разработку операционных систем в свободное время и втайне работу над собственным языком программирования. В реальности, основную часть их времени занимает перемещение клейких бумажек с одного места доски на другое и обеспечение того, что управление перемещается на правильный объект формы по нажатию клавиши табуляции.
Интересно посмотреть на столы и книжные шкафы ваших товарищей программистов, особенно старшего поколения. В некоторых случаях вы сможете найти издания, отражающие нормальное стремление разработчика развиваться, такие как «Строго функциональные структуры данных» («Purely Functional Data Structures») и «Многопользовательское программирование для Windows» («Concurrent Programming in Windows»), а не «Как правильно использовать Postit Notes».
Однако на многих полках вы обнаружите доказательство, что программист пытается как можно скорее отрясти бремя прошлого опыта, направляясь в сторону управления. Каждый раз, как мой взгляд останавливается на книге типа «Стремление добиваться результатов в управлении», лежащей на столе программиста, я ощущаю холодок в области позвоночника.
При этом стремление перейти на управленческую должность вполне объяснимо. В нашей индустрии не любят нанимать программистов в возрасте, и у таких специалистов немного шансов получить продвижение. Вы становитесь старшим разработчиком после пяти лет карьеры, что означает возраст 26 лет, если вы успешно начали карьеру после окончания колледжа! Спустя еще несколько лет, если вы не начнете красить волосы и лгать о своем возрасте, вы начинаете более или менее сильно ощущать необходимость карабканья по смазанному салом ярмарочному столбу к туманной цели «стать менеджером». В результате, опыт практической работы уходит вместе со специалистами. Неудивительно, что в Европе потери от провалившихся ИТпроектов достигают поражающих воображение 200 миллиардов долларов.
Мы в индустрии должны понять, что переход на должность менеджера не развитие карьеры, а полная смена типа работы. Хороший программист не обязательно будет хорошим менеджером, часто наоборот. Так почему же мы так ценим управленческий опыт, когда вклад хорошего программиста в успешный бизнес организации ничуть не меньше вклада хорошего менеджера?
Хорошим программистам следует оставаться программистами, нам нужно поощрять их в этом и давать возможность развития и повышения квалификации. Они должны постоянно искать способы улучшения используемых алгоритмов, расширения масштабируемости приложений, оптимизации использования памяти и так далее. Вместо этого, многие программисты по необходимости стремятся овладеть новейшими методиками управления, стараются использовать в разговоре «горячие» термины и фразы типа «bottom line». А тем временем из восьми проектов семь заканчиваются провалом. Вот так.
Получение сведений о ваших базах данных
DOWNLOAD
Введение
Время от времени большинство из нас получает задание «достать некие данные из некой базы данных». Не знаю, происходит ли это только со мной, но меня постоянно просят поработать с базами, о которых я ничего не знаю. Обычно я не имею никакой документации и никаких сведений о модели данных, принципах именования, вообще почти ничего. Обыкновенно у меня есть какаято неопределенная информация о том, что я надеюсь найти, например, «все данные заказчика из нашей старой базы данных Интернетмагазина», и в этом случае я уже ожидаю обнаружить некие обычные связанные таблицы клиентов и заказов, как Customers, Companies, Countries, Orders и т. д. Тем не менее, среди таблиц и столбцов легко заблудиться.
Поэтому, чтобы подготовить некую отправную точку, из которой я смог бы узнать об этих базах данных больше, я создал три небольших хранимых процедуры, каждая из которых дает мне более подробную информацию об объектах, которые я изучаю. Эти вещи с использованием другого инструментария, полагаю, можно было бы исполнить более изящно, но у меня в распоряжении есть только SQL Server 2000.
Идея такова: у вас есть база данных, но вы не знаете, в какие таблицы смотреть, поэтому сначала попытайтесь обнаружить из них интересные (или, по меньшей мере, сократить ваш список кандидатов). Когда вы знаете, какие таблицы исследовать, затем вам нужно узнать, связаны ли эти таблицы какимто образом с другими, поэтому вы выясняете зависимости от них — столько, сколько потребуется (что может быть не всегда очень просто или легко проделать с помощью запросов). Затем вы хотели бы получить представление о том, какие столбцы, вероятнее всего, стоит проверить, поэтому вы пытаете счастье, отыскивая столбцы с похожими названиями.
Результаты, разумеется, очень сильно зависят от ситуации, но поскольку в таблице Items есть, как правило, столбцы с именем, вроде %item%, может иметь смысл проверить таблицы со схожими названиями. В процессе работы список таблицкандидатов будет исследован следующим образом: насколько они велики, какие столбцы содержат, сколько в них различных значений и т. д. Хотя установленные цифры не всегда стопроцентно точны, они достаточны для данной цели — а именно это и имеет сейчас значение. На завершающей стадии останется некоторая ручная работа, связанная с просмотром результатов, но не в огромном количестве.
Поскольку мы надеемся найти таблицы, занимающие центральное место в базе данных, где лежат все «хорошие данные», где много строк и у которых имеется множество зависимостей, мы можем предположить, что в таких таблицах будет, по меньшей мере, несколько столбцов со схожими названиями. Это хорошие кандидаты на рассмотрение. Если я вижу стандартную таблицу заказов (Orders), в ней, по всей вероятности, будет иметься столбец с названием, очень близким к [Customer No.] (номер клиента). Точно такое же название столбца затем, вероятно, будет использоваться гденибудь в другом месте базы данных — везде, где важен заказчик. И это то, что мы ищем в первую очередь.
Предотвращение конфликта на уровне записи за счет ограничения изменений
Существует программный код, которым можно воспользоваться, чтобы не допустить перезаписи внесенных изменений данными из источника данных ASP.NET DataSource.
Чутьчуть программирования, и вы можете избавиться от тех проблем, которые создают источники данных ASP.NET DataSource в том случае, когда двое обращаются к одной и той же записи.
Хорошо, хорошо, много программирования.
Представьте себе, что Сью и Лу одновременно извлекают запись из таблицы Customer. Сью вносит изменения в поле LastName и сохраняет свою версию записи. Прискорбно, но вслед за этим Лу уничтожает внесенное ею изменение, модифицировав поле CustomerCredit перед тем, как сохранить свою версию записи. К сожалению, изменение, внесенное Сью в поле LastName, теперь потеряно, потому что, сохраняя запись Лу, источник данных ASP.NET DataSource обеспечил обновление всех остальных полей в этой записи теми данными, которые извлек Лу перед тем, как свое обновление выполнила Сью. Нехорошо.
Избежать возникновения такой проблемы нетрудно: если бы Лу нужно было обновить одно только поле CustomerCredit, измененное им самим, тогда он не перезаписал бы данные в поле LastName, измененном Сью. Добиться этого можно написав собственный программный код для процедуры обновления.
Но перед тем как приступить к программированию (и ради полноты картины), упомянем один сценарий, который не позволяет ограничиться обновлением одних только изменившихся полей.
Разрешение конфликта на уровне данных с помощью оптимистичного параллелизма
Для большинства таблиц модель оптимистичного параллелизма (optimistic concurrency) не срабатывает. Однако Питер демонстрирует, как можно изменить ситуацию.
Один из способов, позволяющих разрешить конфликт на уровне данных, — обновление данных в источниках DataSource в режиме оптимистичного параллелизма. Однако проблема заключается в том, что в случае большинства таблиц эта модель работать не будет. Вот действия, которые необходимо выполнить, чтобы обеспечит оптимистичный параллелизм, и то, что можете сделать вы, чтобы заставить эту модель работать.
В предыдущей статье из этой рубрики («Предотвращение конфликта на уровне записи за счет ограничения изменений») я описал проблему, возникающую в том случае, когда в вебприложении два пользователя обращаются к одной и той же записи; и предположил, что ее можно решить, если обновлять только те поля записи, которые были изменены. Элемент управления источниками данных ASP.NET DataSource предлагает встроенное решение, которое называется «Оптимистичный параллелизм» («Optimistic Concurrency»). К сожалению, в версиях ASP.NET 2.0/3.5 это решение чаще всего не работает.
Ограничьте себя!
В своей первой статье Джо Селко раскрывает тайну использования ограничений (constraint) и указывает на то, что этот механизм является важным компонентом языка SQL, обеспечивающим отличный способ гарантировать единообразное, в одном месте, однократное применение бизнес-правил. Почти каждый программист баз данных найдет в этой статье что-то новое и полезное.
В тех тематических интернетконференциях, которые я чаще всего посещаю, я сталкиваюсь с необходимостью постоянно напоминать их участникам о том, что строки — это не записи, столбцы — не поля, а таблицы не являются файлами.
После того как я не один десяток лет потратил на обучение языку SQL и написание книг о нем, у меня сложилось твердое убеждение: тому, кто в состоянии перестроить свой образ мыслей и переключиться с процедурного программирования и последовательных файлов на декларативное программирование и множества, язык SQL и моделирование данных даются много, много легче. Это — прозрение, почти равноценное тому, как для процедурного программиста внезапно обретает смысл рекурсия. Если по своему «происхождению» вы являетесь LISPпрограммистом, замените в последнем предложении «рекурсию» на «итерацию».
Часть этого прозрения — осознание того, что языки DDL (Data Declaration Language — язык объявления данных), DML (Data Manipulation Language — язык манипулирования данными) и DCL (Data Control Language — язык управления данными) являются важными составляющими языка SQL, а не отдельными, обособленными языками. В этой статье речь идет о языке DDL, но чем совершеннее язык DDL, тем совершеннее языки DML и DCL. Если бизнесправило сформулировано на языке DDL, способ его выполнения унифицирован, оно выполняется в одном месте, один раз. Вам не надо возлагать надежды на то, что каждое приложение и каждое предложение языка DML правильно выполнят все правила. Вы не должны рассчитывать, что изменение в правилах приведет к необходимости вносить коррективы в сотне или даже тысяче мест в системе.
Что быстрее: SAN или напрямую подключаемое хранилище
Следует ли мне размещать файлы базы данных в сети хранения данных (SAN) или в напрямую подключаемом хранилище? Это часто задаваемый вопрос. Он постоянно возникает в открытых группах новостей, почтовых списках рассылки и при личных встречах с заказчиками, проявляющими интерес к производительности баз данных.
Какая SAN?
Термин «сеть хранения данных» (Storage Area Network — SAN) может подразумевать две различные вещи. Для профессионалов сферы хранения данных он может принимать узкое значение коммутирующей матрицы (набор комутаторов — по версии 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
DOWNLOAD
Как все мы знаем, SQL Server 2005 Express — это очень мощное бесплатное издание SQL Server 2005. Тем не менее оно не содержит службы агента SQL Server. И поэтому планирование заданий невозможно. Таким образом, если мы хотим этим заняться, то вынуждены установить бесплатный или коммерческий продукт производства третьей стороны. Это не всегда позволено в силу политики безопасности многих хостинговых компаний и, следовательно, представляет проблему. Возможно, нам требуется запланировать ежедневное резервное копирование, переиндексацию базы данных, обновление статистики и т. п. Вот почему мне захотелось иметь решение, реализованное только на SQL Server 2005 Express и не зависящее от компании, предоставляющей хостинг. И, разумеется, таковое, основанное на нашем старом друге, — компоненте Service Broker, существует.