|
Программирование >> Проектирование баз данных
Рис. 6.2. Таблица с первичным ключом, который полностыо уникален Теперь, даже если значения системных даты и времени по какой-то причине сдвинутся назад (например, при переходе на зимнее время), столбец VERSION* сообщит нам истинную последовательность версий. Учтите, что дефекты такого рода (когда записи могут расположиться в неправильном порядке) очень легко предотвратить, но довольно сложно исправить после сдачи системы в эксплуатацию. Описанный нами подход обеспечивает уникальность первичного ключа. Однако при этом все равно остались ловущки, которые в некоторых ситуациях могут вызвать неприятности. Например, присвоить новый номер версии, имея такую структуру, не так просто, как может показаться на первый взгляд, особенно если вы хотите, чтобы номера версий каждого файла всегда назначались в возрастающем порядке без пропусков значений. Чаще всего номер следующей версии будут пытаться определить с помощью такого запроса: SELECT МАХ(version*) + X FROM 30urce code WHERE directory = :id AND filename = :f; Операция чтения осуществляется здесь без блокировки, поэтому один и тот же ответ могут получить несколько пользователей. Даже если вы уже выполнили операцию SELECT FOR UPDATE над файлом, который вы считаете последней версией, это не помешает другому пользователю выдать запрос SELECT МАХ().-. и получить такой же номер версии. В результате два пользователя одновременно могут пытаться создать одну и ту же версию, и один из них потерпит неудачу из-за нарушения ограничения UNIQUE. Возможна также ситуация, в которой нескольким модулям нужно извлечь последнюю (только последнюю) версию конкретного файла. Чтобы найти ее, придется воспользоваться приблизительно таким запросом: SELECT . . , FROM source code WHERE directory = :id AND filename = :f AND version* = (SELECT MAX(з2.version*) FROM 3ource code s2 WHERE з2.directory = :id AND з2.filename = :f); Давайте проанализируем этот запрос. Он не очень эффективен, хотя в последних версиях скорость его выполнения и увелртчилась. Это является следствием того, что в нем производится два поиска в индексе по первичному juiio4y. Если вы читали предыдущую главу, то наверняка поймете, что, во-первых, таблицу SOURCE CODE следует назвать SOURCE CODE VER-SIONS (ВЕРСИИ ИСХОДНОГО КОДА) и, во-вторых, следует ввести новую таблицу SOURCE CODE для хранения всех атрибутов файла, приемлемых для каждой версии. Теперь мы можем ввести в эту главную таблицу производный столбец для регистрации номера последней версии исходного кода. Примечание Обратите внимание на область определения 2 данного запроса. Учитывая то, как Oracle разрешает имена, рекомендуется всегда использовать такой подход для подзапросов. Отметим также, что в подзапросе связанные переменные должны использоваться повторно. Если сделать его коррелирующим, это повлечет за собой полное сканирование таблицы (по крайней мере, в версии 7.2). После создания новой таблицы (а она почти наверняка потребуется в любом случае) и добавления производного столбца вместо предыдущего запроса можно использовать следующий: SELECT ... FROM source code s , source code versions v WHERE s.directory = :d AND s.filename = :f AND V.directory = s.directory AND V.filename = s.filename AND V.version* = s.latest version#; Итак, теперь у нас есть абсолютно эффективный способ ведения номера версии. Если выполнить запрос SELECT FOR UPDATE к соответствующей строке таблицы SOURCE CODE, то можно выполнить вставку в SOUR-CE CODE VERSIONS и обновление в SOURCE CODE, обеспечив при этом и целостность данных, и эффективность действия. Если вы считаете это решение неэффективным, попробуйте написать запрос на поиск номера последней версии для каждого файла, используя как однотабличную реализацию, так и решение с двумя таблицами, главной и справочной. Замена длинных каскадных ключей суррогатными Выше мы говорили о том, что следует подвергать сомнению все синтетические, или суррогатные, первичные ключи, введенные в процессе анализа. Давайте рассмотрим противоположную ситуацию. Иногда в процессе Проектирования оправданной является замена реального первичного ключа. Полученного при анализе, суррогатным. Зачем это делается? В реляционных системах первичный ключ играет двоякую роль. Он служит для обеспечения уникальности строк, благодаря чему две строки в одной таблице не могут иметь одинаковый первичный ключ. Кроме того, его значение используется для ссылки на строку - в частности, когда он является внешним ключом в другой таблице. В этом качестве он выполняет ту же функцию, что и указатель в сетевой базе данных, Если первичный ключ состоит более чем из одного столбца, его называют составным, и каждый его компонент должен быть представлен во внешнем ключе,* Если ключ используется как внешний (данная таблица связана с родительской или главной) и состоит, например, более чем из четырех компонентов, то он становится громоздким как по объему данных, хранящихся в дочерних записях, так и по объему SQL-кода, необходимого для соединения этих таблиц. В таком случае стоит рассмотреть возможность ввода в таблицу суррогатного первичного ключа. Его обычно называют <сокращенное название таб-лицы> 1Т> или просто ID, а значения этого ключа генерируются, как правило, при помощи последовательности. Таблицы с большими составными первичными ключами часто образуются из длинной иерархии сущностей, у которых ключи наследуются. Другими словами, когда для нескольких уровней иерархии внешний ключ родительской таблицы образует часть первичного ключа дочерней. Это иллюстрируется на рис. 6,3 (обратите внимание на переход от COUNTRY к BUILD-ING CONTRACTOR), HOUSE виШШ CONTRACTOR Number STREET Name TOWN Name REGION COUNTRY Name Name Рис. 6.3. Длинное наследование компонента первичного ключа В этом примере сущность COUNTRY ( Страна ) имеет простой атомарный ключ - название страны. Сущность REGION ( Область ) внутри страны уникально идентифицируется ее отношением с сущностью COUNTRY (столбец внешнего ключа F CO NAME) и названием области. Это необходимо потому, что в двух странах могут быть области с одинаковыми С некоторыми неочевидными исключениями, которые мы опишем в главе 7,
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |