En analysant les statistiques du site, nous obtenons une vue d'ensemble de ce qui se passe. Nous mettons les résultats en relation avec d'autres connaissances sur le produit ou le service, améliorant ainsi notre expérience.
Lorsque l'analyse des premiers résultats est terminée, que l'on a réfléchi à l'information et tiré des conclusions, la prochaine étape commence. Des idées émergent : que se passerait-il si l'on regardait les données sous un autre angle ?
à ce stade, il y a des limitations aux outils d'analyse. C'est l'une des raisons pour lesquelles l'outil Google Analytics ne m'a pas suffi, notamment en raison de sa capacité limitée à visualiser et manipuler mes données.
J'ai toujours voulu charger rapidement les données de base, ajouter un autre niveau d'agrégation ou interpréter différemment les valeurs existantes.
C'est facile à faire dans basé sur le fichier access.log et il suffit d'utiliser le langage SQL.
Alors, à quelles questions voulais-je trouver des réponses ?
Qu'est-ce qui a changé sur le site et quand ?
L'historique des modifications des données de base est toujours intéressant.

RequĂȘte SQL de rapport
SELECT
1 as 'SideStackedBar: Mises Ă jour de contenu par mois',
strftime('%m/%Y', datetime(UPDATE_DT, 'unixepoch')) AS 'Jour',
COUNT(CASE WHEN PAGE_TITLE != 'n.a.' THEN DIM_REQUEST_ID END) AS 'Mises Ă jour de pages web',
COUNT(CASE WHEN PAGE_DESCR = 'IMAGES' THEN DIM_REQUEST_ID END) AS 'Téléchargements d'images',
COUNT(CASE WHEN PAGE_DESCR = 'VIDEO' THEN DIM_REQUEST_ID END) AS 'Téléchargements de vidéos',
COUNT(CASE WHEN PAGE_DESCR = 'AUDIO' THEN DIM_REQUEST_ID END) AS 'Téléchargements audio'
FROM DIM_REQUEST
WHERE PAGE_TITLE != 'n.a.' OR PAGE_DESCR != 'n.a.'
GROUP BY strftime('%m/%Y', datetime(UPDATE_DT, 'unixepoch'))
ORDER BY UPDATE_DTPar exemple, à un moment donné, une optimisation du référencement a été réalisée ou un nouveau contenu a été ajouté au site, entraßnant une augmentation prévue du trafic.
Groupes d'utilisateurs
Le plus simple exemple de groupe peut ĂȘtre un agent utilisateur ou le nom du systĂšme d'exploitation.
La mesure des agents utilisateurs a accumulé environ mille enregistrements, et j'étais curieux de voir la dynamique de la répartition des agents dans le groupe.

RequĂȘte SQL de rapport
SELECT
1 AS 'SideStackedBar: Agents utilisateurs',
AGENT_OS AS 'OS',
SUM(CASE WHEN AGENT_BOT = 'n.a.' THEN 1 ELSE 0 END) AS 'Agent utilisateur des utilisateurs',
SUM(CASE WHEN AGENT_BOT != 'n.a.' THEN 1 ELSE 0 END) AS 'Agent utilisateur des bots'
FROM DIM_USER_AGENT
WHERE DIM_USER_AGENT_ID != -1
GROUP BY AGENT_OS
ORDER BY 3 DESCLa plupart des différentes combinaisons d'agents proviennent du monde Windows. Parmi les indéfinis, se trouvent des éléments tels que WhatsApp, PocketImageCache, PlayStation, SmartTV, etc.
Activité des groupes d'utilisateurs par semaine
En regroupant certains groupes, on peut observer la répartition de leur activité.
Par exemple, les utilisateurs du cluster Linux consomment plus de trafic sur le site que tous les autres.

