Главная » Microsoft SQL Server, Базы данных » Целостность данных — главная проблема, которая возникает в мире баз данных

0

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

Поскольку данные представляют собой сущности и атрибуты, их целостность обеспечивается целостностью сущностей, домена, а также ссылочной и определяемой пользователем целостностью. Целостность транзакций, т.е. порядок записи и извлечения данных, определяется принципами АСЮ (атомарность, постоянство, изоляция и живучесть), о которых мы поговорим далее в этой главе, сбоями транзакций и уровнем изоляции.

Целостность сущностей

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

Дополнительная Подробно нормализация будет описана в главе 2.

информация

Целостность домена

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

Ссылочная целостность

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

В то же время ссылочная целостность является не вопросом целостности первичного ключа, а только связанного с ним внешнего.

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

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

Определенная пользователем целостность

В стороне от требований целостности реляционной теории существует и определяемая пользователем целостность. Она может поддерживаться следующим образом:

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

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

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

?               поиск некорректных данных;

?               поиск неполных данных;

?               поиск сомнительных данных;

?               поиск несогласованных данных.

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

Целостность транзакций

Транзакцией называется единый логический блок работы, например вставка 100 строк, обновление 1000 строк или выполнение логической цепочки обновлений. Качество продукта базы данных зависит от того, насколько его возможности выполнения транзакций соответствуют принципам АСШ. Как вы помните, эта аббревиатура расшифровывается как четыре взаимозависимых свойства: атомарность, целостность, изоляция и живучесть. Большая часть архитектуры SQL Server основана именно на этих свойствах, поэтому, чтобы понять SQL Server, нужно усвоить их значение.

?               Свойство атомарности подразумевает, что транзакция должна либо выполниться вся, либо не выполниться в целом. В конце транзакции она должна быть либо подтверждена, либо отменена. Если частично выполненная транзакция записывается на диск, то свойство атомарности нарушается.

?               Транзакция должна поддерживать целостность базы данных. Это значит, что транзакция начинает выполняться, когда база данных находится в целостном состоянии, при этом база должна остаться в целостном состоянии и после завершения транзакции. С точки зрения АСЮ целостность означает, что каждая строка и значение должны соответствовать моделируемой реальной ситуации, а все ограничения должны выполняться. Например, если заголовок заказа записан на диск, а строки заказанных в нем товаров — нет, то нарушается ссылочная целостность.

?               Каждая транзакция должна быть изолирована, т.е. отделена от эффекта выполнения других транзакций. Независимо от того, что выполняет другая транзакция, первая должна иметь возможность продолжать работать с тем же набором данных, с которым начала. Изоляция является своеобразным забором между двумя транзакциями. Доказательством наличия изоляции является возможность многократно повторить последовательный набор транзакций над одним и тем же набором данных и каждый раз получить один и тот же результат.

В качестве примера предположим, что некоторый Вася обновляет 100 строк. Пока его транзакция выполняется, некий Петя удалил одну из строк, над которыми работает Вася. Если такое удаление может произойти, значит, транзакция Васи не изолирована от транзакции Пети. Это свойство не так критично, если с базой данных работает всего один пользователь, однако в многопользовательской среде оно приобретает весомое значение.

?               Понятие живучести транзакции относится к ее выполнению независимо от системных сбоев. После того как транзакция будет подтверждена, она остается подтвержденной. СУБД должна быть спроектирована так, чтобы базу данных можно было восстановить до состояния последней полностью выполненной транзакции, даже если устройство данных даст сбой.

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

Архитектура SQL Server поддерживает все свойства АСЮ целостности транзакций. Это значит, что разработчику нужно понимать их, чтобы при создании баз данных взять на вооружение все возможности SQL Server, а администратору баз данных это поможет реализовать хороший план восстановления. Если вы объедините возможности SQL Server, аппаратного и программного обеспечения, модели базы данных, планов восстановления и обслуживания базы данных, то получите великолепный результат. Когда разработчик и администратор сотрудничают, чтобы правильно организовать эти компоненты, база данных работает отлично, а целостность транзакций высокая.

Ошибки транзакций

Понятие полной изоляции подразумевает, что одна транзакция никогда не помешает работе другой. Если изоляция полная, то все изменения, происходящие вне транзакции, она не увидит.

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

