Le ROWID et la place qu’il prend, par Jonathan Lewis

Cet article est la traduction d’un article de Jonathan Lewis publié sur son blog. L’article original en anglais se trouve ici.

Le ROWID identifie un enregistrement d’une table dans la base de données, à partir de l’adresse physique du bloc et du numéro d’enregistrement dans le bloc. Il est utilisé principalement dans les indexes pour pointer sur l’enregistrement de la table, et dans les tables pour les pointeurs des chained rows. C’est le moyen le plus direct car il permet d’aller directement sur le bloc qui contient l’enregistrement.

Jusqu’à Oracle 7, l’adresse physique d’un bloc était constitué du numéro du fichier de la base (absolute file_number, AFN ou FILE_ID ou FILE#) et du numéro de bloc relatif au fichier (block_number ou BLOCK_ID ou BLOCK#). L’ensemble est appelé DBA: Data Block Address. Le ROWID utilise cela pour identifier le bloc, et y ajoute le numéro d’enregistrement dans le bloc (ROW_NUMBER ou ROW#).

A partir d’Oracle 8, l’identification des fichiers est relative au tablespace. Cela permet de supporter plus de fichiers dans une base, et de rendre les tablespaces plus indépendants. On parle alors de numéro de fichier relatif à la tablespace (relative file_number, RFN ou RELATIVE_FNO ou RFILE#). Avec le numéro de bloc relatif au fichier, l’ensemble constitue le RDBA: Relative Data Block Address. Pour les bigfile tablespaces, ne comportant qu’un seul fichier, il s’agit seulement du block#.
Pour trouver un bloc dans la base, il est donc nécessaire de connaître aussi le tablespace. Plutôt que d’ajouter le numéro de tablespace dans le ROWID, c’est le DATA_OBJECT_ID (DATAOBJ# ou OBJD ou OBJ ou OBJECT_NUMBER) qui est utilisé. Il s’agit de l’identifiant de l’objet physique, c’est à dire du segment, contrairement à l’OBJECT_ID (OBJ# ou OBJN) qui est l’identifiant de l’objet logique. Le DATA_OBJECT_ID permet d’identifier le tablespace grâce au dictionnaire, puisque un segment se trouve dans un et un seul tablespace.
Ainsi, le ROWID ne comprends que des informations physiques pour identifier le bloc (segment, datafile, block). C’est ce qui rend optimal les tablespaces transportables ainsi que l’échange de partitions, car ils n’ont pas à modifier le contenu des blocs mais seulement les méta-données du dictionnaire.

L’ancien ROWID est appelé le Restricted ROWID, il est affiché sous la forme block#.row#.file# et celui qui inclut le data_objet_id est appelé Extended ROWID, il est affiché encodé (6 caractères pour dataobj#, 9 caractères pour file#/block#, 3 caractères pour row#).

Cet article de Jonathan Lewis explique la taille nécessaire au stockage du ROWID dans différents cas, ce qui peut être utile pour estimer la taille d’un index par exemple.

Dans une récente discussion sur le blog un article de Charles Hooper , j’ai fait un commentaire disant qu’il est difficile d’être précis et non-ambigu lorsqu’on estime l’espace nécessaire au stockage du ROWID. Je vais donc essayer d’énumérer tous les cas possible que l’on peut rencontrer. Franchement, je ne suis pas sûr d’être exhaustif dès le premier jet.

Alors, quelle place prend un ROWID ?
Lire la suite