RequĂȘte SQL de rapport
SELECT
1 AS 'StackedBar: Volume de Trafic par SystĂšme d'Exploitation Utilisateur et par Semaine',
strftime('%W semaine', datetime(FCT.EVENT_DT, 'unixepoch')) AS 'Semaine',
SUM(CASE WHEN USG.AGENT_OS IN ('Android', 'Linux') THEN FCT.BYTES ELSE 0 END) / 1000 AS 'Utilisateurs Android/Linux',
SUM(CASE WHEN USG.AGENT_OS IN ('Windows') THEN FCT.BYTES ELSE 0 END) / 1000 AS 'Utilisateurs Windows',
SUM(CASE WHEN USG.AGENT_OS IN ('Macintosh', 'iOS') THEN FCT.BYTES ELSE 0 END) / 1000 AS 'Utilisateurs Mac/iOS',
SUM(CASE WHEN USG.AGENT_OS IN ('n.a.', 'BlackBerry') THEN FCT.BYTES ELSE 0 END) / 1000 AS 'Autre'
FROM
FCT_ACCESS_USER_AGENT_DD FCT,
DIM_USER_AGENT USG,
DIM_HTTP_STATUS HST
WHERE FCT.DIM_USER_AGENT_ID = USG.DIM_USER_AGENT_ID
AND FCT.DIM_HTTP_STATUS_ID = HST.DIM_HTTP_STATUS_ID
AND USG.AGENT_BOT = 'n.a.' /* utilisateurs seulement */
AND HST.STATUS_GROUP IN ('Successful') /* bonnes pages */
AND datetime(FCT.EVENT_DT, 'unixepoch') > date('now', '-3 month')
GROUP BY strftime('%W semaine', datetime(FCT.EVENT_DT, 'unixepoch'))
ORDER BY FCT.EVENT_DTConsommation intensive de trafic
Le tableau montre les groupes d'utilisateurs les plus actifs et le jour de leur activité.
Les plus actifs appartiennent au cluster Linux.

RequĂȘte SQL de rapport
SELECT
1 AS 'Table: Agent Utilisateur avec Forte Utilisation',
strftime('%d.%m.%Y', datetime(FCT.EVENT_DT, 'unixepoch')) AS 'Jour',
ROUND(1.0 * SUM(FCT.BYTES) / 1000000, 1) AS 'Trafic MB',
ROUND(1.0 * SUM(FCT.IP_CNT) / SUM(1), 1) AS 'IPs',
ROUND(1.0 * SUM(FCT.REQUEST_CNT) / SUM(1), 1) AS 'Demandes',
USA.DIM_USER_AGENT_ID AS 'ID',
MAX(USA.USER_AGENT_NK) AS 'Agent Utilisateur',
MAX(USA.AGENT_BOT) AS 'Bot'
FROM
FCT_ACCESS_USER_AGENT_DD FCT,
DIM_USER_AGENT USA
WHERE FCT.DIM_USER_AGENT_ID = USA.DIM_USER_AGENT_ID
AND datetime(FCT.EVENT_DT, 'unixepoch') >= date('now', '-30 day')
GROUP BY USA.DIM_USER_AGENT_ID, strftime('%d.%m.%Y', datetime(FCT.EVENT_DT, 'unixepoch'))
ORDER BY SUM(FCT.BYTES) DESC, FCT.EVENT_DT
LIMIT 10En utilisant les attributs jour et ID d'agent, il est possible de trouver et de suivre rapidement les statistiques par jour pour des groupes d'utilisateurs spĂ©cifiques. Si nĂ©cessaire, des informations dĂ©taillĂ©es peuvent ĂȘtre rapidement trouvĂ©es dans la table de stage.
Comment obtenir des informations ?
peuvent ĂȘtre rendues encore plus efficaces en intĂ©grant des sources de donnĂ©es supplĂ©mentaires, en introduisant de nouveaux niveaux d'agrĂ©gation et de regroupement.
Données et entités de base
Les donnĂ©es de base incluent des informations sur les entitĂ©s : pages web, images, contenus vidĂ©o et audio, et pour un magasin â produits.
Ces entités servent de dimensions, et le processus de conservation des modifications des attributs est appelé historisation. Dans une base de données, ce processus est souvent réalisé sous forme de dimensions à changement lent (SCD).
Les sources de données de base peuvent provenir de divers systÚmes, il est donc presque toujours nécessaire de les intégrer.
Dimension Ă changement lent
La dimension DIM_REQUEST contiendra des informations sur les requĂȘtes sur le site sous forme historique.
Table SCD2
CRĂER UNE TABLE DIM_REQUEST (
DIM_REQUEST_ID INTEGER NON NULL CLĂ PRINCIPALE AUTOINCREMENT,
DIM_REQUEST_ID_HIST INTEGER NON NULL DEFAULT -1,
REQUEST_NK TEXTE NON NULL DEFAULT 'n.a.',
PAGE_TITLE TEXTE NON NULL DEFAULT 'n.a.',
PAGE_DESCR TEXTE NON NULL DEFAULT 'n.a.',
PAGE_KEYWORDS TEXTE NON NULL DEFAULT 'n.a.',
DELETE_FLAG INTEGER NON NULL DEFAULT 0,
UPDATE_DT INTEGER NON NULL DEFAULT 0,
UNIQUE (REQUEST_NK, DIM_REQUEST_ID_HIST)
);
INSERT INTO DIM_REQUEST (DIM_REQUEST_ID) VALUES (-1);En plus de cela, nous allons crĂ©er une vue qui affichera toujours tous les enregistrements dans leur dernier Ă©tat. Cela est nĂ©cessaire pour charger la mesure elle-mĂȘme.