“Грязное” чтение

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

Неповторяющееся чтение

Неповторяющееся чтение аналогично “грязному”, однако оно происходит, когда одна транзакция в процессе работы видит подтвержденные в это время обновления другой транзакции. Чтение строки внутри транзакции всегда должно выдавать одни и те же результаты. Если при последовательных чтениях получаются разные результаты, значит, в транзакции произошла ошибка неповторяющегося чтения.

Призрачные строки

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

Среди всех ошибок “грязное” чтение можно назвать самым опасным, неповторяющееся чтение — немного менее опасным, и практически самыми безобидными являются призрачные строки.

Потерянные обновления

Потерянные обновления происходят, когда два пользователя редактируют одну и ту же строку, завершают свою работу и сохраняют данные. При этом обновления, которые были выполнены и сохранены первыми, заменяются обновлениями, сохраненными вторыми.

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

Взаимоблокировки

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

?               Первая транзакция блокировала данные А и собирается для своего завершения блокировать данные Б.

?               В то же время вторая транзакция блокировала данные Б и собирается для своего завершения блокировать данные А.

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

Дополнительная В главе 51 будут приведены примеры ошибок транзакций, уровней изоляции информаций и блокировок в SQL Server.

Уровни изоляции

На физическом уровне любое ядро базы данных, допускающее логические транзакции, должно содержать механизмы изоляции. Для контроля, какие ошибки транзакций допустимы, существуют уровни изоляции, т.е. образно говоря, высота “забора” между ними. В спецификации ANSI SQL-92 определены четыре уровня изоляции:

?               Read uncommited

?               Read commited

?               Repeatable read;

?               Serializable.

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

Пустые значения

Реляционные базы данных всегда представляют отсутствие данных с помощью специального пустого значения null. На самом деле null представляет три совершенно различных сценария отсутствия данных.

?               Столбец не задействован в данной строке. Например, если человек не устроен на работу, значит, какое-либо определенное значение в столбце даты приема на работу будет некорректным.

?               Данные еще не введены, но вскоре это будет сделано. Например, если контактное лицо имеет имя и номер телефона, а адрес будет введен в процессе приема заказа.

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

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

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

Работа с пустыми значениями

В связи с тем что пустое значение подразумевает неизвестность такового, результат любого выражения, включающего в себя значение null, также не может быть известен. Например, если состояние банковского счета неизвестно, а он включен в сумму общих доходов, то эта сумма также будет неизвестна. Та же концепция внедрена и в SQL Server. Как сказал известный разработчик баз данных Фил Сенн: “Пустое значение прекращает жизнь любого другого”. Например, результатом выражения SELECT 1+NULL будет NULL.

Еще одним следствием неопределенности пустого значения является то, что одно значение NULL не может быть равно другому. По этой причине для проверки наличия пустого значения в языке SQL введена специальное выражение IS NULL.

Однако такой стандартный режим работы может быть нарушен. SQL Server будет игнорировать присутствие пустого значения в выражении, если установить для параметра concat_null_yelds_null значение off. Другое выражение, ANSI nulls, управляет тем, будет ли одно пустое значение считаться равным другому.

Противоречивость пустого значения

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

Крайние апологеты “чистоты” баз данных не одобряют пустые значения и в любой создаваемой базе данных запрещают их. Еще один метод предполагает вынесение всех столбцов, принимающих пустые значения, в отдельную таблицу. Этот метод всего лишь заменяет столбцы, принимающие значения NULL, строками, что требует введения левого внешнего объединения для проверки наличия или отсутствия значения. Сложность такого подхода не только снижает производительность, но и отрицательно сказывается на целостности данных. Вместо извлечения данных с пустым столбцом разработчику нужно дополнительно проверить наличие левого внешнего объединения со специализированной таблицей. Такой подход является свидетельством недостаточного понимания принципов единства хранилища данных, целостности данных, их полезности и излишних затрат ресурсов компьютера.

Источник: Нильсен, Пол. Microsoft SQL Server 2005. Библия пользователя. : Пер. с англ. — М. : ООО “И.Д. Вильямс”, 2008. — 1232 с. : ил. — Парал. тит. англ.

По теме:

  • Комментарии