<? include 'head.php' ?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html><head>
<link rel="stylesheet" href="css.css" type="text/css">
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<meta http-equiv="Content-Language" content="ru">
<title>Глава 22.</title></head>
<body>
<h1>Глава 22. КТО И ЧТО МОЖЕТ ДЕЛАТЬ<br>
В БАЗЕ ДАННЫХ?</h1>
<hr width="50%">
<p>В этой главе вы научитесь работать с привилегиями. Как сказано в
<a href="ch2.php">Главе 2</a>, SQL используется обычно в средах, которые 
требуют распознавания пользователей и различий между пользователями систем.</p>
<p>Вообще говоря, администраторы баз данных сами создают пользователей и дают им 
привилегии.<br>
С другой стороны - пользователи, которые создают таблицы, сами имеют 
права на управление этими таблицами. Привилегии это то, что определяет, может ли 
указанный пользователь выполнить данную команду. Имеется несколько типов 
привилегий, соответствующих нескольким типам операций. Привилегии даются и 
отменяются двумя командами SQL: GRANT (ДОПУСК) и REVOKE (ОТМЕНА). Эта глава 
покажет вам, как эти команды используются.</p>
<h3><a name="22.1">П</a>ОЛЬЗОВАТЕЛИ</h3>
<p>Каждый пользователь в среде SQL имеет специальное идентификационное имя или 
номер. Терминология везде разная, но мы выбрали (следуя ANSI) ссылку на имя или 
номер как на Идентификатор (ID) доступа. Команда, посланная в базе данных, 
ассоциируется с определённым пользователем; или иначе - специальным 
Идентификатором доступа. Поскольку это относится к БД SQL, ID разрешения это имя 
пользователя, и SQL может использовать специальное ключевое слово USER, которое 
ссылается на Идентификатор доступа, связанный с текущей командой. Команда 
интерпретируется и разрешается (или запрещается) на основе информации, связанной 
с Идентификатором доступа пользователя, подавшего команду.</p>
<h3><a name="22.2">Р</a>ЕГИСТРАЦИЯ</h3>
<p>В системах с многочисленными пользователями имеется некоторый вид процедуры 
входа в систему, которую пользователь должен выполнить, чтобы получить доступ к 
компьютерной системе. Эта процедура определяет, какой ID доступа будет связан с 
текущим пользователем. Обычно каждый человек, использующий БД, должен иметь свой 
собственный ID доступа и при регистрации превращается в действительного 
пользователям. Однако часто пользователи, имеющие много задач, могут 
регистрироваться под различными ID доступа, или наоборот - один ID доступа может 
использоваться несколькими пользователями. С точки зрения SQL нет никакой 
разницы между этими двум случаями; он воспринимает пользователя просто как его 
ID доступа.</p>
<p>БД SQL может использовать собственную процедуру входа в систему или 
она может позволить другой программе, вроде операционной системы (основная 
программа которая работает на вашем компьютере), обрабатывать файл регистрации и 
получать ID доступа из этой программы. Тем или другим способом, но SQL будет 
иметь ID доступа, чтобы связать его с вашими действиями, а для вас будет иметь 
значение ключевое слово USER.</p>
<h3><a name="22.3">П</a>РЕДОСТАВЛЕНИЕ ПРИВИЛЕГИЙ</h3>
<p>Каждый пользователь БД SQL имеет набор привилегий. Это то, что пользователю 
разрешается делать (возможно это - файл регистрации, который может 
рассматриваться как минимальная привилегия). Эти привилегии могут изменяться со 
временем: новые - добавляться, старые - удаляться. Некоторые из этих привилегий 
определены в ANSI SQL, но имеются и дополнительные привилегии, которые  также 
являются необходимыми.</p>
<p>SQL-привилегий, как определено ANSI, недостаточно в 
большинстве ситуаций реальной жизни. С другой стороны, типы привилегий, которые 
необходимы, могут видоизменяться, в зависимости от используемой системы, 
относительно которой ANSI не может дать никаких рекомендаций. Привилегии, 
которые не являются частью стандарта SQL, могут использовать похожий синтаксис, 
не полностью совпадающий со стандартом.</p>
<h3><a name="22.4">С</a>ТАНДАРТНЫЕ ПРИВИЛЕГИИ</h3>
<p>SQL-привилегии, определённые ANSI, это привилегии объекта. Это означает, что 
пользователь имеет привилегию для выполнения данной команды только на 
определенном объекте в БД. Очевидно, что привилегии должны различать эти 
объекты, но система привилегий, основанная исключительно на привилегиях объекта, 
не может адресовать всё, что нужно SQL, как мы увидим позже в этой главе.</p>
<p>Привилегии объекта связаны одновременно и с пользователями, и с таблицами. То 
есть привилегия дается определенному пользователю в указанной таблице, базовой 
таблице или представлении. Вы должны помнить, что пользователь, создавший 
таблицу (любого вида), является владельцем этой таблицы.</p>
<p>Это означает, что пользователь имеет все привилегии в этой таблице и может 
передавать привилегии другим пользователям  этой таблицы.</p>
<p>Вот привилегии, которые можно назначить пользователю:</p>
<pre>SELECT         Пользователь может выполнять запросы в таблице.

INSERT         Пользователь может выполнять команду INSERT в таблице.

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

DELETE	       Пользователь с этой привилегией может выполнять команду DELETE в таблице.

REFERENCES     Пользователь определить внешний ключ, который использует один или более
               столбцов этой таблицы, как родительский ключ.
               Вы можете ограничить эту привилегию для определённых 
	       столбцов. (Смотрите в <a href="ch19.php">Главе 19</a> 
	       подробности относительно внешнего ключа и родительского ключа.)</pre>
<p>Кроме того, вы столкнётесь с такими нестандартными привилегиями объектов, 
как, например, INDEX (ИНДЕКС), дающей право создавать индекс в таблице, SYNONYM 
(СИНОНИМ), дающей право создавать синоним для объекта, который будет объяснён в
<a href="ch23.php">Главе 23</a>, и ALTER (ИЗМЕНИТЬ), дающей право выполнять 
команду ALTER TABLE в таблице.</p>
<p>Механизм SQL назначает пользователям эти 
привилегии с помощью команды GRANT.</p>
<h3><a name="22.5">К</a>ОМАНДА GRANT</h3>
<p>Предположим, что пользователь Diane имеет таблицу Заказчиков и хочет 
разрешить пользователю Adrian выполнить запрос к ней. Diane должна в этом случае 
ввести следующую команду:</p>
<pre>GRANT INSERT ON Salespeople TO Diane;</pre>
<p>Теперь Adrian может выполнить запросы к таблице Заказчиков. Без этой привилегии он 
может только выбирать значения, но не может выполнить любое действие, которые  влияло 
бы на значения в таблице Заказчиков (включая использование таблицы 
Заказчиков в качестве родительской таблицы внешнего ключа, что ограничивает 
изменения, которые можно выполнять со значением в таблице Заказчиков).</p>
<p>Когда SQL получает команду GRANT, он проверяет привилегии пользователя, 
подавшего эту команду, чтобы определить, допустима ли команда GRANT.</p>
<p>Adrian 
самостоятельно не может выдать эту команду. Он также не может предоставить право 
SELECT другому пользователю: таблица еще принадлежит Diane (далее мы покажем, 
как Diane может дать право Adrian предоставлять SELECT другим пользователям).</p>
<p>Синтаксис - тот же самый, что и для предоставления других привилегий. Если 
Adrian - владелец таблицы Продавцов, то он может позволить Diane вводить в неё 
строки с помощью следующего предложения:</p>
<pre>GRANT INSERT ON Salespeople TO Diane;</pre>
<p>Теперь Diane имеет право помещать нового продавца в таблицу.</p>
<h4>ГРУППЫ ПРИВИЛЕГИЙ. ГРУППЫ ПОЛЬЗОВАТЕЛЕЙ.</h4>
<p>Вы не обязаны ограничивать себя предоставлением единственной привилегии 
отдельному пользователю командой GRANT. Списки привилегий или пользователей, 
разделяемых запятыми, являются совершенно приемлемыми.</p>
<p>Stephen может 
предоставить и SELECT, и INSERT в таблице Заказов для Adrian:</p>
<pre>GRANT SELECT, INSERT ON Orders TO Adrian;</pre>
<p>или и для Adrian, и для Diane:</p>
<pre>GRANT SELECT, INSERT ON Orders TO Adrian, Diane;</pre>
<p>Когда привилегии и пользователи перечислены таким образом, весь список 
привилегий предоставляется всем указанным пользователям. В строгой ANSI 
интерпретации вы не можете предоставить привилегии во многих таблицах сразу 
одной командой, но в некоторых реализациях это ограничение может быть ослаблено, 
что позволяет указывать несколько таблиц, отделяя их запятыми, так чтобы весь 
список привилегий мог быть предоставлен для всех указанных таблиц.</p>
<h4>ОГРАНИЧЕНИЕ ПРИВИЛЕГИЙ НА ОПРЕДЕЛЕННЫЕ СТОЛБЦЫ</h4>
<p>Все привилегии объекта используют один и тот же синтаксис, кроме команд UPDATE 
и  REFERENCES, в которых не обязательно указывать имена столбцов.</p>
<p>Привилегию UPDATE можно предоставлять наподобие других привилегий:</p>
<pre>GRANT UPDATE ON Salespeople TO Diane;</pre>
<p>Эта команда позволит Diane изменять значения в любом или во всех столбцах 
таблицы Продавцов. Однако, если Adrian хочет ограничить Diane в изменении, 
например, комиссионных, он может ввести:</p>
<pre>GRANT UPDATE (comm) ON Salespeople TO Diane;</pre>
<p>Другими словами, он просто должен указать конкретный столбец, к которому 
привилегия UPDATE должна быть применена, в круглых скобках после имени таблицы. 
Имена нескольких столбцов таблицы могут указываться в любом порядке, отделяемые 
запятыми:</p>
<pre>GRANT UPDATE (city, comm) ON Salespeople TO Diane;</pre>
<p>REFERENCES следует тому же самому правилу. Когда вы предоставите привилегию 
REFERENCES другому пользователю, он сможет создавать внешние ключи, ссылающиеся 
на столбцы вашей таблицы как на родительские ключи. Подобно UPDATE, для 
привилегии REFERENCES может быть указан список из одного или более столбцов, для 
которых ограничена эта привилегия. Например, Diane может предоставить Stephen 
право использовать таблицу Заказчиков как таблицу родительского ключа с помощью 
такой команды:</p>
<pre>      GRANT REFERENCES (cname, cnum)
         ON Customers TO Stephen;</pre>
<p>Эта команда дает Stephen право использовать столбцы cnum и cname в качестве 
родительских ключей по отношению к любым внешним ключам в его таблицах. Stephen 
может контролировать то, как это будет выполнено. Он может определить (cname, 
cnum) или,  в нашем случае, (cnum, cname), как двухстолбцовый родительский 
ключ, совпадающий с помощью внешнего ключа с двумя столбцами в одной из его 
собственных таблиц. Или он может создать раздельные внешние ключи, чтобы 
ссылаться на поля индивидуально, обеспечив тем самым, чтобы Diane имела 
принудительное присвоение родительского ключа (см. <a href="ch19.php">Главу 19</a>).</p>
<p>Не имея ограничений на количество внешних ключей, он должен базироваться на этих 
родительских ключах, а родительские ключи различных внешних ключей разрешены для 
перекрытия (overlap).</p>
<p>Как и в случае с привилегией UPDATE, вы можете исключить список столбцов и 
таким образом позволить всем без исключения столбцам быть используемыми в 
качестве родительских ключей.</p>
<p>Adrian может предоставить Diane право сделать это 
следующей командой:</p>
<pre>GRANT REFERENCES ON Salespeople TO Diane;</pre>
<p>Естественно, привилегия будет пригодна для использования только в столбцах, 
которые имеют ограничения, требуемые для родительских ключей.</p>
<h3><a name="22.6">И</a>СПОЛЬЗОВАНИЕ АРГУМЕНТОВ ALL И PUBLIC</h3>
<p>SQL поддерживает два аргумента для команды GRANT, которые имеют специальное 
значение: ALL PRIVILEGES (ВСЕ ПРИВИЛЕГИИ), или просто ALL, и PUBLIC (ОБЩИЕ).</p>
<p>ALL 
используется вместо имён привилегий в команде GRANT, чтобы передать все привилегии 
в таблице.</p>
<p>Например, Diane может выдать Stephen весь набор привилегий в таблице 
Заказчиков с помощью такой команды:</p>
<pre>GRANT REFERENCES ON Salespeople TO Diane;</pre>
<p>(привилегии UPDATE и REFERENCES, естественно, применяются ко всем столбцам.)</p>
<p>А это другой способ высказать ту же мысль:</p>
<pre>GRANT ALL ON Customers TO Stephen;</pre>
<p>PUBLIC больше похож на тип аргумента - он захватывает всё (catch-all), - чем 
на пользовательскую привилегию.</p>
<p>Когда вы предоставляете привилегии для 
публикации, все пользователи автоматически их получают. Наиболее часто это 
применяется для привилегии SELECT в определённых базовых таблицах или 
представлениях, которые вы хотите сделать доступными для любого пользователя. 
Чтобы позволить любому пользователю видеть таблицу Заказов, вы, например, можете 
ввести следующее:</p>
<pre>GRANT SELECT ON Orders TO PUBLIC;</pre>
<p>Конечно, вы можете предоставить любые или все привилегии каждому, но это, 
очевидно, нежелательно. Все привилегии, за исключением SELECT, позволяют 
пользователю изменять (или, в случае REFERENCES, ограничивать) содержание 
таблицы. Разрешение всем пользователям изменять содержание ваших таблиц создаст проблемы.</p>
<p>Даже если вы имеете небольшую компанию и в ней работают все ваши текущие 
пользователи, способные выполнять команды модификации в данной таблице, было бы 
лучше предоставить привилегии каждому пользователю индивидуально, чем одни и те 
же привилегии для всех.</p>
<p>PUBLIC не ограничен в его передаче только текущим 
пользователям. Любой новый пользователь, добавляемый к вашей системе, 
автоматически получит все привилегии назначенные ранее всем, так что, если вы 
захотите ограничить доступ к таблице всем, сейчас или в будущем, лучше всего 
предоставить привилегии иные, нежели SELECT для индивидуальных пользователей.</p>
<h3><a name="22.7">П</a>РЕДОСТАВЛЕНИЕ ПРИВИЛЕГИЙ С ПОМОЩЬЮ WITH GRANT OPTION</h3>
<p>Иногда создателю таблицы необходимо, чтобы другие пользователи могли получить 
привилегии в его таблице. Обычно это делается в системах, где один человек или более 
 
создают несколько (или все) базовые таблицы в базе данных, а затем 
передают ответственность за них тем, кто будет фактически с ними работать. SQL 
позволяет делать это с помощью предложения WITH GRANT OPTION.</p>
<p>Если бы Diane хотела, чтобы Adrian имел право предоставлять привилегию SELECT в таблице Заказчиков 
другим пользователям, она дала бы ему привилегию SELECT с использованием 
предложения WITH GRANT OPTION:</p>
<pre>          GRANT SELECT ON Customers TO Adrian
            WITH GRANT OPTION;</pre>
<p>После этого Adrian получил право передавать привилегию SELECT третьим лицам; 
он может выдать команду</p>
<pre>	 GRANT SELECT ON Diane.Customers TO Stephen;</pre>
<p>или даже</p>
<pre>         GRANT SELECT ON Diane.Customers TO Stephen
          WITH GRANT OPTION;</pre>
<p>Пользователь с помощью GRANT OPTION в особой привилегии в данной таблице 
может, в свою очередь, предоставить эту привилегию в той же таблице, с или без GRANT OPTION, любому другому пользователю. Это не меняет принадлежности самой 
таблицы; как и прежде таблица принадлежит ее создателю. (Поэтому пользователи, 
получившие права, должны устанавливать префикс ID доступа владельца, когда 
обращаются к этим таблицам. Следующая глава покажет вам этот способ.) 
Пользователь же с помощью GRANT OPTION во всех привилегиях для данной таблицы 
будет иметь всю полноту власти в той таблице.</p>
<h3><a name="22.8">О</a>ТМЕНА ПРИВИЛЕГИЙ</h3>
<p>Также как ANSI предоставляет команду CREATE TABLE, чтобы создать таблицу, а 
DROP TABLE - чтобы от нее избавиться, так и команда GRANT позволяет вам давать 
привилегии пользователям, не предоставляя способа отобрать их обратно.</p>
<p>Удаление привилегии выполняется командой REVOKE, фактически - 
стандартному средству с достаточно понятной формой записи. Синтаксис команды 
REVOKE похож на GRANT, но имеет обратный смысл.</p>
<p>Чтобы удалить привилегию INSERT 
для Adrian в таблице Заказов, вы можете ввести</p>
<pre>	REVOKE INSERT ON Orders FROM Adrian;</pre>
<p>Использование списков привилегий и пользователей здесь допустимы, как и в 
случае с GRANT, так что вы можете ввести следующую команду:</p>
<pre>        REVOKE INSERT, DELETE ON Customers
          FROM Adrian, Stephen;</pre>
