Base De Données | BI experience

Archive pour le mot-clef ‘Base de données’

Copier une base de données vers une autre avec Talend

Jeudi 25 août 2011

Depuis la version 4.1.2, Talend a sortie une option assez remarquable :le Dynamic Schema

Je vous propose dans ce post de détailler la démarche que nous avons adoptée pour l‘alimentation de notre infocentre : copie des différentes bases de données de la société à partir desquelles le datawarehouse est alimenté.

Un simple job sera réalisé pour amener les données d’une base de données source vers une base de données cible :
job_fils

Voici l’option en question que vous pourrez utiliser dans votre input:

option_dynamic_schema2

Et si vous avez des règles de gestion à ajouter n’hésitez pas avec le tJavaFlex :
action_sur_lignes1

/**l’exemple de traitement en plus lisible…**/
for(int i = 0; i < row3.dyn_Col.metadatas.size(); i++) {
row3.dyn_Col.metadatas.get(i).setName(row3.dyn_Col.metadatas.get(i).getName().toLowerCase());
}

Ce job, décrit ci-dessus, est appelé par un job père qui lui donne le contexte contenant le nom de la table courante à migrer :

job_pere

Une variable de context est passée au sous job (monsousjobcopie) : my_current_table

L’input requête sur une table de paramétrage. En effet nous n’avons pas forcement besoin de toutes les tables de toutes les bases de données. Donc à travers une table de paramétrage nous choisisson celle que l’on veut migrer :

input_job_pere

Ce job père appelle aussi un autre sous job qui lui va permettre de migrer les indexes :
index

Donc pour chaque table on fera un appel à une routine (code qu’il y a dans le tJava):

routines.IndexMigrer.migrate_index(((java.sql.Connection)globalMap.get(”conn_tMSSqlConnection_2″)), ((String)globalMap.get(”current_TABLE.nom_table”)), ((java.sql.Connection)globalMap.get(”conn_tPostgresqlConnection_4″)),context.Cible_Schema + (String)globalMap.get(”schema”) + “.” +
((String)globalMap.get(”current_TABLE.nom_table”)));

Et en bonus voici la routine que nous avons créés qui selon la base de données (Oracle, Posgres, SQL Server 2000 ou SQL Server 2005) va requêter dans la bonne table système :

/***************Routines migration indexes ************************/

