Базы данных Oracle - статьи

         

Текстовый индекс


Практически обработку текстовой информации в Oracle Text обеспечивает текстовый индекс. Содержательно он организует хранение «обращенного списка», который по предъявленному поисковому слову выдает список пар <документ, словоместо>. Для этого он хранит список документов, позиций словоформ в документах и одно или несколько индексируемых слов в каждой позиции.

Технически текстовый индекс устроен сложнее обычных B-древовидного или же поразрядного индексов хотя бы тем, что реализован сразу группой объектов и группой структур хранения. В этом легко удостовериться:

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;

OBJECT_NAME OBJECT_TYPE ------------------------------ ------------------------------ 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, принадлежат текстовому индексу. Точнее, в результате команды CREATE INDEX docs_vc2doc_idx ... индекс DOCS_VC2DOC_IDX (типа DOMAIN) появился только как логический объект в БД; технически его реализуют четыре возникшие служебные таблицы:

  • Таблица DR$DOCS_VC2DOC_IDX$I.
    Хранит перечень всех словоформ, попавших в индекс, внутренний номер документа («DOCID») и список позиций словоформ в документе. Вторичные, связанные с ней объекты:

    • индекс DR$DOCS_VC2DOC_IDX$X (обычный, типа NORMAL),
    • сегменты типа LOBSEGMENT и LOBINDEX для хранения данных поля TOKEN_INFO типа BLOB.


  • Таблица DR$DOCS_VC2DOC_IDX$K.
    Хранит соответствие DOCID адресу ROWID строки с текстом или ссылкой на текст. Индексно-организованная таблица, хранится в структуре индекса.
  • Таблица DR$DOCS_VC2DOC_IDX$R.
    Хранит список для обратного поиска: ROWID по DOCID. Вторичные, связанные с ней объекты:


    • сегменты типа LOBSEGMENT и LOBINDEX для хранения данных поля DATA типа BLOB.


    • Таблица 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 STAR 1 TWINKLE 1



      Еще одно отличие текстового индекса от обычного в том, что он не правится автоматически при правке документа. Например:

      CTX> UPDATE docs SET vc2doc = 'This Land is my land' WHERE doc_id = 3;

      1 row updated.

      CTX> COMMIT;

      Commit complete.

      CTX> SELECT token_text, token_count FROM dr$docs_vc2doc_idx$i;

      TOKEN_TEXT TOKEN_COUNT ------------------------------------------------- ----------- LAMB 2 LITTLE 2 MARY 1 STAR 1 TWINKLE 1

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

      CTX> SELECT pnd_index_name, pnd_rowid FROM ctx_user_pending;

      PND_INDEX_NAME PND_ROWID ---------------------------- ------------------ DOCS_VC2DOC_IDX AAAMm2AAEAAAABAAAC

      CTX> EXECUTE CTX_DDL.SYNC_INDEX ( 'docs_vc2doc_idx' )

      PL/SQL procedure successfully completed.

      CTX> /

      no rows selected

      CTX> SELECT token_text, token_count FROM dr$docs_vc2doc_idx$i;

      TOKEN_TEXT TOKEN_COUNT ------------------------------------------------- ----------- LAMB 2 LAND 1

      LITTLE 2 MARY 1 STAR 1 TWINKLE 1

      (Синхронизировать индекс можно и командой ALTER INDEX, но сейчас фирма Oracle этого не советует).

      Стандартный прием - создать задание для плановой корректировки текстового индекса по расписанию.


      Содержание раздела