<p>Однако здесь имеется некоторая неясность. Кто имеет право отменять 
привилегии? Когда пользователь с правом передавать привилегии другим, теряет это 
право, пользователи, которым он предоставил эти привилегии, также их потеряют?<br>
Так как это нестандартная особенность, нет никаких авторитетных ответов на эти 
вопросы, но наиболее общий подход таков:</p>
<ul>
  <li>Привилегии отменяются пользователем, который их предоставил, и отмена 
  будет каскадироваться, то есть она будет автоматически распространяться на 
  всех пользователей, получивших от него эту привилегию.</li>
</ul>
<h3><a name="22.9">И</a>СПОЛЬЗОВАНИЕ ПРЕДСТАВЛЕНИЙ ДЛЯ ФИЛЬТРАЦИИ ПРИВИЛЕГИЙ</h3>
<p>Вы можете сделать действия привилегий более точными, используя представления. 
Всякий раз, когда вы передаёте привилегию в базовой таблице пользователю, она 
автоматически распространяется на все строки, а при использовании возможных 
исключений UPDATE и REFERENCES - на все столбцы таблицы.</p>
<p>Создавая представление, 
которое ссылается на основную таблицу и затем переносит привилегию на 
представление, а не на таблицу, вы можете ограничивать эти привилегии любыми 
выражениями в запросе, содержащемся в представлении. Это значительно улучшает 
базисные возможности команды GRANT.</p>
<h4>КТО МОЖЕТ СОЗДАВАТЬ ПРЕДСТАВЛЕНИЯ?</h4>
<p>Чтобы создавать представление, вы должны иметь привилегию SELECT во всех 
таблицах, на которые вы ссылаетесь в представлении. Если это представление 
модифицируемое, любая привилегия INSERT, UPDATE и DELETE, которые вы имеете в 
базовой таблице, будут автоматически передаваться представлению.</p>
<p>Если у вас отсутствуют привилегии на модификацию в базовых таблицах, вы не 
сможете иметь их и в представлениях, которые вы создали, даже если сами эти 
представления - модифицируемые.</p>
<p>Так как внешние ключи не используются в 
представлениях, привилегия REFERENCES никогда не используется при создании 
представлений. Все эти ограничения определяются ANSI.<br>
Нестандартные привилегии 
системы (обсуждаемые позже в этой главе) также могут быть включены.</p>
<p>В 
последующих разделах мы предположим, что создатели представлений, которые мы 
обсуждаем, имеют частные или соответствующие привилегии во всех базовых 
таблицах.</p>
<p><b>ОГРАНИЧЕНИЕ ПРИВИЛЕГИИ SELECT ДЛЯ ОПРЕДЕЛЁННЫХ СТОЛБЦОВ</b> </p>
<p>Предположим, вы хотите дать пользователю Claire способность видеть только 
столбцы snum и sname таблицы Продавцов. Вы можете сделать это, поместив имена 
этих столбцов в представление</p>
<pre>         CREATE VIEW Clairesview
            AS SELECT snum, sname
               FROM Salespeople;</pre>
<p>и предоставить Claire привилегию SELECT в представлении, а не в самой таблице 
Продавцов:</p>
<pre>	  GRANT SELECT On Clairesview to Claire;</pre>
<p>Вы можете создать привилегии специально для столбцов, наподобие использования 
других привилегий, но для команды INSERT это будет означать вставку значений по 
умолчанию, а для команды DELETE ограничение столбца не будет иметь значения.</p>
<p>Привилегии REFERENCES и UPDATE, конечно, могут сделать столбцы специализированными, 
не прибегая к представлению.</p>
<p><b>ОГРАНИЧЕНИЕ ПРИВИЛЕГИЙ ДЛЯ ОПРЕДЕЛЁННЫХ СТРОК</b></p>
<p>Обычно более полезный способ фильтровать привилегии с представлениями - это 
использовать представление, чтобы привилегия относилась только к определенным 
строкам. Вы делаете это, естественно, используя предикат в представлении, 
который определит, какие строки являются включенными.</p>
<p>Чтобы предоставить 
пользователю Adrian привилегию UPDATE в таблице Заказчиков для всех заказчиков, 
размещенных в Лондоне, вы можете создать такое представление:</p>
<pre>       CREATE VIEW Londoncust
          AS SELECT *
             FROM Customers
             WHERE city = 'London'
             WITH CHECK OPTION;</pre>
