Bases de données réparties: TP1 Partie 1: répartition 1) et 2) Création d'un user avec les droits suffisants CREATE USER cuenot IDENTIFIED BY cuenot; GRANT connect, resource, create view, create database link, create snapshot TO cuenot; 3) Création d'une table répartie sur chaque DB (Employe1 et Employe2) # Sur base1 CREATE TABLE Employe1( nomemp VARCHAR(10), CONSTRAINT idemp_pk PRIMARY KEY (idemp)); # Sur base2 CREATE TABLE Employe2( nomemp VARCHAR(10), CONSTRAINT idemp_pk PRIMARY KEY (idemp)); 4) Mise en place d'une vue Employe sur chaque machine pour rendre la fragmentation transparente # Sur la base1 CREATE DATABASE LINK BASE2.RIA USING 'BASE2.RIA'; CREATE VIEW Employe AS SELECT Employe1.idemp, Employe1.nomemp FROM Employe1@BASE1.RIA SELECT Employe2.idemp, Employe2.nomemp FROM Employe2@BASE2.RIA; # Sur la base2 CREATE DATABASE LINK BASE1.RIA USING 'BASE1.RIA'; CREATE VIEW Employe AS SELECT Employe2.idemp, Employe2.nomemp FROM Employe2@BASE2.RIA SELECT Employe1.idemp, Employe1.nomemp FROM Employe1@BASE1.RIA; 5) Création de triggers pour gérer l'insertion et l'auto-increment: # Creation d'une sequence CREATE SEQUENCE new_emp; # Creation du trigger d'auto-increment /!\ Marche pas CREATE TRIGGER Tr_incemp BEFORE INSERT ON Employe 1
WHEN (new.idemp is null) SELECT new_emp.nextval INTO :New.idemp from DUAL; END; #Si pair: insertion sur la base1 #Si impair: insertion sur la base2 CREATE OR REPLACE TRIGGER Tr_repemp INSTEAD OF INSERT on Employe IF :New.idemp mod 2 = 0 THEN INSERT INTO Employe1@BASE1.RIA(idemp,nomemp) VALUES (:New.idemp,:New.nomemp); ELSE INSERT INTO Employe2@BASE2.RIA(idemp,nomemp) VALUES (:New.idemp,:New.nomemp); END IF; END; # Test: INSERT INTO Employe (idemp, nomemp) VALUES ('1', 'Test1'); INSERT INTO Employe (idemp, nomemp) VALUES ('2', 'Test2'); 6) Création d'une table fragmentée verticalement # Sur base1 CREATE TABLE Produit1( nomprod VARCHAR(10), prixachat FLOAT, CONSTRAINT idprod_pk PRIMARY KEY (idprod)); # Sur base2 CREATE TABLE Produit2( prixvente FLOAT, CONSTRAINT idprod_pk PRIMARY KEY (idprod)); # Création de la vue CREATE VIEW Produit AS SELECT Produit1.idprod, Produit1.nomprod, Produit1.prixachat, Produit2.prixvente FROM Produit1@BASE1.RIA, Produit2@BASE2.RIA #Création du trigger sur les 2 bases CREATE OR REPLACE TRIGGER Tr_prod1 INSTEAD OF INSERT on Produit INSERT INTO Produit1@BASE1.RIA(idprod,nomprod,prixachat) VALUES (:New.idprod,:New.nomprod,:New.prixachat); INSERT INTO Produit2@BASE2.RIA(idprod,prixvente) VALUES (:New.idprod,:New.prixvente); 2
END; #Test INSERT INTO Produit (idprod, nomprod, prixachat, prixvente) VALUES ('1', 'pain', '1', '2'); 7) Creation d'une page achat CREATE TABLE Achat1( idachat INTEGER, dateachat DATE, CONSTRAINT idachat_pk PRIMARY KEY (idachat), CONSTRAINT idachat_fk FOREIGN KEY (idemp) REFERENCES Employe1(idemp)); # Base2 CREATE TABLE Achat2( idachat INTEGER, dateachat DATE, CONSTRAINT idachat_pk PRIMARY KEY (idachat), CONSTRAINT idachat_fk FOREIGN KEY (idemp) REFERENCES Employe2(idemp)); # Vue CREATE VIEW Achat AS SELECT Achat1.idachat,Achat1.idprod,Achat1.idemp,Achat1.dateachat FROM Achat1@BASE1.RIA SELECT Achat2.idachat,Achat2.idprod,Achat2.idemp,Achat2.dateachat FROM Achat2@BASE2.RIA; # Base2 CREATE VIEW Achat AS SELECT Achat2.idachat,Achat2.idprod,Achat2.idemp,Achat2.dateachat FROM Achat2@BASE2.RIA SELECT Achat1.idachat,Achat1.idprod,Achat1.idemp,Achat1.dateachat FROM Achat1@BASE1.RIA; # Trigger CREATE OR REPLACE TRIGGER Tr_achat1 INSTEAD OF INSERT on Achat IF :New.idemp mod 2 = 0 THEN INSERT INTO Achat1@BASE1.RIA(idachat,idprod,idemp,dateachat) VALUES (:New.idachat,:New.idprod,:New.idemp,:New.dateachat); ELSE INSERT INTO Achat2@BASE2.RIA(idachat,idprod,idemp,dateachat) 3
VALUES (:New.idachat,:New.idprod,:New.idemp,:New.dateachat); END IF; END; # Test INSERT INTO Achat (idachat, idprod, idemp, dateachat) VALUES ('1', '5', '1', '20071210'); INSERT INTO Achat (idachat, idprod, idemp, dateachat) VALUES ('1', '8', '2', '20071220'); Partie 2: réplication # Sur la base1 CREATE DATABASE LINK BASE2.RIA CONNECT TO cuenot IDENTIFIED BY cuenot USING 'BASE2.RIA'; # Sur la base1 CREATE DATABASE LINK BASE1.RIA CONNECT TO cuenot IDENTIFIED BY cuenot USING 'BASE1.RIA'; 1) Création d'une table fournisseur # Création de la table CREATE TABLE Fournisseur1( idfourn INTEGER, nomfourn VARCHAR(10), adrfourn VARCHAR(20), CONSTRAINT idfourn_pk PRIMARY KEY (idfourn)); # Création des vues matérialisées pour la réplication complète CREATE VIEW Fournisseur AS SELECT * FROM Fournisseur1@BASE1.RIA; # Base2 CREATE MATERIALIZED VIEW Fournisseur REFRESH COMPLETE AS SELECT * FROM Fournisseur1@BASE1.RIA; # Test INSERT INTO Fournisseur(idfourn,nomfourn,adrfourn) VALUES('1', 'kugar', 'strasbourg'); INSERT INTO Fournisseur(idfourn,nomfourn,adrfourn) VALUES('2', 'roger', 'dtc'); # Remplacement par une réplication incrémentale #Base1 on crée un snapshot CREATE SNAPSHOT LOG ON Fournisseur1 ; 4
# Base 2 on met a jour la vue matérialisée ALTER MATERIALIZED VIEW Fournisseur REFRESH FAST; # ou on la drop et recrée CREATE MATERIALIZED VIEW Fournisseur REFRESH FAST AS SELECT * FROM Fournisseur1@BASE1.RIA; 2) # Donner les droits a quelqu'un d'autre GRANT select ON Fournisseur TO mikrobe; GRANT select ON MLOG$_Fournisseur TO mikrobe; # Réplication complète REFRESH COMPLETE AS SELECT * FROM Mikrobe.Fournisseur@BASE1.RIA; #Base2 REFRESH COMPLETE AS SELECT * FROM Mikrobe_Fourn@BASE1.RIA; # Réplication incrémentale REFRESH FAST AS SELECT * FROM Mikrobe.Fournisseur@BASE1.RIA; CREATE SNAPSHOT LOG ON Mikrobe_Fourn ; #Base2 REFRESH FAST AS SELECT * FROM Mikrobe_Fourn@BASE1.RIA; 5
3) # Mise en place d'un table catégorie CREATE TABLE Categorie1( idcat INTEGER, nomcat VARCHAR(10), CONSTRAINT idcat_pk PRIMARY KEY (idcat)); DBMS_REPCAT.CREATE 6