РОУИД (оракул) - какая польза от этого? - PullRequest
34 голосов
/ 24 апреля 2010

Насколько я понимаю, ROWID является уникальным значением для каждой строки в результате, возвращаемом запросом.

Зачем нам этот ROWID? В ORACLE уже есть ROWNUM.

Кто-нибудь использовал ROWID в запросе SQL?

Ответы [ 6 ]

43 голосов
/ 24 апреля 2010

ROWID - это физическое местоположение строки. Следовательно, это самый быстрый способ найти строку, даже быстрее, чем поиск по первичному ключу. Таким образом, это может быть полезно в определенных типах транзакций, когда мы выбираем несколько строк, сохраняем их ROWID, а затем используем ROWID в предложениях where для DML для этих же строк.

Синтаксис Oracle SELECT ... FOR UPDATE неявно использует ROWID, когда мы обновляем заблокированную строку, используя WHERE CURRENT OF. Также в таблице EXCEPTIONS (на которую ссылаются при применении ограничений с предложением EXCEPTIONS INTO) есть столбец ROW_ID. Это позволяет нам быстро идентифицировать строки, которые нарушают наше ограничение.

Этот последний пример указывает на другое общее использование: когда мы пишем какой-то общий фрагмент кода и нам нужен механизм для хранения UID без проблем с типом данных, составными ключами и т. Д.

ROWNUM, с другой стороны, является псевдостолбцом, который помечает строку в данном наборе результатов. Это не имеет постоянного значения.

редактировать

ROWID для данной записи может изменяться в течение срока службы системы, например, при перестроении таблицы. Также, если одна запись удалена, новой записи может быть присвоен этот ROWID. Следовательно, ROWID не подходят для использования в качестве UID в долгосрочной перспективе. Но они достаточно хороши для использования в транзакции.

12 голосов
/ 24 апреля 2010

Теперь я знаю пример для этого.

предположим, что у вас есть таблица без первичных ключей. так что эта таблица может иметь повторяющиеся строки. Как бы вы удалили повторяющиеся строки, но сохранили именно такую?

Oracle предоставляет ROWID как своего рода замену первичного ключа. Вы можете написать вложенный запрос, который имеет коррелированный тип [(сгруппировать по всем столбцам в строке и взять MIN (ROWID) в каждой группе во внутреннем запросе, для каждой группы удалить другие строки в группе в externalquery)]

Пример

SQL> select * from employees;

       SSN NAME
---------- ----------
         1 helen
         1 helen
         2 helen
         2 peter
        10 sally
        11 null
        11 null
        12 null

8 rows selected.

SQL> delete from employees where ROWID NOT IN (select min(ROWID) from employees
group by ssn,name);

2 rows deleted.

SQL> select * from employees;

       SSN NAME
---------- ----------
         1 helen
         2 helen
         2 peter
        10 sally
        11 null
        12 null

6 rows selected.
6 голосов
/ 24 апреля 2010

обратите внимание, что ROWID не сохраняется в течение цикла EXPORT и IMPORT базы данных. вы НИКОГДА не должны хранить rowid в ваших таблицах в качестве значения ключа.

3 голосов
/ 07 декабря 2016

ROWID состоит из (но не обязательно в этом порядке, хотя часть ROWNUM, насколько я помню, является последней частью ROWID):

  • ObjId Уникальный идентификатор объекта.
  • FILENO Относительный номер файла данных в табличном пространстве.
  • БЛОКНО Относительный номер блока в файле данных после заголовка файла.
  • ROWNUM Относительный rownum в пределах блока.

Вы можете легко разбить ROWID на его составные поля (OBJID, FILENO, BLOCKNO, ROWNUM), используя SQL-функцию ROWIDTOCHAR (), или использовать:

    SQL> select DBMS_ROWID.ROWID_OBJECT(rowid) "OBJECT",
    2         DBMS_ROWID.ROWID_RELATIVE_FNO(rowid) "FILE",
    3         DBMS_ROWID.ROWID_BLOCK_NUMBER(rowid) "BLOCK",
    4         DBMS_ROWID.ROWID_ROW_NUMBER(rowid) "ROW"
    5  from dual
    6  /
        OBJECT       FILE      BLOCK        ROW
    ---------- ---------- ---------- ----------
           258          1       2082          0

Обратите внимание, что поле ROWNUM (или ROW в приведенном выше запросе) имеет значение , а не такое же значение ROWNUM, что и псевдостолбец SQL ROWNUM, который вы используете в запросе SELECT, который является просто динамически генерируемым номером строки строки в набор результатов.

Обратите внимание, что из-за этой реализации строки, блоки, экстенты и сегменты не могут быть переданы без нарушения ROWID, что делает индексы недействительными.

ROWID является наиболее прямым путем доступа к блоку, в котором находится строка, и однозначно идентифицирует строку, поскольку он кодирует уникальный файл и уникальный блок в этом файле и уникальную строку в этом блоке.

Дополнительная информация:

См .: Примечания СУБД в формате ROWID

Примечание:

Если вы немного разбираетесь в том, как oracle структурирует файлы и блоки базы данных, и знаете немного программирования на C, вы можете довольно легко создать программу, которая отображает содержимое блока, заданного ROWID (8k или любой другой размер блока). используется в базе данных, блок начинается с fileheadersize + BLOCKNO * BLOCK_SIZE. Блок содержит заголовок блока, а затем (при условии, что таблица не кластеризована) rowdir, который для каждой строки дает относительное смещение в блоке для каждой строки. Так, например, в позиции 0 в rowdir - относительное смещение 0-й строки в блоке, в позиции 1 в rowdir - относительная позиция 1-й строки и т. Д. Количество самих строк хранится где-то в заголовок блока (см. документацию по макету блока).

Приложив немного знаний в области программирования и просмотрев документацию по файлам базы данных Oracle, блоков для точной компоновки блоков, вы сможете увидеть, как строки хранятся на диске, и даже восстановить все значения, которые строки хранят для каждого столбца. , Каждая строка содержит метаданные для длины строки и количества столбцов, а для каждого столбца указывается тип столбца, а также размер байта и последующее значение. Байт 0 означает, что данные столбца пустые (или: NULL).

3 голосов
/ 24 апреля 2010

ROWID уникально идентифицирует строку в таблице. ROWNUM дает номер строки результата для конкретного запроса. Они очень разные и не взаимозаменяемы.

Также есть ROW_NUMBER, который является более современной версией ROWNUM и ведет себя немного по-другому. Проверьте эту статью , которая объясняет разницу.

0 голосов
/ 24 апреля 2010

ROWID в основном позволяет иметь две строки с одинаковыми данными. Хотя обычно вы хотите, чтобы ваш первичный ключ был немного более значимым, чем RowID, это просто простой способ автоматического обеспечения уникальности между строками.

...