web-dev-qa-db-fra.com

ROWID (Oracle) - tout usage?

D'après ce que je comprends, le ROWID est une valeur unique pour chaque ligne du résultat renvoyé par une requête.

Pourquoi avons-nous besoin de ce ROWID? Il existe déjà le ROWNUM dans Oracle.

Est-ce que quelqu'un a utilisé ROWID dans une requête SQL?

32
user319280

ROWID est l'emplacement physique d'une ligne. Par conséquent, il s'agit du moyen le plus rapide de localiser une ligne, même plus rapidement qu'une recherche par clé primaire. Cela peut donc être utile dans certains types de transaction où nous sélectionnons certaines lignes, stockons leurs ROWID, puis les utilisons ultérieurement dans les clauses where pour DML par rapport à ces mêmes lignes. 

La syntaxe Oracle SELECT ... FOR UPDATE utilise implicitement ROWID lorsque nous mettons à jour la ligne verrouillée à l'aide de WHERE CURRENT OF. La table EXCEPTIONS (référencée lors de l'application de contraintes avec la clause EXCEPTIONS INTO) contient également une colonne ROW_ID. Cela nous permet d'identifier rapidement les lignes qui rompent notre contrainte. 

Ce dernier exemple renvoie à un autre usage général: lorsque nous écrivons un morceau de code générique et qu’il nous faut un mécanisme pour stocker les UID sans souci du type de données, des clés composites, etc. 

ROWNUM, par contre, est une pseudo-colonne qui marque une ligne dans un jeu de résultats donné. Cela n'a pas de signification permanente. 

modifier

Le ROWID d'un enregistrement donné peut changer pendant la durée de vie d'un système, par exemple via une reconstruction de table. De plus, si un enregistrement est supprimé, un nouvel enregistrement peut être attribué à ROWID. Par conséquent, les ROWID ne peuvent pas être utilisés à long terme comme UID. Mais ils sont assez bons pour une utilisation dans une transaction.

42
APC

Je connais maintenant un exemple pour cela.

supposons que vous ayez une table sans clé primaire. si cette table peut avoir des lignes en double. Comment voulez-vous supprimer les lignes en double tout en conservant exactement une de ce type? 

Oracle fournit ROWID comme une sorte de substitut de la clé primaire. Vous pouvez écrire une requête imbriquée de type corrélé [(groupez toutes les colonnes de la ligne et prenez MIN (ROWID) dans chaque groupe de la requête interne. Pour chaque groupe, supprimez les autres lignes du groupe de la requête externe)

Exemple

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.
11
user319280

notez que ROWID ne persiste pas dans les cycles EXPORT et IMPORT de la base de données . vous ne devez JAMAIS stocker un rowid dans vos tables en tant que valeur de clé.

6
Randy

Un ROWID comprend (mais pas nécessairement dans cet ordre, bien que la partie ROWNUM soit la dernière partie de ROWID pour autant que je m'en souvienne):

  • OBJID Identificateur unique de l'objet.
  • FILENO Le nombre relatif du fichier de données dans le tablespace.
  • le BLOCKNO Le numéro de bloc relatif dans le fichier de données après l'en-tête de fichier.
  • the ROWNUM Le rownum relatif dans le bloc.

Vous pouvez facilement décomposer le ROWID en ses champs composites (OBJID, FILENO, BLOCKNO, ROWNUM) en utilisant la fonction SQL ROWIDTOCHAR () ou utiliser:

    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

Notez que le champ ROWNUM (ou ROW dans la requête ci-dessus) est non identique à la pseudo-colonne SQL ROWNUM que vous utilisez dans la requête SELECT, qui est simplement le numéro d’aller généré dynamiquement de la ligne dans le jeu de résultats.

Notez qu'en raison de cette implémentation, les lignes, les blocs, les extensions et les segments ne sont pas transportables sans rompre le ROWID, ce qui invalide les index.

Le ROWID est le chemin d'accès le plus direct au bloc dans lequel la ligne réside et identifie de manière unique la ligne, car il code le fichier unique et le bloc unique dans ce fichier et la ligne unique dans ce bloc.

Plus d'information:

Voir: Notes sur le SGBD sur le format ROWID

Remarque:

Si vous comprenez un peu la manière dont Oracle structure les fichiers de base de données et les blocs et connaissez la programmation C, vous pouvez très facilement créer un programme affichant le contenu du bloc donné par ROWID (un fichier de 8 Ko, ou la taille de bloc utilisée). la base de données, bloc qui commence à la taille du fichier + BLOCKNO * BLOCK_SIZE. Le bloc contient l'en-tête du bloc et ensuite (en supposant que la table n'est pas clusterisée) le rowdir, qui donne pour chaque ligne le décalage relatif dans le bloc pour chaque ligne. à la position 0 dans le rowdir correspond au décalage relatif de la 0-ème ligne dans le bloc, à la position 1 dans le rowdir à la position relative de la 1-ère ligne, etc. Le nombre de lignes lui-même est stocké quelque part dans l'en-tête du bloc (Voir la documentation orale sur la disposition des blocs).

Avec un peu de connaissances en programmation et en consultant la documentation sur les fichiers de base de données Oracle et des blocs pour la disposition exacte des blocs, vous pouvez voir comment les lignes sont stockées sur le disque et même reconstruire toutes les valeurs que les lignes stockent pour chaque colonne. Chaque ligne contient des métadonnées pour la longueur de la ligne et le nombre de colonnes, ainsi que, pour chaque colonne, une indication du type de la colonne et de la taille en octets, puis de la valeur. Taille d'octet 0 signifie que les données de la colonne sont vides (ou: NULL).

3
Rob Heusdens

ROWID identifie de manière unique une ligne dans une table. ROWNUM vous donne le numéro de ligne d'un résultat pour une requête spécifique. Les deux sont très différents et ne sont pas interchangeables.

ROW_NUMBER est également une version plus moderne de ROWNUM et se comporte légèrement différemment. Découvrez cet article qui explique la différence.

3
Mark Byers

ROWID vous permet en principe d’avoir deux lignes avec exactement les mêmes données. Bien que vous souhaitiez généralement que votre clé primaire soit un peu plus significative qu'un RowID, il s'agit simplement d'un moyen simple de garantir automatiquement l'unicité entre les lignes.

0
Robert Greiner