<p>Затем вы должны передать привилегию UPDATE в этой таблице для Adrian:</p>
<pre>          GRANT UPDATE ON Londoncust TO Adrian;</pre>
<p>В этом отличие привилегии для определённых строк от привилегии UPDATE для 
определённых столбцов, которая распространена на все столбцы таблицы Заказчиков, 
но не на строки, среди которых строки со значением поля city, иным, чем London, 
не будут учитываться. Предложение WITH CHECK OPTION предохраняет Adrian от 
замены значения поля city на любое значение кроме London.</p>
<p><b>ПРЕДОСТАВЛЕНИЕ ДОСТУПА ТОЛЬКО К ИЗВЛЕЧЁННЫМ ДАННЫМ</b></p>
<p>Другая возможность состоит в том, чтобы предлагать пользователям доступ к уже 
извлечённым данным, а не к фактическим значениям в таблице. Агрегатные функции 
могут быть весьма удобными в применении такого способа. Вы можете создавать 
представление, которое выдаёт подсчёт, среднее и общее количество  заказов на 
каждый день заказов:</p>
<pre>         CREATE VIEW Datetotals
            AS SELECT odate, COUNT (*), SUM (amt), AVG (amt)
               FROM Orders
               GROUP BY odate;</pre>
<p>Теперь вы передаёте пользователю Diane привилегию SELECT в представлении 
Datetotals:</p>
<pre>            GRANT SELECT ON Datetotals TO Diane;</pre>
<p><b>ИСПОЛЬЗОВАНИЕ ПРЕДСТАВЛЕНИЙ В КАЧЕСТВЕ АЛЬТЕРНАТИВЫ  ОГРАНИЧЕНИЯМ</b></p>
<p>Одной из последних прикладных программ из серии, описанной в
<a href="ch18.php">Главе 18</a>, является использование представлений с WITH 
CHECK OPTION как альтернативы ограничениям.</p>
<p>Предположим,  вы хотели 
бы удостовериться, что все значения поля city в таблице Продавцов находятся в одном 
из городов, где ваша компания в настоящее время имеет ведомство. Вы можете 
установить ограничение CHECK непосредственно на столбец city, но позже может 
стать трудно его изменить, если ваша компания, например, откроет там другие 
офисы. В качестве альтернативы можно создать представление, которое исключает 
неправильные значения city:</p>
<pre>   CREATE VIEW Curcities
       AS SELECT *
         FROM Salespeople
           WHERE city IN ('London', 'Rome', 'San Jose', 'Berlin')
          WITH CHECK OPTION;</pre>
<p>Теперь, вместо того чтобы предоставить пользователям привилегии 
модифицирования в таблице Продавцов, вы можете предоставить их в представлении 
Curcities. Преимущество такого подхода в том, что, если вам нужно сделать 
изменение, вы можете удалить это представление, создать новое и предоставить в 
этом новом представлении привилегии пользователям, что проще, чем изменять 
ограничения. Недостатком является то, что владелец таблицы Продавцов также 
должен использовать это представление, если он не хочет чтобы его собственные 
команды были отклонены. С другой стороны, этот подход позволяет владельцу 
таблицы и любым другим получить привилегии модификации в самой таблице, а не в 
представлении, чтобы делать исключения для ограничений.</p>
<p>Это часто бывает желательно, но невыполнимо, если вы используете ограничения 
в базовой таблице. К сожалению, эти исключения нельзя будет увидеть в 
представлении. Если вы выберите этот подход, вам захочется создать второе 
представление, содержащее только исключения:</p>
<pre>         CREATE VIEW Othercities
           AS SELECT *
             FROM Salespeople
             WHERE city NOT IN ('London', 'Rome', 'San Jose',
              'Berlin')
             WITH CHECK OPTION;</pre>
<p>Вы должны выбрать для передачи пользователям только привилегию SELECT в этом 
представлении, чтобы они могли видеть исключенные строки, но не могли помещать 
недопустимые значения city в базовую таблицу. Фактически пользователи могли бы 
сделать запрос обоих представлений в объединении и увидеть все строки сразу.</p>
<h3><a name="22.10">Д</a>РУГИЕ ТИПЫ ПРИВИЛЕГИЙ</h3>
<p>Вы, разумеется, хотите знать, кто же имеет право первым создать таблицу. Эта 
область привилегий не относится к ANSI, но не может игнорироваться. Все 
стандартные привилегии ANSI вытекают из этой привилегии - привилегии создателей 
таблиц, которые могут передавать привилегии объекта. Если все ваши пользователи 
будут создавать в системе базовые таблицы с разными размерами, это приведет к 
избыточности в них и к неэффективности системы.</p>
<p>Возникают и другие вопросы:</p>
<ul>
  <li>Кто имеет право изменять, удалять или ограничивать таблицы? </li>
  <li>Должны ли права создания базовых таблиц отличаться от прав создания 
  представлений? </li>
  <li>Должен ли иметься суперпользователь - пользователь который отвечает за 
  поддержание базы данных и, следовательно, имеющий наибольшие или все 
  привилегии, которые не предоставляются индивидуально? </li>
