699
.pdfSAVE simplequestion REPLACE COLUMN vc2doc FORMAT A60 SET VERIFY OFF
Проверка:
CTX> @simplequestion 'star' SCORE VC2DOC
---------- --------------------------
----------------------------------
0 Mary had a little lamb
4 Twinkle, twinkle little star
0 This Lamb is my lamb
CTX> @simplequestion 'little' SCORE VC2DOC
---------- --------------------------
----------------------------------
4 Mary had a little lamb
4 Twinkle, twinkle little star
0 This Lamb is my lamb
Другой способ обращения к текстовому индексу:
SELECT SCORE (1), vc2doc FROM docs WHERE CONTAINS (vc2doc, 'lamb', 1 ) > 0 ORDER BY SCORE ( 1 ) DESC;
SCORE (1) VC2DOC
---------- --------------------------
----------------------
7 This Lamb is my lamb
4 Mary had a little lamb
Поиск в метаданных Oracle словаря полнотекстового индексирования.
CTX> COLUMN object_name FORMAT A30 CTX> COLUMN object_type FORMAT A30 CTX> COLUMN segment_name FORMAT A30 CTX> COLUMN segment_type FORMAT A30 CTX> SELECT object_name, object_type
FROM user_objects ORDER BY 2, 1; [3]
OBJECT_NAME OBJECT_TYPE
151
------------------------------------------------------ |
------ |
||
|
|||
|
DOCS_VC2DOC_IDX INDEX |
|
|
|
DR$DOCS_VC2DOC_IDX$X INDEX |
||
|
SYS_IOT_TOP_51619 INDEX |
|
|
|
SYS_IOT_TOP_51624 INDEX |
|
|
|
SYS_LOB0000051616C00006$$ LOB |
||
|
SYS_LOB0000051621C00002$$ LOB |
||
|
DOCS TABLE |
|
|
|
DR$DOCS_VC2DOC_IDX$I TABLE |
||
|
DR$DOCS_VC2DOC_IDX$K TABLE |
||
|
DR$DOCS_VC2DOC_IDX$N TABLE |
||
|
DR$DOCS_VC2DOC_IDX$R TABLE |
||
|
CTX> |
SELECT |
segment_name, |
segment_type |
FROM user_segments ORDER BY |
||
2, |
1; |
|
|
|
SEGMENT_NAME SEGMENT_TYPE |
------------------------------ ------
------------------------
DR$DOCS_VC2DOC_IDX$X INDEX SYS_IOT_TOP_51619 INDEX SYS_IOT_TOP_51624 INDEX SYS_IL0000051616C00006$$ LOBINDEX SYS_IL0000051621C00002$$ LOBINDEX SYS_LOB0000051616C00006$$ LOBSEGMENT SYS_LOB0000051621C00002$$ LOBSEGMENT DOCS TABLE
DR$DOCS_VC2DOC_IDX$I TABLE
DR$DOCS_VC2DOC_IDX$R TABLE
В обоих запросах все объекты БД и структуры хранения, кроме DOCS, принадлежат текстовому индексу [3].
DOCS_VC2DOC_IDX (типа DOMAIN) появился толь-
ко как логический объект в БД; технически его реализуют четыре возникшие служебные таблицы:
1. Таблица DR$DOCS_VC2DOC_IDX$I. Хранит пере-
чень всех словоформ, попавших в индекс, внутренний но-
152
мер документа («DOCID») и список позиций словоформ в документе. Вторичные, связанные с ней объекты:
•индекс DR$DOCS_VC2DOC_IDX$X (обычный, типа NORMAL);
•сегменты типа LOBSEGMENT и LOBINDEX для хранения данных поля TOKEN_INFO типа BLOB.
2. Таблица DR$DOCS_VC2DOC_IDX$K. Хранит соот-
ветствие DOCID адресу ROWID строки с текстом или ссылкой на текст. Индексно-организованная таблица хранится в структуре индекса.
3. Таблица DR$DOCS_VC2DOC_IDX$R. Хранит спи-
сок для обратного поиска: ROWID по DOCID. Вторичные, связанные с ней объекты: сегменты типа LOBSEGMENT и LOBINDEX для хранения данных поля DATA типа BLOB.
4. Таблица DR$DOCS_VC2DOC_IDX$N. Хранит спи-
сок удаленных документов (DOCID), пополняющийся при оптимизации текстового индекса. Индексно-организо- ванная таблица, хранится в структуре индекса.
ПримервыдачиизтаблицыDR$DOCS_VC2DOC_IDX$I:
CTX> SELECT token_text, token_count FROM dr$docs_vc2doc_idx$i;
TOKEN_TEXT TOKEN_COUNT
-------------------------------------
------------LAMB 2
LITTLE 2 MARY 1
В отличие от обычного индекса, текстовый не правится автоматически при правке документа. Чтобы обновить текстовый индекс docs_vc2doc_idx, нужно выполнить:
CTX> EXECUTE CTX_DDL.SYNC_INDEX('docs_vc2doc_idx')
PL/SQL procedure successfully completed.
153
CTX> /
Стандартный прием – создать задание для плановой корректировки текстового индекса по расписанию.
Планы выполнения запросов
Команда EXPLAIN PLAN отмечает обращение к текстовому индексу:
CTX> EXPLAIN PLAN FOR SELECT * FROM docs
WHERE CONTAINS ( vc2doc, 'twinkle |
AND |
||||
star' ) > 0; |
|
|
|
|
|
Explained. |
* |
FROM |
TABLE |
( |
|
CTX> |
SELECT |
||||
dbms_xplan.display ); |
|
|
|
||
PLAN_TABLE_OUTPUT |
|
|
|
|
------------------------------------------
-----------------------------------
Plan hash value: 3477406887
------------------------------------------
-----------------------------------
| Id | Operation | Name |Rows|Bytes|Cost (%CPU)|Time |
------------------------------------------
-----------------------------------
| 0| SELECT STATEMENT | | 1| 2027| 4 (0)|00:00:01|
| 1|TABLE ACCESS BY INDEX| DOCS | 1| 2027| 4 (0)|00:00:01|
|* 2|DOMAIN INDEX |DOCS_VC2DOC_IDX| | | 4 (0)|00:00:01|
Детали отработки самого текстового (не SQL) запроса наблюдаются через специальную таблицу, а не привычную PLAN_TABLE. Создать ее можно примерно так:
CREATE GLOBAL TEMPORARY TABLE ctx_explain (
explain_id VARCHAR2 ( 30 ),
154
id NUMBER, parent_id NUMBER,
operation VARCHAR2 ( 30 ), options VARCHAR2 ( 30 ), object_name VARCHAR2 ( 64 ), position NUMBER,
cardinality NUMBER
)
ON COMMIT PRESERVE ROWS;
Просмотр плана для конкретного обращения к конкретному индексу делается через специальную процедуру из системного пакета CTX_QUERY:
BEGIN ctx_query.explain (
index_name => 'docs_vc2doc_idx'
,text_query => 'twinkle AND star'
,explain_table => 'ctx_explain'
,explain_id => 'twinkle star'
);
END;
/
Пример просмотра сформированного в CTX_EXPLAIN планаобработкитекстового запроса:
CTX> SELECT
2 explain_id 3, id
4, parent_id 5, operation 6, options
7, object_name 8, position
9FROM
10ctx_explain
11ORDER BY
12id
13/
155
EXPLAIN_ID ID PARENT_ID OPERATION OPTIONS OBJECT_NAME POSITION
-------------- --- ---------- -------
-- ------- -------------- ---------
twinkle star 1 0 AND 1
twinkle star 2 1 WORD TWINKLE 1 twinkle star 3 1 WORD STAR 2
Настройки для полнотекстового индекса
Рассмотрим пример создания контекстного полнотекстового индекса по таблице документов docs.
Создадимтаблицу документови наполним ееданными:
create |
table docs (id |
number not |
|
null, text |
varchar2(1000) not null); |
||
insert into docs values (1, 'Шла Саша |
|||
по шоссе и |
сосала сушку.'); |
(2, 'London |
|
insert |
into docs values |
is the capital of The United Kingdom of Great Britain and Northern Ireland.');
Создадим настройки для полнотекстового индекса и выполним его построение:
begin
ctx_ddl.create_preference('my_wordlist', 'BASIC_WORDLIST');
ctx_ddl.create_preference('my_lexer', 'AUTO_LEXER');
ctx_ddl.set_attribute('my_lexer', 'INDEX_STEMS','YES');
end;
create index docs_idx on docs (text) indextype is ctxsys.context parameters ('LEXER my_lexer WORDLIST my_wordlist');
Тестируем построенный индекс [30]:
select * from docs where contains(text, 'саша') > 0;
156
ID TEXT
1 Шла Саша по шоссе и сосала сушку. select * from docs where
contains(text, 'uni%') > 0; ID TEXT
2 London is the capital of The United Kingdom of Great Britain and Northern
Ireland.
2.18. Представления
Ограничение целостности существует в пределах таблицы представления.
Представление – это объект БД, инструкция SELECT с заданным именем, хранящаяся в БД. Позволяет модифицировать данные. Представления можно секционировать, делить на несколько более мелких с одинаковой структурой. Можно создать индекс представления.
Представления применяются для того, чтобы предоставить пользователям доступ к группе таблиц таким образом, как будто это одна таблица, и тем самым ограничить доступ к ним. Представления также можно использовать для ограничения доступа к строкам таблицы (выделяя, таким образом, подмножество записей). Для ограничения доступа к столбцам представления не нужны, если сервер БД обладает развитой системой привилегий.
Многие СУБД не разрешают выполнять операции обновления представлений. Вместо этого необходимо обновлять отдельные таблицы. При разработке механизма поддержки представлений целью было, оставаясь в рамках стандарта SQL, достичь полной совместимости с шестым правилом Кодда для реляционных баз данных. Все представления, теоретически обновляемые, должны быть обновляемы на практике.
157
Представления добавляют уровень защиты данных (например, можно создать представление для таблицы, где пользователю, выполняющему SELECT над представлением, видны только сведения о зарплате).
Представления могут скрывать сложность данных, комбинируя нужную информацию из нескольких таблиц.
Представления могут скрывать настоящие имена столбцов, порой трудные для понимания, и показывать более простые имена.
Представление создается с помощью команды CREATE VIEW. После создания представления становятся частью схемы создавшего их пользователя. Переназначить их другому пользователю можно тогда, когда у него имеется системная привилегия CREATE ANY VIEW.
Основные ключевые слова и параметры CREATE VIEW Oracle:
OR REPLACE, FORCE, NOFORCE, Sсhema, View, Alias, AS subquery, WITH CHECK OPTION, Constraint
OR REPLACE – пересоздает представление, если оно уже существует.
FORCE – создает представление независимо от того, существуют ли базовые таблицы этого представления и имеет ли владелец схемы, содержащей представление, привилегии по этим таблицам. Необходимо, чтобы оба названных условия были удовлетворены, прежде чем по данному представлению можно будет выдавать любые предложения
SELECT, INSERT, UPDATE или DELETE. По умолчанию применяется параметр NOFORCE.
NOFORCE создает представление только в том случае, если существуют базовые таблицы этого представления, а владелец схемы, содержащей представление, имеет привилегии по этим таблицам.
158
Sсhema – схема, в которой создается представление. Если СХЕМА опущена, то ORACLE создает представление в схеме пользователя [45].
Пример 1
Простое представление, которое создается из данных одной таблицы:
CREATE VIEW London_view AS SELECT * FROM Salespeople WHERE city = ‘London’;
Пример 2
При создании представления можно можно задать новые имена полей:
CREATE VIEW Rating_view(rating,number) AS SELECT rating, COUNT(*) FROM Customers GROUP BY rating;
Пример 3
Представления могут получать информацию из любого количества базовых таблиц:
CREATE VIEW Nameorders AS SELECT onum, amt,a.snum, sname, cname FROM Orders a, Customers b, Salespeople C WHERE a.cnum = b.cnum AND a.snum = c.snum;
Пример 4
При создании представлений можно использовать подзапросы, включая связанные подзапросы:
CREATE VIEW Sales_view AS SELECT b.odate, a.snum, a.sname, FROM Salespeople
a, Orders b WHERE a.snum |
= b.snum |
AND |
|
b.amt |
= (SELECT MAX(amt) |
FROMOrders |
c |
WHERE |
c.odate = b.odate); |
|
|
Пример 5
CREATE VIEW empl_v04 AS SELECT e.eid, e.sname, e.fname, e.otch, p.pname, d.dname FROM posts p, departments d, employees e WHERE e.did = d.did AND e.pid = p.pid;
159
2.19. Операторы манипуляции данными
(Data Manipulation Language, DML)
Операторы манипуляции данными (Data Manipulation Language, DML):
•SELECT – считывает данные, удовлетворяющие заданным условиям;
•INSERT – добавляет новые данные;
•UPDATE – изменяет существующие данные;
•DELETE – удаляет данные;
Создание простого SQL-запроса
SQL-запрос возвращает строки из одной или нескольких таблиц. ВобщемвидесинтаксисSQL-запросавыглядиттак:
[ WITH <common_table_expression>] SELECT select_list [ INTO new_table ] [ FROM table_source ] [ WHERE
search_condition ]
[ GROUP BY group_by_expression ] [ HAVING search_condition ]
[ ORDER BY order_expression [ ASC | DESC ] ]
Операторы UNION, EXCEPT и INTERSECT исполь-
зуются, чтобы скомбинировать строки из нескольких таблиц в одну таблицу, которая выдается в запросе.
Для Transact-SQL синтаксис запроса выглядит следующим образом:
<SELECT statement>::=
[WITH <common_table_expression> [,...n]]
<query_expression>
[ ORDER BY { order_by_expression | column_position [ ASC | DESC ] }
[,...n ] ] [ COMPUTE
160