Генераторы - лучшие друзья первичных ключей
Генераторы - лучшие друзья первичных ключей
Надо сказать несколько слов о реализации первичного ключа. Так как он предназначен для обеспечения уникальности, то никакие две записи в одной таблице не могут иметь одинаковых значений этого ключа. То есть, чтобы удовлетворить этому условию, при занесении новой записи в таблицу InterBase должен просмотреть все записи в таблице и выяснить, нет ли уже таких значений в таблице. Для быстрого поиска в InterBase существует механизм индексов - специальных объектов InterBase, которые позволяют очень быстро найти запись в таблице. Поэтому при создании и удалении первичного ключа создается или удаляется индекс на то поле (или поля), которое входит в первичный ключ.
Как уже было сказано, первичный ключ может содержать несколько полей. При этом будет отслеживаться уникальность сочетания значений этих полей. Например, если мы определим ключ на поля ID и NAME, то сервер будет следить за тем, чтобы во всей таблице не было одинаковых сочетаний этих полей. То есть сочетания полей ID и NAME вроде 1 и "Иванов", 2 и "Иванов" будут корректными, поскольку они отличаются значениями поля ID.
Таким образом, первичный ключ может включать несколько полей любых типов. Однако на практике самым распространенным видом ключа является счетчик - целочисленное поле, которое содержит увеличивающиеся значения.
Почему так? Это является отражением давнего спора между естественными и суррогатными ключами. Концепция естественных ключей утверждает, что в качестве ключа надо стараться использовать значения, реально существующие в предметной области, которую отражает база данных. Например, если мы разрабатываем систему учета людей для паспортного стола, то согласно этой концепции необходимо в качестве первичного ключа взять сочетание номера и серии паспорта. Действительно, каждый человек должен иметь свое уникальное сочетание номера и серии паспорта. Однако как быть с тем, что человек может поменять паспорт в течение жизни (в связи с достижением определенного возраста, при заключении брака и т. д.)? В этом случае нам будет необходимо сменить номер и серию паспорта, поставленные в соответствие конкретному человеку, т. е. фактически, сменить наш первичный ключ. Эго нежелательно с точки зрения разработки приложений баз данных: при разветвленной системе связей между таблицами (этому посвящена следующая глава) может понадобиться слишком много усилий разработчика для отслеживания этой ситуации.
Поэтому в большинстве случаев используется суррогатный ключ. Суррогатный - значит искусственный, т. е. не существующий в предметной области, которую описывает наша база данных, а созданный искусственно - для удобства разработки приложений базы данных.
Как уже было сказано, обычно первичным ключом является счетчик. Некоторые СУБД, такие, как Paradox и MS SQL, имеют специальный тип - счетчик (auto increment). При добавлении в таблицу новой записи значение поля с этим типом автоматически увеличивается на величину приращения - обычно на единицы. В InterBase нет поля типа счетчик, однако есть возможность реализовать подобное поведение. Для создания поля, которое бы заполнялось автоматически при добавлении записи в таблицу, используется совокупность средств: первым из них является генератор.
Что такое генератор! Говоря по-простому, генератор - это именованный счетчик. Внутри базы данных мы можем создать счегчик, дать ему уникальное имя в пределах этой базы и управлять значениями этого счетчика. Это и будет генератор. Чтобы это пояснить - вот пример предложений DDL:
CREATE GENERATOR gl;
SET GENERATOR gl TO 2445;
В этом примере в первой строчке в базе данных создается генератор с именем gl, а во второй - этому генератору присваивается значение 2445. Теперь возникает вопрос, как нам использовать полученный генератор. Чтобы получать и изменять значения генераторов, существует встроенная в InterBase функция GEN_ID. Эта функция принимает в качестве параметров имя генератора и величину приращения, которую нужно применить к данному генератору, а возвращает целочисленное значение, соответствующее значению генератора, полученному в результате прибавления к нему приращения. Вот пример вызова функции GEN_ID в тригере или хранимой процедуре:
Current_value = GEN_ID (gl, 1)
Чтобы получить значение генератора в клиентском приложении, можно воспользоваться таким запросом:
SELECT GEN_ID(gl, 1)FROM
RDB$ DATABASE
Так как в таблице RDB$ Database всегда содержится только одна запись, то мы получим в результате данного запроса значение генератора gl.
Здесь current_value - переменная (как использовать переменные в InterBase - см. в следующих главах), gl - генератор, 1 -приращение. В этом примере в переменную current_value попадет значение генератора gl после прибавления к нему приращения 1, т. е. следующее значение генератора!
Обратите внимание, что приращение может быть не равно единице! Более того, оно может быть даже отрицательным:
Current_value = GEN_ID (gl, -23)
В результате выполнения этой функции текущее значение генератора gl уменьшиться на 23. Как видите, диапазон возможных применений генераторов довольно широк - его можно использовать не только для получения значений первичных ключей, но и для отслеживания глобальных изменений в базе данных.
Люди, знакомые с базами данных, могут задать вопрос: "А что будет, если одновременно несколько клиентов попробуют внести данные в одну и ту же таблицу и одновременно "дернут" генераторы? Получат ли они одно или разные значения генератора?" Однозначно, что они получат РАЗНЫЕ значения генератора. Какой бы "одновременной" ни была попытка получить значение генератора, каждый обратившийся получит свое уникальное значение. Это гарантируется самой "конструкцией" генераторов: они работают на самом низком уровне сервера и никакие процессы записи и вставки не влияют на них - часто говорят, что генераторы работают "вне контекста транзакций". Что такое транзакции, вы можете узнать в главе "Транзакции. Параметры транзакций" (ч. 1), а как устроены генераторы - в главе "Структура базы данных InterBase" (ч. 4).
Ну хорошо, в лице генераторов мы имеем надежный механизм для формирования уникальных первичных ключей. Однако как же нам воспользоваться этим механизмом? Как поместить получаемое от генератора значение в поле первичного ключа?
Для этого есть два способа - вставка первичного ключа на стороне клиента и на стороне сервера. Чтобы освоить первый способ, следует обратиться к главе "Использование основных компонентов FIBPlus", а чтобы понять второй - к главе "Триггеры" (ч. 1). Здесь мы лишь кратко скажем, в чем заключается суть обоих способов.
В случае формирования первичного ключа на клиенте происходит следующее. Когда сформирована запись, которая будет вставлена в базу данных, выполняется вызов функции GEN_ID(<имя генератора>,1) и полученное значение подставляется в сформированную запись. Происходит вставка в таблицу, при этом мы получаем гарантированно уникальный первичный ключ.
Второй способ - формирование первичного ключа на стороне сервера - вообще исключает всякую заботу на стороне клиента о том, каково будет значение первичного ключа. В этом случае при вставке записи срабатывает триггер - специальный объект базы данных, который может осуществлять какие-либо действия при вставке/удалении/изменении записей в таблицах. И в этом триггере происходит вызов функции GEN_ID, получение нужного значения генератора и вставка его в таблицу.
Достоинством второго способа является то, что при разработке клиентского приложения совершенно не надо заботиться о формировании первичного ключа, достаточно лишь раз написать нужный триггер. Но его недостатком является то, что мы не можем получить в приложении значение сформированного ключа сразу после вставки! При использовании первого способа мы, хотя и сами должны каждый раз при вставке первичного ключа заботиться о его формировании, можем получить его значение. Какой способ лучше - однозначно сказать нельзя, все зависит от конкретной задачи, но возможные варианты разрешения вопросов работы с первичным ключом будут еще не раз затронуты далее в этой книге.
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКЧитайте также
Онлайн-генераторы
Онлайн-генераторы www.csssprites.com. Обладает довольно минималистичным дизайном, есть возможность загружать несколько исходных файлов.www.printf.ru/spritr/. В этом инструменте есть возможность загружать несколько файлов, очень милый дизайн, но в целом настроек мало.spritegen.website-performance.org.
9.2. Генераторы паролей
9.2. Генераторы паролей Генераторы паролей используются для создания особо сложных и длинных паролей. Генераторов паролей – несчетное множество. Каждый школьник, обладая начальными навыками программирования, может создать программу, генерирующую случайную
Глава 14 Оформление и учет первичных документов
Глава 14 Оформление и учет первичных документов К достоинствам программы «1С: Предприятие 7.7» можно отнести возможность оформления большого количества первичных документов, таких как платежное поручение, приходный и расходный кассовые ордера, доверенность, авансовый
Генераторы текстур
Генераторы текстур В состав Filters Unlimites входит несколько генераторов текстур. Подобные эффекты больше всего пригодятся разработчикам трехмерных игр и других 3D-проектов.При помощи фильтров категории Paper Backgrounds (Фон бумаги) можно создать текстуру поверхности любого типа
R.11.4 Друзья
R.11.4 Друзья Другом класса называется функция, которая не является членом класса, но в которой можно использовать частные и защищенные члены этого класса. Имя друга не принадлежит области видимости класса, и дружественная функция не вызывается с помощью операций доступа к
Использование других методов для генерации первичных ключей
Использование других методов для генерации первичных ключей Вовсе не обязательно, чтобы каждая таблица имела первичный ключ, но в практическом отношении желательно, чтобы было именно так. Важность первичного ключа в таблице трудно переоценить. Как отмечалось в
15.3. Генераторы специализированного кода
15.3. Генераторы специализированного кода Unix имеет давнюю традицию поддержки инструментов, которые специально предназначены для генерации кода для различных специальных целей. Давними "монументами" данной традиции, которые "уходят корнями" в Version 7 и ранние дни Unix, а также
15.3. Генераторы специализированного кода
15.3. Генераторы специализированного кода Unix имеет давнюю традицию поддержки инструментов, которые специально предназначены для генерации кода для различных специальных целей. Давними "монументами" данной традиции, которые "уходят корнями" в Version 7 и ранние дни Unix, а также
Генераторы перестановок (Permutation generators)
Генераторы перестановок (Permutation generators) template ‹class BidirectionalIterator›bool next_permutation(BidirectionalIterator first, BidirectionalIterator last);template ‹class BidirectionalIterator, class Compare›bool next_permutation(BidirectionalIterator first, BidirectionalIterator last, Compare comp);next_permutation берёт последовательность, определённую диапазоном [first, last), и
Аддитивные генераторы
Аддитивные генераторы Второй стандартный метод получения "более случайных" чисел от простого генератора называется аддитивным.В соответствии с этим методом, мы инициализируем массив чисел с плавающей запятой с помощью простого генератора, например, минимального
Тасующие генераторы
Тасующие генераторы И последний тип рассматриваемых нами генераторов, позволяющих получать "более случайные" числа, принадлежит к алгоритмам тасования. Здесь мы опишем генератор, реализованный на основе одного внутреннего генератора, хотя существуют и другие
Генераторы
Генераторы Генераторы являются идеальным средством для создания значений автоинкрементных уникальных ключей или серий значений числового столбца, а также других серий. Генераторы в базе данных объявляются оператором CREATE, как и любой другой объект базы данных:CREATE GENERATOR
Дмитрий Вибе: Лучшие друзья девушек Дмитрий Вибе
Дмитрий Вибе: Лучшие друзья девушек Дмитрий Вибе Опубликовано 16 сентября 2011 года Поводом послужила статья Мэтью Бэйлеса из Суинборнского технологического университета (Австралия) и его коллег об открытии действительно весьма необычного
Генераторы Adobe Audition
Генераторы Adobe Audition