</ul>
<p>Пока ANSI не принимает в этом участия, а SQL используется в различных средах, 
мы не можем дать окончательный ответ на эти вопросы. Мы предлагаем рассмотреть 
здесь часть наиболее общих выводов.</p>
<p>Привилегии, которые не определяются в терминах специальных объектов данных, 
называются привилегиями системы или правами базы данных. На базисном уровне они 
будут, вероятно, включать в себя право создавать объекты данных, возможно, 
отличающиеся от базовых таблиц (обычно создаваемых несколькими пользователями) и 
представлений (обычно создаваемых большинством пользователей).<br>
Привилегии 
системы для создания представлений должны дополнять, а не заменять привилегии 
объекта, которые ANSI требует от создателей представлений (описанных ранее в 
этой главе). Кроме того, в системе любого размера всегда имеются некоторые типы суперпользователей - пользователей, которые автоматически имеют большинство или 
все привилегии и которые могут передать свой статус суперпользователя 
кому-нибудь с помощью привилегии или группы привилегий. Администратор Базы 
Данных (DBA) является термином наиболее часто используемым для такого 
суперпользователя и для привилегий, которыми он обладает.</p>
<h3><a name="22.11">Т</a>ИПИЧНЫЕ ПРИВИЛЕГИИ СИСТЕМЫ</h3>
<p>При обычном подходе имеется три базовых привилегии системы: CONNECT 
(Подключить), RESOURCE (Ресурс) и DBA (Администратор Базы Данных). Проще можно 
сказать, что CONNECT состоит из права зарегистрироваться и права создавать 
представления и синонимы (см. <a href="ch23.php">Главу 23</a>), если переданы 
привилегии объекта. RESOURCE состоит из права создавать базовые таблицы. DBA это 
привилегия суперпользователя, дающая пользователю высокие полномочия в базе 
данных. Один или более пользователей с функциями администратора базы данных 
может иметь эту привилегию. Некоторые системы кроме того имеют специального 
пользователя, иногда называемого SYSADM или SYS (Системный Администратор Базы 
Данных), который имеет наивысшие полномочия; это специальное имя, а не просто 
пользователь со специальной DBA-привилегией. Фактически только один человек 
имеет право зарегистрироваться с именем SYSADM, являющимся его идентификатором 
доступа. Различие - весьма тонкое и функционирует по разному в различных 
системах.<br>
Для наших целей мы будем ссылаться на высокопривилегированного 
пользователя, который разрабатывает БД и управляет ею, имея полномочия DBA, понимая, что фактически эти полномочия - та же самая привилегия. Команда GRANT, в измененной форме, 
пригодна для использования как с 
привилегиями объекта, так и с системными привилегиями. Для начала передача прав 
может быть сделана с помощью DBA. Например, DBA может передать привилегию для 
создания таблицы пользователю Rodriguez следующим образом:</p>
<pre>         GRANT RESOURCE TO Rodriguez;</pre>
<h3><a name="22.12">С</a>ОЗДАНИЕ И УДАЛЕНИЕ ПОЛЬЗОВАТЕЛЕЙ</h3>
<p>Естественно, появляется вопрос, откуда возьмётся пользователь с именем 
Rodriguez? Как определить его ID допуска? В большинстве реализаций DBA создаёт 
пользователя, автоматически предоставляя ему привилегию CONNECT.</p>
<p>В этом случае обычно добавляется предложение IDENTIFIED BY, указывающее 
пароль. (Если же нет, операционная система должна определить, можете ли вы 
зарегистрироваться в БД с данным ID доступа.) DBA может, например, ввести:</p>
<pre>GRANT CONNECT TO Thelonius IDENTIFIED BY Redwagon;</pre>
<p>что приведет к созданию пользователя с именем Thelonius, даст ему право 
регистрироваться и назначит ему пароль Redwagon, и всё это в одном предложении.</p>
<p>Раз Thelonious - уже опознанный пользователь, он или DBA могут использовать 
эту же команду, чтобы изменить пароль Redwagon.</p>
<p>Хотя это и удобно, но всё же имеется ограничение и в этом подходе: 
невозможность иметь пользователя, который  мог бы зарегистрироваться, хотя бы 
временно. Если вы хотите запретить пользователю регистрироваться, вы должны 
использовать для REVOKE привилегию CONNECT, которая &quot;удаляет&quot; этого 
пользователя. Некоторые реализации позволяют вам создавать и удалять 
пользователей, независимо от их привилегий при регистрации. Когда вы 
предоставляете привилегию CONNECT пользователю, вы создаете этого пользователя. 
При этом, чтобы сделать это вам самим, вы должны иметь DBA-привилегию. Если этот 
пользователь будет создавать базовые таблицы (а не только представления), ему 
нужно также предоставить привилегию RESOURCE. Но это сразу порождает другую 
проблему.</p>
<p>Если вы сделаете попытку удалить привилегию CONNECT пользователя, который 
имеет созданные им таблицы, команда будет отклонена, потому что её действие 
оставит таблицу без владельца, а это не разрешается. Вы должны сначала удалить 
все таблицы, созданные этим пользователем, прежде чем удалить его привилегию 
CONNECT. Если эти таблицы - не пустые, то вы, вероятно, захотите передать их 
данные в другие таблицы с помощью команды INSERT, которая использует запрос. Вам 
не нужно удалять отдельно привилегию RESOURSE; достаточно удалить CONNECT, чтобы 
удалить пользователя.</p>
<p>Хотя всё выше сказанное это вполне стандартный подход к привилегиям системы, 
он также имеет значительные ограничения. Появились альтернативные подходы, 
которые более конкретно определены и точнее управляют привилегиями системы.</p>
<p>Это несколько выводит нас за пределы стандарта SQL, как он определён в 
настоящее время, и, в некоторых реализациях, можно полностью выйти за пределы 
стандарта SQL. Эти вещи, вероятно, не будут слишком вас касаться, если вы не DBA 
или не пользователь высокого уровня. Обычные пользователи просто должны быть 
знакомыми с привилегиями системы в принципе, справляясь в своей документации 
только в случае специальных сообщений.</p>
<h3><a name="22.13">Р</a>ЕЗЮМЕ</h3>
<p>Привилегии дают вам возможность видеть SQL под новым углом зрения, когда SQL 
выполняет действия через специальных пользователей в специальной системе базы 
данных.</p>
<p>Сама команда GRANT достаточно проста: с её помощью вы предоставляете те 
или иные привилегии объекта одному или более пользователям. Если вы 
предоставляете привилегию WITH GRANT OPTION пользователю, этот пользователь 
может, в свою очередь, предоставить эту привилегию другим. Теперь вы понимаете 
намеки на использование привилегий в представлениях - чтобы усовершенствовать 
привилегии в базовых таблицах, или как альтернативы ограничениям - и на 
некоторые преимущества и недостатки такого подхода.</p>
<p>Привилегии системы, которые 
необходимы, но не входят в область стандарта SQL, обсуждались в их наиболее 
общей форме, поэтому вы будете знакомиться с ними на практике.
<a href="ch23.php">Глава 23</a> продолжит обсуждение таких вопросов о выводе в 
SQL как 
сохранение или восстановление изменений, создание ваших собственных имён для 
таблиц, принадлежащих другим людям и понимание того, что происходит, когда 
различные пользователи пытаются обращаться к одному и тому же объекту 
одновременно.</p>
<h3><a name="22.14">Р</a>АБОТА СО SQL</h3>
<pre>1. Передайте Janet право на изменение оценки заказчика.

2. Передайте Stephan право передавать другим пользователям право
   делать запросы в таблице Заказов.

3. Отнимите привилегию INSERT (ВСТАВКА) в таблице Продавцов
   у Claire и у всех пользователей, которым она была предоставлена.

4. Передайте Jerry право вставлять в или модифицировать таблицу
   Заказчиков с сохранением его возможности оценивать значения
   в диапазоне от 100 до 500.

5. Разрешите Janet делать запросы в таблице Заказчиков, но запретите
   ей уменьшать оценки в той же таблице Заказчиков.

(См. ответы в <a href="a.php#23">Приложении A</a>.)</pre></body></html>
<? include 'foot.php' ?>