RDB$DB_KEY
Chaque table et vue contient une pseudo-colonne RDB$DB_KEY
.
La colonne RDB$DB_KEY
est une clé interne qui indique la position d’un enregistrement dans une table. Elle est maintenue par le serveur de base de données pour un usage interne et peut être utilisée par vous dans certains cas comme le moyen le plus rapide de trouver un enregistrement dans une table.
RDB$DB_KEY
est un pointeur logique vers une entrée de la table, et en aucun cas vers une adresse physique sur le disque. Les valeurs de RDB$DB_KEY
ne suivent pas une séquence prévisible, donc n’essayez pas d’utiliser directement des calculs impliquant leurs positions relatives. Cela ne peut être fait qu’avec la fonction MAKE_DBKEY
.
Important
|
Les valeurs de |
RDB$DB_KEY
Pour les tables, le champ RDB$DB_KEY
utilise 8 octets et est de type BINARY(8)
. Pour les vues, le champ RDB$DB_KEY
utilise une taille de 8 octets fois le nombre de tablesutilisées dans la vue. Par exemple, si une vue joint trois tables, la RDB$DB_KEY
utilise 24 octets. Ceci est important lorsque vous travaillez avec des modules PSQL et que vous avez l’intention de stocker RDB$DB_KEY
dans des variables. Vous devez utiliser le type de données BINARY(n)
de la bonne longueur. La valeur exacte de la longueur du champ RDB$DB_KEY
peut être trouvée en utilisant la table système RDB$RELATIONS
. Il est stocké dans le champ RDB$DBKEY_LENGTH
.
RDB$DB_KEY
pour la vue V_FARM
.SELECT
RDB$DBKEY_LENGTH
FROM RDB$RELATIONS
WHERE RDB$RELATION_NAME = 'V_FARM'
RDB$DB_KEY
Puisque RDB$DB_KEY
pointe directement vers l’endroit où l’enregistrement est stocké, la recherche sera plus rapide qu’avec une clé primaire. Si, pour une raison quelconque, la table n’a pas de clé primaire ou d’index unique actif, ou si l’index unique autorise les valeurs NULL
, il est possible que des enregistrements en double existent. Dans ces circonstances, RDB$DB_KEY
est le seul moyen d’identifier précisément chaque enregistrement.
Le serveur Firebird utilise RDB$DB_KEY
pour optimiser certaines méthodes d’accès. Par exemple, pour optimiser le tri externe. Si la largeur des enregistrements à trier est très grande (dépasse la valeur spécifiée dans le paramètre de configuration InlineSortThreshold
), alors au lieu du tri externe classique, seul le tri par clé est utilisé, en sauvegardant RDB$DB_KEY
pour les tables liées, et en effectuant ensuite un Refetch pour récupérer les enregistrements de ces tables en utilisant le RDB$DB_KEY
sauvegardé.
Une autre utilisation de RDB$DB_KEY
et de la fonction MAKE_DBKEY
est de diviser les grandes tables en parties à peu près égales, ce qui est utilisé dans les sauvegardes parallèles.
-- Récupérer les données de la table SOMETABLE contenues dans les pages de données (DP),
-- désignées par la première page de pointeurs (PP).
select * from SOMETABLE
where rdb$db_key >= make_dbkey('SOMETABLE', 0, 0, 0)
and rdb$db_key < make_dbkey('SOMETABLE', 0, 0, 1);
-- Récupérer les données de la table SOMETABLE contenues dans les pages de données (DP),
-- désignées par la deuxième page de pointeurs (PP).
select * from SOMETABLE
where rdb$db_key >= make_dbkey('SOMETABLE', 0, 0, 1)
and rdb$db_key < make_dbkey('SOMETABLE', 0, 0, 2);
...
RDB$DB_KEY
Par défaut, la portée de RDB$DB_KEY
est la transaction courante. Vous pouvez supposer qu’elle reste correcte tant que la transaction courante est en cours. Confirmer ou annuler une transaction rendra les valeurs de RDB$DB_KEY
imprévisibles. Si vous utilisez COMMIT RETAINING, le contexte de la transaction est préservé, ce qui bloque la collecte des déchets et empêche donc l’ancienne clé_db d’être "réaffectée". Dans ces conditions, les valeurs RDB$DB_KEY
pour tous les enregistrements utilisés dans votre transaction sont maintenues valides jusqu’à ce qu’une validation "forcé"(commit) ou un rollback se produise.
Après une validation(commit) ou un retour en arrière(rollback), une autre transaction peut supprimer un enregistrement qui a été isolé dans le contexte de votre transaction et donc traité comme "existant" dans votre application. Toute valeur RDB$DB_KEY
peut maintenant pointer vers un enregistrement inexistant ou vers un autre enregistrement placé à cet endroit.
RDB$RECORD_VERSION
Chaque table contient une pseudo-colonne RDB$RECORD_VERSION
de type BIGINT
.La pseudo-colonne nommée RDB$RECORD_VERSION
renvoie le numéro de la transaction qui a créé la version actuelle de l’enregistrement.
Les tables système RDB$PROCEDURES
, RDB$FUNCTIONS
et RDB$TRIGGERS
contiennent un champ RDB$VALID_BLR
. Il est destiné à signaler qu’un module PSQL (procédure ou trigger) peut être invalide après que les domaines ou les colonnes de table dont il dépend aient été modifiés. Dans ce cas, le champ RDB$VALID_BLR
est mis à 0 pour les procédures ou les triggers dont le code peut être invalide.
Dans les déclencheurs, les procédures et les fonctions, les dépendances portent sur les colonnes de la table à laquelle ils font référence, ainsi que sur tout paramètre ou variable défini dans le module à l’aide de la clause TYPE OF
.
Après que le noyau Firebird ait modifié un domaine, y compris les domaines implicites créés en interne lors de la définition des colonnes ou des paramètres, Firebird recompile en interne toutes les dépendances.
Note
|
L’invalidation se produit pour les procédures, les fonctions, les packages et les triggers, mais pas pour les blocs d’instructions DML, qui sont exécutés avec EXECUTE BLOCK. |
Tout module qui n’a pas pu être recompilé en raison d’une incompatibilité résultant d’un changement de domaine est marqué comme invalide (le champ RDB$VALID_BLR
est mis à 0 dans l’entrée de la table système correspondante (RDB$PROCEDURES
ou RDB$TRIGGERS
).
La réinitialisation (mise à 1 de RDB$VALID_BLR
) se produit lorsque
le domaine est à nouveau modifié et sa nouvelle définition est compatible avec la définition du module précédemment invalide ; ou
le module précédemment invalide est modifié de manière à correspondre à la nouvelle définition du domaine.
La requête ci-dessous recherche les procédures et les triggers dépendant d’un domaine particulier (dans l’exemple, il s’agit du domaine 'MYDOMAIN') et affiche l’état du champ RDB$VALID_BLR
:
WITH VALID_PSQL (
PSQL_TYPE,
ROUTE_NAME,
VALID)
AS (SELECT
'Procedure',
RDB$PROCEDURE_NAME,
RDB$VALID_BLR
FROM
RDB$PROCEDURES
WHERE
RDB$PROCEDURES.RDB$PACKAGE_NAME IS NULL
UNION ALL
SELECT
'Function',
RDB$FUNCTION_NAME,
RDB$VALID_BLR
FROM
RDB$FUNCTIONS
WHERE
RDB$FUNCTIONS.RDB$PACKAGE_NAME IS NULL
UNION ALL
SELECT
'Package',
RDB$PACKAGE_NAME,
RDB$VALID_BODY_FLAG
FROM
RDB$PACKAGES
UNION ALL
SELECT
'Trigger',
RDB$TRIGGER_NAME,
RDB$VALID_BLR
FROM
RDB$TRIGGERS
WHERE
RDB$TRIGGERS.RDB$SYSTEM_FLAG = 0)
SELECT
PSQL_TYPE,
ROUTE_NAME,
VALID
FROM
VALID_PSQL
WHERE
EXISTS(SELECT
*
FROM
RDB$DEPENDENCIES
WHERE
RDB$DEPENDENT_NAME = VALID_PSQL.ROUTE_NAME
AND RDB$DEPENDED_ON_NAME = 'MYDOMAIN');
/*
Remplacez MYDOMAIN par le nom réel du domaine à tester. Utilisez des lettres majuscules si le domaine a été créé sans tenir compte de la casse - sinon, utilisez l'orthographe exacte du nom de domaine en tenant compte de la casse.
*/
La requête suivante recherche les procédures et les déclencheurs qui dépendent d’une certaine colonne de table (dans l’exemple, il s’agit de la colonne 'MYCOLUMN' de la table 'MYTABLE') et fournit des informations sur l’état du champ RDB$VALID_BLR
:
WITH VALID_PSQL (
PSQL_TYPE,
ROUTE_NAME,
VALID)
AS (SELECT
'Procedure',
RDB$PROCEDURE_NAME,
RDB$VALID_BLR
FROM
RDB$PROCEDURES
WHERE
RDB$PROCEDURES.RDB$PACKAGE_NAME IS NULL
UNION ALL
SELECT
'Function',
RDB$FUNCTION_NAME,
RDB$VALID_BLR
FROM
RDB$FUNCTIONS
WHERE
RDB$FUNCTIONS.RDB$PACKAGE_NAME IS NULL
UNION ALL
SELECT
'Package',
RDB$PACKAGE_NAME,
RDB$VALID_BODY_FLAG
FROM
RDB$PACKAGES
UNION ALL
SELECT
'Trigger',
RDB$TRIGGER_NAME,
RDB$VALID_BLR
FROM
RDB$TRIGGERS
WHERE
RDB$TRIGGERS.RDB$SYSTEM_FLAG = 0)
SELECT
PSQL_TYPE,
ROUTE_NAME,
VALID
FROM
VALID_PSQL
WHERE
EXISTS(SELECT
*
FROM
RDB$DEPENDENCIES D
WHERE
D.RDB$DEPENDENT_NAME = VALID_PSQL.ROUTE_NAME
AND D.RDB$DEPENDED_ON_NAME = 'MYTABLE'
AND D.RDB$FIELD_NAME = 'MYCOLUMN');
/*
Remplacez MYTABLE et MYCOLUMN par les noms réels de la table et de sa colonne à vérifier.
Utilisez des lettres majuscules si la table et sa colonne ont été créées sans tenir compte de la casse - sinon, utilisez l'orthographe exacte du nom de la table et de sa colonne en tenant compte de la casse.
*/
Important
|
Tous les modules invalides causés par les changements de domaine/colonne sont reflétés dans le champ
|
Note
|
Autres commentaires
|
Important
|
Cette observation sur les opérateurs d’égalité et d’inégalité s’applique à tout Firebird. |
L’opérateur =
, qui est utilisé dans de nombreuses conditions, ne compare que des valeurs entre elles. Selon la norme SQL, NULL
n’est pas une valeur et, par conséquent, deux valeurs NULL
ne sont ni égales ni inégales l’une à l’autre. Si vous voulez que les valeurs NULL
correspondent l’une à l’autre lorsqu’elles sont combinées, utilisez l’opérateur IS NOT DISTINCT FROM
.
SELECT *
FROM A
JOIN B ON A.id IS NOT DISTINCT FROM B.code
De même, si vous voulez que les valeurs NULL
soient différentes de toute valeur et que deux valeurs NULL
soient traitées comme égales, utilisez l’opérateur IS DISTINCT FROM
au lieu de l’opérateur <>
.
SELECT *
FROM A
JOIN B ON A.id IS DISTINCT FROM B.code