public class IndexMigrer {
public static void migrate_index(Connection org_connect, String org_nomtable,
Connection dest_connect, String dest_nomtable)  throws java.sql.SQLException
{
if(org_connect.getMetaData().getDatabaseProductName().equalsIgnoreCase(”Microsoft SQL Server“) )
{
Statement stat = org_connect.createStatement();
ResultSet rs;
if(org_connect.getMetaData().getDatabaseMajorVersion()==9)
{
rs=stat.executeQuery(”SELECT IDX.name as index_name, COL.name as column_name FROM sys.index_columns IDXC”
+” INNER JOIN sys.objects OBJ”
+” ON IDXC.object_id = OBJ.object_id”
+” INNER JOIN sys.schemas SCH”
+” ON SCH.schema_id = OBJ.schema_id”
+” INNER JOIN sys.indexes IDX”
+” ON (IDXC.object_id = IDX.object_id AND IDXC.index_id = IDX.index_id)”
+” INNER JOIN sys.columns COL”
+” ON (IDXC.column_id = COL.column_id AND OBJ.object_id = COL.object_id)”
+” where OBJ.name=\’”+org_nomtable+”\’”
+” ORDER BY OBJ.name” );
}
else
{
rs=stat.executeQuery(”select i.name as index_name,c.name as column_name”
+” from sysindexkeys as indk”
+” inner join sysindexes as i on”
+” (indk.indid=i.indid and indk.id=i.id )”
+” inner join syscolumns as c on”
+” (indk.colid=c.colid and indk.id=c.id )”
+” inner join sysobjects as o on”
+” (indk.id=o.id)”
+” and o.name=\’”+org_nomtable+”\’ ”
+” ORDER BY o.name” );
}
Map m =new HashMap();
Map m_key=new HashMap();
while(rs.next())
{
if(!m.containsKey(rs.getString(1)))
{
List l = new ArrayList();
l.add(rs.getString(2));
m.put(rs.getString(1),l);
m_key.put(rs.getString(1), rs.getString(1));
}
else if(m.containsKey(rs.getString(1)))
{
List l=(List)m.get(rs.getString(1));
l.add(rs.getString(2));
m.put(rs.getString(1),l);
}
}
StringBuffer sb=new StringBuffer();
for (Iterator i = m.keySet().iterator() ; i.hasNext();){
String key = (String)i.next();
sb.append(”CREATE INDEX “);
sb.append(”IDX_”+key);
sb.append(” ON “+dest_nomtable+” (”);
List l=(List)m.get(key);
for(int j=0;j<l.size();j++)
{
sb.append(l.get(j));
if(j!=l.size()-1)
sb.append(”,”);
}
sb.append(”);\n”);
}
try{
Statement bla=dest_connect.createStatement();
System.out.println(”"+sb.toString());
bla.execute(sb.toString());
}
catch (java.sql.SQLException e)
{
//System.out.println(dest_nomtable);
System.out.println(e.getMessage());
}
dest_connect.commit();
//System.out.println(dest_nomtable);
}
if(org_connect.getMetaData().getDatabaseProductName().equalsIgnoreCase(”PostgreSQL“))
{
Statement stat = org_connect.createStatement();
ResultSet rs=stat.executeQuery(”SELECT indkey as colonne_index,pci.relname as nom_index,pct.relname as nom_table from pg_index as pi”
+” , pg_class as pci, pg_class as pct ”
+” where pci.oid=pi.indexrelid”
+” and pct.oid=pi.indrelid and pct.relname  not like ‘pg_%’ and pct.relname=’”+org_nomtable+”‘ ” );
while( rs.next())
{
String s=rs.getString(1);
java.util.StringTokenizer tokenizer = new java.util.StringTokenizer(s, ” “);
List <Integer> num_columns=new ArrayList();
while ( tokenizer.hasMoreTokens() ) {
num_columns.add(Integer.parseInt(tokenizer.nextToken()));
}
Statement sel=org_connect.createStatement();
ResultSet rsset=sel.executeQuery(”SELECT * from “+org_nomtable+” LIMIT 1″);
StringBuffer sb=new StringBuffer();
sb.append(”CREATE INDEX “+rs.getString(2)+” ON “+dest_nomtable+” (” );
Iterator i=num_columns.iterator();
while(i.hasNext())
{
sb.append(rsset.getMetaData().getColumnLabel((Integer)i.next()));
if(i.hasNext())
sb.append(”,”);
}
sb.append(”) ;\n”);
Statement bla=dest_connect.createStatement();
bla.execute(sb.toString());
dest_connect.commit();
bla.close();
}
}
if(org_connect.getMetaData().getDatabaseProductName().equalsIgnoreCase(”Oracle“))
{
Statement stat = org_connect.createStatement();
ResultSet rs=stat.executeQuery(”SELECT col.index_name,col.column_name FROM all_indexes cons INNER JOIN all_ind_columns col ON cons.owner = col.index_owner AND cons.index_name = col.index_name WHERE OWNER = ‘AEFE’ AND cons.table_name=\’”+org_nomtable+”\’” );
Map m =new HashMap();
Map m_key=new HashMap();
while(rs.next())
{
if(!m.containsKey(rs.getString(1)))
{
List l = new ArrayList();
l.add(rs.getString(2));
m.put(rs.getString(1),l);
m_key.put(rs.getString(1), rs.getString(1));
}
else if(m.containsKey(rs.getString(1)))
{
List l=(List)m.get(rs.getString(1));
l.add(rs.getString(2));
m.put(rs.getString(1),l);
}
}
StringBuffer sb=new StringBuffer();
for (Iterator i = m.keySet().iterator() ; i.hasNext();){
String key = (String)i.next();
sb.append(”CREATE INDEX “);
sb.append(”IDX_”+key);
sb.append(” ON “+dest_nomtable+” (”);
List l=(List)m.get(key);
for(int j=0;j<l.size();j++)
{
sb.append(l.get(j));
if(j!=l.size()-1)
sb.append(”,”);
}
sb.append(”);\n”);
}
Statement bla=dest_connect.createStatement();
System.out.println(”"+sb.toString());
bla.execute(sb.toString());
dest_connect.commit();
}}}

Très important, si un problème de typage persiste n’hésitez pas à modifier les fichiers de mapping dans :

fichier_mappingCes fichiers sont utiles et simples à utiliser puisqu’ils permettent de connaitre les transformations de typage. En gros voici comment procède Talend :

typage BDD source => typage JAVA => typage BDD cible

Exemple d’utilisation :

ma base de données source est SQL server et ma base de données cible est postgres  :

La démarche sera donc d’aller dans  MSSQL_mapping.xml  et de regarder la rubrique : <dbToTalendTypes> pour voir en quel type Java les typages de ma base de données MSSQL seront transformés. Ensuite il faudra regarder dans postgres_mapping.xml pour regarder les typages par défault que propose Talend dans la rubrique  <talendToDbTypes> pour la retransformation des types JAVA en typages postgres.

Vous pourrez ainsi personnaliser ces transformations.

Si ces fichiers sont modifiés il faudra bien sur les répercutés sur tous les clients  TIS  et sur le serveur  dans les workspaces dans:

  • .JAVA > src > xmlMappings
  • et dans .JAVA > classes > xmlMappings

J’espère que ce post vous aura permis de voir les possibilités qu’offrent la solution Talend pour ce genre de besoin.

N’hésitez pas à poster pour donner votre opinion!

Optimisation du serveur de base de données PostgreSQL

Samedi 1 mai 2010

Pour de bonnes performances au niveau de la restitution, il faut à la fois optimiser les rapports, cube, univers.. créés grâce au logiciel de restitution et la base de données où est stockée le datawarehouse. Celle-ci doit passer par une phase d’optimisation, de configuration.

Je vous propose dans ce post de détailler la configuration de postgreSQL qu’un DBA est venu faire chez nous.

Tout d’abord notre environnement de production où la BDD a un serveur dédié était :

  • VM Debian
  • 2 Go RAM
  • 2 processeurs Intel(R) Xeon(R) 1,6 Ghz

kernel.shmmax : désigne le maximum de mémoire partagée entre les processus.

Pour connaître sa valeur actuelle voici la commande : cat /proc/sys/kernel/shmmax

Valeur par défaut : kernel.shmmax=33554432  (32 Mo de segment )

Pour changer cette valeur sysctl -w kernel.shmmax=134217728 (soit 128 Mo)  (cette valeur a été choisie par rapport à la configuration citée plus haut. Elle pourra donc être modulée)

Ensuite toute la configuration se fera dans le fichier : postgresql/x.x/main/postgresql.conf

work_mem=10MB : Ce paramètre est utilisé pour chaque connexion pour les opérations de tris et de hachages.

max_connexions=100 : Valeur par défaut, à conserver.

maintenance_work_mem=128MB : Ce paramètre est utilisé pour les opérations de maintenance (CREATE INDEX, VACUUM, etc). (On pourra jouer sur ce paramètre en fonction de la configuration du serveur)

effective_cache_size=1GB : Permet de donner à l’optimiseur une idée de la mémoire disponible pour le cache des tables et des index. En général, on peut le positionner jusqu’à 2/3 de la RAM pour une machine dédiée à PostgreSql, mais la moitié est suffisante. (On pourra jouer sur ce paramètre en fonction de la configuration du serveur)

shared_buffers = 64MB : Taille des buffers de mémoire partagée entre les threads PostgreSQL. (On pourra aussi jouer sur ce paramètre en fonction de la configuration du serveur)

wal_buffers = 4 MB Buffer alloué au process wal_writer. Largement suffisant, sachant qu’il y a très peu d’écriture en utilisation normale vu que nous sommes dans un contexte décisionnel avec un datawarehouse qui est utilisé pour faire de la lecture intensive.

checkpoint_segments = 10 : Nombre de segments écrits dans le fichier de LOG avant checkpoint, ie écriture dans les fichiers de data.

checkpoint_completion_target = 0.8 : Pourcentage de temps utilisé par le process writer pour effectuer le checkpoint par rapport au temps max d’écriture sur les 10 segments de LOG. Ce paramètre permet de diluer l’application des modifications sur les fichiers de data dans le temps.

random_page_cost = 2.0 : Passer à 2.0 pour les disques rapides récents, 4.0 (défaut) pour les disques lents. Il favorise l’utilisation des index.

Redémarrer postgresql pour appliquer ces changements :
/etc/init.d/postgresql-x.x restart

Le changement de ces quelques paramètres a vraiment amélioré significativement nos performances. J’espère que ce post pourra  en aider d’autres pour que leurs requêtes SQL soient encore plus réactives. Si vous connaissez d’autres astuces, n’hésitez pas postez!

Enquête sur les tables de nos bases de données

Jeudi 30 octobre 2008

Dans le décisionnel, la volumétrie est quand même une donnée non négligeable. Vous avez envie d’en savoir plus sur vos tables? Voilà une requête qui peut vous intéressez :

—————————————

/*On crée la table  #temp qui contiendra les infos sur chaque table de notre BDD*/

CREATE TABLE #temp(
rec_id int IDENTITY (1, 1),
NomTable varchar(128),
nbrLignes int,
data_space decimal(15,2),
index_space decimal(15,2),
total_size decimal(15,2),
percent_of_db decimal(15,12),
db_size decimal(15,2))

/*j’execute ce script qui me permet de relevé des infos grace aux tables system*/

EXEC sp_msforeachtable @command1=”insert into #temp(nbrLignes, data_space, index_space) exec sp_mstablespace ‘?’”,
@command2=”update #temp set NomTable= ‘?’ where rec_id = (select max(rec_id) from #temp)”
UPDATE #temp
SET total_size = (data_space + index_space), db_size = (SELECT SUM(data_space + index_space) FROM #temp)
UPDATE #temp
SET percent_of_db = (total_size/db_size) * 100
SELECT * FROM #temp ORDER BY total_size DESC

/* vous pouvez tout sélectionner */
SELECT * FROM #temp

/*les 5 premières plus grosse tables */
SELECT TOP 5 * FROM #temp ORDER BY total_size DESC

/*supprimer la table */
DROP TABLE #temp

————————————

Cette requête a été fait pour SQL Server et les tailles sont exprimés en Mo

Avec quel outil modélisez vous vos bases de données ?

Lundi 1 septembre 2008

Et bien oui, les vacances sont finies… Pour reprendre,  je voudrais faire un inventaire de quelques logiciels qui permettent de modéliser les Bases de données :

PowerAMC (payant) :

Cet ensemble d’outils supporte plusieurs techniques de modélisation standard :

  • modélisation Merise (Données et Traitements)
  • Modélisation UML particulièrement adaptée à la logique des applications
  • Modélisation des Processus Métiers dédiée aux non-informaticiens pour leur faciliter l’expression des besoins.

Il propose

  • un Référentiel d’Entreprise (en option pour une gestion de l’ensemble des méta-données)
  • une série d’outils pour la génération de code : synchronisation entre modèle et code.
  • de prendre en charge des structures de SGBD-R pour plus de 45 moteurs du marché
  • Génération automatique de code pour les plates-formes Java, Microsoft .Net, WSDL, XML, PowerBuilder, ebXML, BPEL4WS.
  • Modèle de génération automatique pour Java EJB, Web Services…

SQL Designer (gratuit) :

Trés sympathique, il permet

  • de générer du code SQL pour MYSQL ou SQLITE
  • d’enregistrer votre modèle dans un fichier XML, ou de lancer un modèle à partir d’un fichier XML

Ce qui le différencie des autres c’est que tout se fait avec un client léger mais il reste vraiment très simple pour la modélisation. ( il ne fait ni du mcd ni de l’uml, ni de modèle relationnel, aucun modèle selon merise…)

Vous pourrez télécharger le client ici : SQL Designer. Vous pourrez aussi y consulter la démo…

DBDesigner (gratuit):

DB designer  est un logiciel plus  sophistiqué puisque l’on pourra:

  • faire du mcd, du modèle relationnel… 
  • permette de créer et de gérer la base de données sous MySQL
  • générer rapidement des scripts SQL ou XML

Voila ou le télécharger : DBDesigner.

D’après ce post sur dbnewz.com MySQL WorkBench serait le successeur de ce logiciel…

Cet article m’a juste permis de  faire un petit récapitulatif des  différents logiciels de modélisation dont j’avais entendu parler pendant mes stages…

En connaitriez vous d’autres?

openday : Ingres

Mardi 24 juin 2008

Hier soir il y avait une conférence BI concernant INGRES. Voici mon petit compte rendu…

pinguin_ingres.JPG

Petit historique :

La création de la Base de données Ingres a été créée en 1970. Ce n’est qu’en 2006 qu’ils ont déclaré leur présence au sein de l’open source afin de favoriser l’innovation et pour redonner un coup de jeune à leur offre. En 2007 est né Appliance : une solution clef en main que j’ai présenté dans un autre post ( OS : Linux, ETL : Talend Report : Jaspersoft)

Leur communauté :

Cette communauté insiste sur le fait qu’elle est francophone et donc que tous les forums, documents, assistances sont en français.

Plusieurs projets communautaires sont en cours de création. D’ailleurs si ça intéresse quelqu’un il recherche des gens pour participer à tout ce travail de communauté.

Résumé technique :

Cette conférence était très théorique. Ils ont beaucoup insister sur les concepts de base de la BI ainsi que sur les particularités de leur base de données Ingres :

  • optimisation de requêtes
  • support des hash join
  • Architecture multithreads : Requêtes parallèles, Optimisation des I/O, Optimisation des indexations
  • Fonctionnalité de bulkloading puissant
  • grands choix de connectivité pour les ETL
  • Supporte une forte volumétrie ( voir le post sur Ingres qui entre le livre des records)

J’attends les prochaines conférences et j’espère qu’elles seront plus orientées BI.

Sympa sinon l’ambiance de la conférence à la Cantine! (151 rue de Montmartre Paris 2e)

En tout cas ce qu’il en est ressorti c’est que sur le marché OSBI les solutions qui marchent sont : SpagoBI, Jaspersoft et Ingres ! Et oui pentaho n’a pas de succès…

Pour aller plus loin :

Si vous voulez tester cette solution pendant 60 jours :
ingres.com/downloads

Pour plus de renseignements sur le sujet :
ingres-ua.fr
iicomfr.org