Qu'est-ce que le concept de table préservée clé?


12

J'ai lu dans la documentation Oracle sur la table à clé préservée dans la section Mise à jour des vues de jointure.

Cependant, je n'ai trouvé aucun moyen simple de le comprendre.

J'espère recevoir des détails conceptuels simples autres que la documentation officielle d'Oracle.


1
Avez-vous vu cela sur AskTom?
Jack dit d'essayer topanswers.xyz

Voici une autre explication qui m'a fait comprendre ce concept délicat: dba.stackexchange.com/questions/38728/…
Vadzim

Réponses:


7

Clé préservée signifie que 1 valeur de clé va à 1 table. Donner des contre-exemples peut vous aider à mieux comprendre ce concept.

Exemple 1:

Votre vue contient une agrégation. Supposons que vous ayez la structure de vue suivante.

GroupID, AverageSalary
1 , 10000
2, 12000
3, 14000

Dans cet exemple: vos valeurs proviennent de plusieurs lignes. Si vous essayez de mettre à jour AverageSalary dans cette vue, la base de données n'a aucun moyen de trouver QUELLES lignes à mettre à jour.

Exemple2: votre vue affiche les valeurs de plusieurs tables. Votre vue affiche les valeurs des tables PERSON et PERSON_CONTACT_DETAILS (ID, PersonID, ContactType, ContactValue).

Exemples de lignes:

 1,1,email,ddd@example.com
 1,1,phone,898-98-99

Vous rejoignez ce tableau 2 et affichez des informations plus conviviales pour les entreprises.

PersonId, Name, LastName, Phone1, Email1

Ici, vous souhaitez mettre à jour Phone1 et Email1. Mais votre personID est mappé sur deux lignes différentes, peut-être plus de lignes, dans cet exemple. Dans cette vue, encore une fois, la base de données n'a aucun moyen de trouver QUELLES lignes mettre à jour.

Remarque: Si vous limitez votre vue sql et qu'il est clair de trouver les lignes à mettre à jour, cela peut fonctionner.

Ces deux exemples sont des premiers exemples qui me viennent à l'esprit. Ils peuvent être augmentés. Mais le concept est clair. La base de données doit mapper 1 valeur de clé à 1 table. Par exemple, vous avez une à une table PERSON, PERSON_DETAILS. Ici, l'affichage et la mise à jour fonctionneront car ils sont un à un.


que faire si la table que vous souhaitez mettre à jour contient une clé primaire composite?
johny pourquoi

7

La documentation que vous avez déjà lue le dit assez bien. Pour expliquer davantage:

Le concept d'une table à clé préservée est fondamental pour comprendre les restrictions sur la modification des vues de jointure.

Normalement, un updateagit sur une seule table. Pour éviter les sous-requêtes tortueuses dans le filtre, Oracle vous permet de updatevisualiser (ou de sous-interroger) tant qu'il est toujours en mesure de mapper facilement les modifications que vous effectuez sur de vraies lignes sous-jacentes dans une table. Cela est possible si la setclause ne modifie que les colonnes d'une table 'clé préservée':

Une table est préservée si chaque clé de la table peut également être une clé du résultat de la jointure. Ainsi, une table à clés conservées a ses clés préservées via une jointure.

Par exemple:

create table foo( foo_id integer primary key, foo_val integer not null );
create table bar( bar_id integer primary key, bar_val integer not null, 
                  foo_id integer not null references foo );

update (select * from foo join bar using(foo_id)) set foo_val=1;
ORA-01779: cannot modify a column which maps to a non key-preserved table

update (select * from foo join bar using(foo_id)) set bar_val=1;
0 rows updated.

la première mise à jour échoue car Oracle ne dispose d'aucun moyen de mappage 1: 1 foo_valdans la requête vers foo_valin foo- à l'inverse, la deuxième mise à jour réussit car Oracle peut mapper 1: 1 chacun bar_valvers bar_valin bar. L'important est qu'il foo_idest unique dans foo- donc pour chaque ligne bar, il ne peut y avoir au plus qu'une ligne correspondante foo(en fait exactement 1 dans cet exemple, mais il en va de même pour une clé étrangère annulable - le fait est qu'il n'y a jamais plusieurs lignes).


3

Permettez-moi de donner un exemple en premier et de l'expliquer plus tard. Considérons 2 tables Etudiants (t_étudiants) et Cours (t_cours).

  • La table des étudiants (stundentid, name, courseid) a une clé primaire sur l'ID étudiant.
  • La table des cours (courseid, coursename) a une clé primaire sur l'ID du cours.

Lorsque ces deux tables sont jointes ->

select * from t_students S, t_course C where S.courseid=C.courseid; 

Les données résultantes auront exactement le même nombre de lignes que la table Students. Il n'y aura pas de valeurs en double de studentid dans le jeu de résultats (studentid est conservé). Cependant, bien que l'ID de cours soit unique dans la table des cours, il sera répété plusieurs fois dans l'ensemble de résultats, car de nombreux étudiants peuvent avoir opté pour le même cours (en d'autres termes, l'ID de cours n'est pas conservé).

Avec cet exemple en place, vous pouvez conclure que:

  • Chaque clé de la table de base agit comme la clé des données résultantes après la jointure (studentid)
  • Les lignes de la ligne de base apparaissent au moins une fois dans les données résultantes. (Pas de lignes en double)

C'est le concept des tables conservées clés.

Pour savoir si les colonnes de vue peuvent être mises à jour,

select * from all_updatable_columns where table_name='V_VIEW_NAME';

PS: indiquez le nom de la table / vue en lettres MAJUSCULES.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.