Vue actuelle SCD2
/* Content: actual view on scd table */
SELECT HI.DIM_REQUEST_ID,
HI.DIM_REQUEST_ID_HIST,
HI.REQUEST_NK,
HI.PAGE_TITLE,
HI.PAGE_DESCR,
HI.PAGE_KEYWORDS,
NK.CNT AS HIST_CNT,
HI.DELETE_FLAG,
strftime('%d.%m.%Y %H:%M', datetime(HI.UPDATE_DT, 'unixepoch')) AS UPDATE_DT
FROM
( SELECT REQUEST_NK, MAX(DIM_REQUEST_ID) AS DIM_REQUEST_ID, SUM(1) AS CNT
FROM DIM_REQUEST
GROUP BY REQUEST_NK
) NK,
DIM_REQUEST HI
WHERE 1 = 1
AND NK.REQUEST_NK = HI.REQUEST_NK
AND NK.DIM_REQUEST_ID = HI.DIM_REQUEST_ID;Et une vue oĂč pour chaque enregistrement, les informations historiques sont rassemblĂ©es. Cela est nĂ©cessaire pour Ă©tablir une connexion historiquement correcte avec les faits.

Vue historique SCD2
/* Content: actual view on scd table */
SELECT SCD.DIM_REQUEST_ID,
SCD.DIM_REQUEST_ID_HIST,
SCD.REQUEST_NK,
SCD.PAGE_TITLE,
SCD.PAGE_DESCR,
SCD.PAGE_KEYWORDS,
SCD.DELETE_FLAG,
CASE
WHEN HIS.UPDATE_DT IS NULL
THEN 1
ELSE 0 END ACTIVE_FLAG,
SCD.DIM_REQUEST_ID_HIST AS ID_FROM,
SCD.DIM_REQUEST_ID AS ID_TO,
CASE
WHEN SCD.DIM_REQUEST_ID_HIST=-1
THEN 3600
ELSE IFNULL(SCD.UPDATE_DT,3600)
END AS TIME_FROM,
CASE
WHEN HIS.UPDATE_DT IS NULL
THEN 253370764800
ELSE HIS.UPDATE_DT
END AS TIME_TO,
CASE
WHEN SCD.DIM_REQUEST_ID_HIST=-1
THEN STRFTIME('%d.%m.%Y %H:%M', DATETIME(3600, 'unixepoch'))
ELSE STRFTIME('%d.%m.%Y %H:%M', DATETIME(IFNULL(SCD.UPDATE_DT,3600), 'unixepoch'))
END AS ACTIVE_FROM,
CASE
WHEN HIS.UPDATE_DT IS NULL
THEN STRFTIME('%d.%m.%Y %H:%M', DATETIME(253370764800, 'unixepoch'))
ELSE STRFTIME('%d.%m.%Y %H:%M', DATETIME(HIS.UPDATE_DT, 'unixepoch'))
END AS ACTIVE_TO
FROM
DIM_REQUEST SCD
LEFT OUTER JOIN DIM_REQUEST HIS
ON SCD.REQUEST_NK = HIS.REQUEST_NK AND SCD.DIM_REQUEST_ID = HIS.DIM_REQUEST_ID_HIST;Agrégation des données
La compression (agrégation) permet d'évaluer les données à un niveau plus élevé et de détecter des anomalies et des tendances qui ne sont pas visibles dans les rapports détaillés.
Par exemple, dans la mesure avec les codes d'Ă©tat des requĂȘtes DIM_HTTP_STATUS, nous ajouterons un groupe :
ĂTAT / GROUPE
0xx / n.a.
1xx / Informatif
2xx / Réussi
3xx / Redirection
4xx / Erreur du client
5xx / Erreur du serveur
La mesure des agents utilisateur DIM_USER_AGENT contiendra les attributs AGENT_OS et AGENT_BOT, responsables des groupes. Ils peuvent ĂȘtre remplis lors du processus ETL :
Chargement de DIM_USER_AGENT
/* Propagate the user agent from access log */
INSERT INTO DIM_USER_AGENT (USER_AGENT_NK, AGENT_OS, AGENT_ENGINE, AGENT_DEVICE, AGENT_BOT, UPDATE_DT)
WITH CLS AS (
SELECT BROWSER
FROM STG_ACCESS_LOG WHERE LENGTH(BROWSER)>1
GROUP BY BROWSER
)
SELECT
CLS.BROWSER AS USER_AGENT_NK,
CASE
WHEN INSTR(CLS.BROWSER,'Macintosh')>0
THEN 'Macintosh'
WHEN INSTR(CLS.BROWSER,'iPhone')>0
OR INSTR(CLS.BROWSER,'iPad')>0
OR INSTR(CLS.BROWSER,'iPod')>0
OR INSTR(CLS.BROWSER,'Apple TV')>0
OR INSTR(CLS.BROWSER,'Darwin')>0
THEN 'iOS'
WHEN INSTR(CLS.BROWSER,'Android')>0
THEN 'Android'
WHEN INSTR(CLS.BROWSER,'X11;')>0 OR INSTR(CLS.BROWSER,'Wayland;')>0 OR INSTR(CLS.BROWSER,'linux-gnu')>0
THEN 'Linux'
WHEN INSTR(CLS.BROWSER,'BB10;')>0 OR INSTR(CLS.BROWSER,'BlackBerry')>0
THEN 'BlackBerry'
WHEN INSTR(CLS.BROWSER,'Windows')>0
THEN 'Windows'
ELSE 'n.a.' END AS AGENT_OS, -- OS
CASE
WHEN INSTR(CLS.BROWSER,'AppleCoreMedia')>0
THEN 'AppleWebKit'
WHEN INSTR(CLS.BROWSER,') ')>1 AND LENGTH(CLS.BROWSER)>INSTR(CLS.BROWSER,') ')
THEN COALESCE(SUBSTR(CLS.BROWSER, INSTR(CLS.BROWSER,') ')+2, LENGTH(CLS.BROWSER) - INSTR(CLS.BROWSER,') ')-1), 'N/A')
ELSE 'n.a.' END AS AGENT_ENGINE, -- Engine
CASE
WHEN INSTR(CLS.BROWSER,'iPhone')>0
THEN 'iPhone'
WHEN INSTR(CLS.BROWSER,'iPad')>0
THEN 'iPad'
WHEN INSTR(CLS.BROWSER,'iPod')>0
THEN 'iPod'
WHEN INSTR(CLS.BROWSER,'Apple TV')>0
THEN 'Apple TV'
WHEN INSTR(CLS.BROWSER,'Android ')>0 AND INSTR(CLS.BROWSER,'Build')>0
THEN COALESCE(SUBSTR(CLS.BROWSER, INSTR(CLS.BROWSER,'Android '), INSTR(CLS.BROWSER,'Build')-INSTR(CLS.BROWSER,'Android ')), 'n.a.')
WHEN INSTR(CLS.BROWSER,'Android ')>0 AND INSTR(CLS.BROWSER,'MIUI')>0
THEN COALESCE(SUBSTR(CLS.BROWSER, INSTR(CLS.BROWSER,'Android '), INSTR(CLS.BROWSER,'MIUI')-INSTR(CLS.BROWSER,'Android ')), 'n.a.')
ELSE 'n.a.' END AS AGENT_DEVICE, -- Device
CASE
WHEN INSTR(LOWER(CLS.BROWSER),'yandex.com')>0
THEN 'yandex'
WHEN INSTR(LOWER(CLS.BROWSER),'googlebot')>0
THEN 'google'
WHEN INSTR(LOWER(CLS.BROWSER),'bingbot')>0
THEN 'microsoft'
WHEN INSTR(LOWER(CLS.BROWSER),'ahrefsbot')>0
THEN 'ahrefs'
WHEN INSTR(LOWER(CLS.BROWSER),'jobboersebot')>0 OR INSTR(LOWER(CLS.BROWSER),'jobkicks')>0
THEN 'job.de'
WHEN INSTR(LOWER(CLS.BROWSER),'mail.ru')>0
THEN 'mail.ru'
WHEN INSTR(LOWER(CLS.BROWSER),'baiduspider')>0
THEN 'baidu'
WHEN INSTR(LOWER(CLS.BROWSER),'mj12bot')>0
THEN 'majestic-12'
WHEN INSTR(LOWER(CLS.BROWSER),'duckduckgo')>0
THEN 'duckduckgo'
WHEN INSTR(LOWER(CLS.BROWSER),'bytespider')>0
THEN 'bytespider'
WHEN INSTR(LOWER(CLS.BROWSER),'360spider')>0
THEN 'so.360.cn'
WHEN INSTR(LOWER(CLS.BROWSER),'compatible')>0 OR INSTR(LOWER(CLS.BROWSER),'http')>0
OR INSTR(LOWER(CLS.BROWSER),'libwww')>0 OR INSTR(LOWER(CLS.BROWSER),'spider')>0
OR INSTR(LOWER(CLS.BROWSER),'java')>0 OR INSTR(LOWER(CLS.BROWSER),'python')>0
OR INSTR(LOWER(CLS.BROWSER),'robot')>0 OR INSTR(LOWER(CLS.BROWSER),'curl')>0 OR INSTR(LOWER(CLS.BROWSER),'wget')>0
THEN 'other'
ELSE 'n.a.' END AS AGENT_BOT, -- Bot
STRFTIME('%s','now') AS UPDATE_DT
FROM CLS
LEFT OUTER JOIN DIM_USER_AGENT TRG
ON CLS.BROWSER = TRG.USER_AGENT_NK
WHERE TRG.DIM_USER_AGENT_ID IS NULLIntégration des données
Inclut l'organisation du transfert de données du systÚme d'exploitation au rapport. Pour cela, il est nécessaire de créer une table d'étape avec une structure similaire à celle de la source.
Les informations sur les pages Web atteignent la table d'Ă©tape Ă partir de la sauvegarde de la CMS sous forme de requĂȘtes d'insertion.
Le chargement de la table historique DIM_REQUEST avec les données de base se déroule en trois étapes : chargement des nouvelles clés et attributs, mise à jour des existants et enregistrement des enregistrements supprimés.
Chargement des nouveaux enregistrements SCD2
/* Load request table SCD from master data */
INSERT INTO DIM_REQUEST (DIM_REQUEST_ID_HIST, REQUEST_NK, PAGE_TITLE, PAGE_DESCR, PAGE_KEYWORDS, DELETE_FLAG, UPDATE_DT)
WITH CLS AS ( -- prepare keys
SELECT
'/' || NAME AS REQUEST_NK,
TITLE AS PAGE_TITLE,
CASE WHEN DESCRIPTION = '' OR DESCRIPTION IS NULL
THEN 'n.a.' ELSE DESCRIPTION
END AS PAGE_DESCR,
CASE WHEN KEYWORDS = '' OR KEYWORDS IS NULL
THEN 'n.a.' ELSE KEYWORDS
END AS PAGE_KEYWORDS
FROM STG_CMS_MENU
WHERE CONTENT_TYPE != 'folder' -- only web pages
AND PAGE_TITLE != 'n.a.' -- master data which make sense
)
/* new records from stage: CLS */
SELECT
-1 AS DIM_REQUEST_ID_HIST,
CLS.REQUEST_NK,
CLS.PAGE_TITLE,
CLS.PAGE_DESCR,
CLS.PAGE_KEYWORDS,
0 AS DELETE_FLAG,
STRFTIME('%s','now') AS UPDATE_DT
FROM CLS
LEFT OUTER JOIN
(
SELECT
DIM_REQUEST_ID,
REQUEST_NK,
PAGE_TITLE,
PAGE_DESCR,
PAGE_KEYWORDS
FROM DIM_REQUEST_V_ACT
) TRG ON CLS.REQUEST_NK = TRG.REQUEST_NK
WHERE TRG.REQUEST_NK IS NULL -- no such record in data martMise Ă jour des attributs SCD2
/* Load request table SCD from master data */
INSERT INTO DIM_REQUEST (DIM_REQUEST_ID_HIST, REQUEST_NK, PAGE_TITLE, PAGE_DESCR, PAGE_KEYWORDS, DELETE_FLAG, UPDATE_DT)
WITH CLS AS ( -- prepare keys
SELECT
'/' || NAME AS REQUEST_NK,
TITLE AS PAGE_TITLE,
CASE WHEN DESCRIPTION = '' OR DESCRIPTION IS NULL
THEN 'n.a.' ELSE DESCRIPTION
END AS PAGE_DESCR,
CASE WHEN KEYWORDS = '' OR KEYWORDS IS NULL
THEN 'n.a.' ELSE KEYWORDS
END AS PAGE_KEYWORDS
FROM STG_CMS_MENU
WHERE CONTENT_TYPE != 'folder' -- only web pages
AND PAGE_TITLE != 'n.a.' -- master data which make sense
)
/* updated records from stage: CLS and build reference to history: HIST */
SELECT
HIST.DIM_REQUEST_ID AS DIM_REQUEST_ID_HIST,
HIST.REQUEST_NK,
CLS.PAGE_TITLE,
CLS.PAGE_DESCR,
CLS.PAGE_KEYWORDS,
0 AS DELETE_FLAG,
STRFTIME('%s','now') AS UPDATE_DT
FROM CLS,
DIM_REQUEST_V_ACT TRG,
DIM_REQUEST HIST
WHERE CLS.REQUEST_NK = TRG.REQUEST_NK
AND TRG.DIM_REQUEST_ID = HIST.DIM_REQUEST_ID
AND ( CLS.PAGE_TITLE != HIST.PAGE_TITLE /* changes only */
OR CLS.PAGE_DESCR != HIST.PAGE_DESCR
OR CLS.PAGE_KEYWORDS != HIST.PAGE_KEYWORDS )Enregistrements supprimés SCD2
/* Load request table SCD from master data */
INSERT INTO DIM_REQUEST (DIM_REQUEST_ID_HIST, REQUEST_NK, PAGE_TITLE, PAGE_DESCR, PAGE_KEYWORDS, DELETE_FLAG, UPDATE_DT)
WITH CLS AS ( -- prepare keys
SELECT
'/' || NAME AS REQUEST_NK,
TITLE AS PAGE_TITLE
FROM STG_CMS_MENU
WHERE CONTENT_TYPE != 'folder' -- only web pages
AND PAGE_TITLE != 'n.a.' -- master data which make sense
)
/* deleted records in data mart: TRG */
SELECT
TRG.DIM_REQUEST_ID AS DIM_REQUEST_ID_HIST,
TRG.REQUEST_NK,
TRG.PAGE_TITLE,
TRG.PAGE_DESCR,
TRG.PAGE_KEYWORDS,
1 AS DELETE_FLAG,
STRFTIME('%s','now') AS UPDATE_DT
FROM (
SELECT
DIM_REQUEST_ID,
REQUEST_NK,
PAGE_TITLE,
PAGE_DESCR,
PAGE_KEYWORDS
FROM DIM_REQUEST_V_ACT
WHERE PAGE_TITLE != 'n.a.' -- track master data only
AND DELETE_FLAG = 0 -- not already deleted
) TRG
LEFT OUTER JOIN CLS ON TRG.REQUEST_NK = CLS.REQUEST_NK
WHERE CLS.REQUEST_NK IS NULL -- no such record in stageChaque source de donnĂ©es doit ĂȘtre accompagnĂ©e d'une description formelle, par exemple, dans un fichier readme.txt :
Destinataire des données formellement/techniquement : nom, adresse électronique
Fournisseur de données formellement/techniquement : nom, adresse électronique
Source des données : chemin d'accÚs au fichier, noms des services
Informations sur l'accÚs aux données : utilisateurs et mots de passe
Le schéma de circulation des données aidera dans le processus de maintenance et de mise à jour, par exemple, sous forme textuelle :
Déplacement de fichier. Source : ftp.domain.net: /logs/access.log Cible : /var/www/access.log
Lecture dans l'étape. Cible : STG_ACCESS_LOG
Chargement et transformation. Objectif : FCT_ACCESS_REQUEST_REF_HH
Chargement et transformation. Objectif : FCT_ACCESS_USER_AGENT_DD
Rapport. Objectif : /var/www/report.html
Sortie
Ainsi, l'article décrit des mécanismes tels que l'intégration de bases de données et l'introduction de nouveaux niveaux d'agrégation. Ils sont nécessaires lors de la construction d'entrepÎts de données en vue d'obtenir des connaissances supplémentaires et d'améliorer la qualité des informations.
Source : habr.com
