Συνεχίζοντας την σειρά των post που αφορούν την υλοποίηση ενός DW για την κάλυψη των αναγκών μιας BI λύσης θα ασχοληθούμε σε αυτό με τον logical design του DW.
Όπως έχω ήδη αναφέρει σε παλαιότερα post ένα DW είναι ο θεμέλιος λίθος καθώς σε αυτό γίνονται τα ερωτήματα που θα δώσουν τις απαντήσεις σε αυτούς που πρέπει να λάβουν αποφάσεις. Έτσι αυτό θα πρέπει σαν Νούμερο Ένα Απαίτηση να είναι έτσι φτιαγμένο ώστε να υποστηρίζει γρήγορο διάβασμα (optimized for data read operations).
Ανάμεσα στις δύο κυρίαρχες μεθοδολογίες για την υλοποίηση ενός DW (Inmon Vs Kimball) πιστεύω ότι η μεθοδολογία του Kimball η οποία ορίζει το dimensional modeling είναι αυτή που, κατά την γνώμη μου πάντα, ταιριάζει.
Η μεθοδολογία του Kimball είναι αυτή που βασίζεται σε star schemas (ενίοτε και snowflake schemas).
Για να φτάσει κάποιος στο ποθητό αποτέλεσμα να έχει δηλαδή στα χέρια του ένα τέτοιο σχήμα θα πρέπει σε συνεργασία με τους ανθρώπους του business να θεμελιώσει τις απαιτήσεις (requirements). Έχοντας αυτές, έχει ήδη το πρόπλασμα καθώς μέσα από αυτές θα μπορεί να ξέρει τι θα μετράει και με ποια κριτήρια. Για παράδειγμα εάν ο πελάτης είναι μια εμπορική εταιρία θα μπορούσε να είχε ζητήσει να βλέπει τις πωλήσεις του ανά πωλητή, προϊόν, περιοχή, πόλη, χώρα, κόστος, πελάτη κλπ. Έχοντας αυτά στα χέρια μας είναι εύκολο στο να γνωρίζουμε τι θα έχω σαν fact και τι σαν dimension tables.
Ας θυμίσουμε όμως λίγα πράγματα για το star schema (η επανάληψη κάνει πάντα καλό όπως οι αρχαίοι πρόγονοι μας σοφά έλεγαν).
Star Schema
Σε ένα star schema έχω έναν fact table (μπορώ να έχω και περισσότερους) που περιέχει τα μετρήσιμα πχ Ποσότητα, Αξία, Κόστος, κλπ. Αυτός είναι συσχετιζόμενος με πίνακες δορυφόρους (dimensional tables) οι οποίοι στην ουσία είναι τα διάφορα ανά που ζητούνται για τα μετρήσιμα. Έτσι αν θα πάρουμε για παράδειγμα το παραπάνω θα μπορούσα εν δυνάμει να έχω τους εξής dimension tables: Πωλητών, Πελατών, Προϊόντων, Χωρών, Περιοχών, Πόλεων.
Ας δούμε λίγο πιο βαθιά τη πιθανή δομή των fact και dimension tables.
Fact Table
Στα facts αποθηκεύονται εγγραφές που περιέχουν τα αριθμητικά μετρήσιμα για κάποιο γεγονός που λαμβάνει χώρα μέσα στην εταιρία πχ Τιμολόγηση Αγαθών/Υπηρεσιών, Σύστημα Παραγγελιών ή κάποιο άλλο.
Το σημαντικότερο σημείο στο οποίο θα πρέπει να δοθεί προσοχή είναι το granularity ή αλλιώς grain της πληροφορίας που θα αποθηκεύεται μέσα σε αυτό. Τι σημαίνει όμως αυτό;
Αν για παράδειγμα θέλουμε να μετρήσουμε τις πωλήσεις της εταιρίας θα πρέπει να διαβάσουμε τα τιμολόγια της. Αν από τις απαιτήσεις που έχουν ορισθεί το αφεντικό θέλει να μπορεί να δει της πωλήσεις ανά πελάτη, πωλητή και πόλη θα μπορούσαμε εύκολα να καταλήξουμε στην μορφή του πίνακα fact. Σαν πρώτο βήμα λοιπόν θα ήταν να πούμε ότι συγκεκριμένος πίνακας θα περιέχει την Καθαρή Αξία του τιμολογίου και την Αξία του ΦΠΑ (φυσικά θα μπορούσα να έχω και άλλα πεδία αλλά για την απλότητα του παραδείγματος θα κρατήσω μόνο αυτά τα δύο) σαν μετρήσιμα. Όμως για μπορέσω να εξάγω τις πληροφορίες που το αφεντικό θέλει θα πρέπει σε κάθε record (γιατί κάθε εγγραφή αναφέρεται σε ένα τιμολόγιο) να προσθέσω και τον κωδικό του πελάτη την ημερομηνία του τιμολογίου. Αυτό σημαίνει ότι το επίπεδο grain που έχω αυτή την στιγμή είναι το τιμολόγιο. Αν το αφεντικό όμως αποφασίσει ότι θέλει να δει τι πωλήσεις ανά Προϊόν ανά Πελάτη ή ανά Πόλη τότε το granularity το οποίο έχω αυτή την στιγμή δεν με εξυπηρετεί όπως εύκολα γίνεται κατανοητό καθώς δεν μπορεί να γίνουν οι υπολογισμοί σε επίπεδο προϊόντος.
Από αυτό καταλαβαίνουμε ότι είναι σχεδόν σίγουρο ότι μέσα σε μια εταιρία οι ανάγκες για διαφορετικό grain στα fact tables είναι κάτι το οποίο δεν μπορεί να αποφευχθεί. Για το λόγο αυτό μην προσπαθήσετε να φτιάξετε ένα fact table που να προσπαθεί να καλύπτει όλες τις πιθανές εκδοχές. Είναι καλύτερα να έχεις ξεχωριστά για λόγους προφανείς όπως συντήρησης και επίδοσης.
Το ίδιο ισχύει και για τα μετρήσιμα. Προσπαθήστε να ομαδοποιήσετε λογικά αυτά σε ξεχωριστά fact tables.
Ένα ακόμα σημείο το οποίο πρέπει να δοθεί η δέουσα προσοχή είναι τα κλειδιά που πρέπει να υπάρξουν μέσα στον fact table. Το primary key συνήθως είναι composite και περιέχει όλες τις κολώνες/πεδία που είναι foreign keys στους dimension tables. Επίσης σημαντική είναι και η σειρά που θα μπουν αυτά. Καλό είναι να μπαίνουν με την λογική από το γενικότερο προς το ειδικότερο.
Measures
Όσον αφορά τα μετρήσιμα (measures) αυτά όπως έχει ήδη αναφερθεί είναι αυτά τα οποία υπολογίζονται σύμφωνα με τα dimension τα οποία έχουμε. Υπάρχουν τρεις κατηγορίες στις οποίες εντάσσονται τα measures.
1. Additive measures
Είναι όλα όσα μπορούν να υπολογιστούν (sum, agv) σε όλα τα επίπεδα σε όλα τα dimensions πχ πωλήσεις αξία, πωλήσεις ποσότητα
2. Nonadditive measures
Αυτά που δεν μπορούν να υπολογιστούν στα dimensions πχ % κέρδους επί της πώλησης.
3. Semi-additive measures
Αυτά που μπορούν να υπολογιστούν σε κάποια dimensions πχ. Το υπόλοιπο λογαριασμού τράπεζας αυτό μπορεί να υπολογιστεί σε επίπεδο πελάτη. Αν προσπαθήσεις να το υπολογίσεις σε μια διάσταση χρόνου τα αποτελέσματα δεν θα είναι αυτά που θα περίμενες.
Dimensions
Οι πίνακες που περιέχουν τα κριτήρια με τα οποία θέλουμε να δούμε τα μετρήσιμα (ας μου επιτραπεί αυτή η εξομοίωση) είναι τα dimension tables. Μέσα σε αυτούς υπάρχουν τα πεδία (attributes) με τα οποία οι χρήστες ζητάνε να δούνε την πληροφορία. Η επικρατούσα άποψη είναι τα dimension tables να είναι wide. Αυτό σημαίνει ότι περιέχουν μεγάλο αριθμό πεδίων ώστε να καλύψουν τις ανάγκες των χρηστών.
Αν για παράδειγμα πάρουμε το dimension Πελάτης θα μπορούσα να έχω εκτός από τα κλασσικά πεδία όπως το όνομα και την χώρα , πόλη, καθεστώς πελάτη, κλπ. Αυτό που θα πρέπει να γίνει σίγουρα είναι denormalization των δεδομένων. Γιατί εύκολα κάποιος θα μπορούσε να υποθέσει ότι η χώρα θα μπορούσε να ήταν ξεχωριστός πίνακας και να υπάρχει συσχέτιση με τον πίνακα των Πελατών. ΟΧΙ ΟΧΙ ΟΧΙ δεν είμαστε σε OLTP! ΣΚΟΠΟΣ ΜΑΣ ΕΙΝΑΙ ΝΑ ΚΑΝΟΥΜΕ ΕΛΑΧΙΣΤΗ ΧΡΗΣΗ ΤΩΝ JOINS.
Με τα Κeys που υπάρχουν σε αυτούς τι γίνεται;
Το best practice είναι να υπάρχουν για κάθε record δύο κλειδιά. Το business key το οποίο είναι αυτό που έρχεται από τις πηγές μας ατόφιο και το surrogate key το οποίο δημιουργείται μοναδικά στο dimension table και θα είναι και το primary key. Οι λόγοι που μας οδηγούν σε μια τέτοια πρακτική είναι
- Μέσα στα dimension tables μπορεί να ρίχνω records που έρχονται από διαφορετικά συστήματα. Σε αυτή την περίπτωση δεν μπορεί κανείς να εγγυηθεί ότι τα κλειδιά αυτών είναι μοναδικά ή σε συμβατά data types.
- Σε αρκετές περιπτώσεις τα κλειδιά που χρησιμοποιούνται στα OLTP συστήματα μπορεί να είναι complex ή GUID. Αν και μπορούν να χρησιμοποιηθούν καλύτερα είναι να χρησιμοποιηθούν μικρά και απλά data types όπως πχ integers καθώς δίνουν καλύτερο query performance όταν γίνονται joins μεταξύ των fact και dimension tables.
- Επειδή μέσα σε ένα DW πρέπει να έχω την δυνατότητα να κρατήσω ιστορικότητα αλλαγών πχ ένας πωλητής αλλάζει manager για να βγαίνουν σωστά τα αποτελέσματα θα πρέπει να έχω την δυνατότητα να κρατήσω δύο records του συγκεκριμένου πωλητή. Έτσι ενώ το business key δεν έχει αλλάξει θα έχω όμως νέο surrogate key με το οποίο θα μπορώ να κάνω track την ιστορικότητα αυτή αλλά και θα δείχνω και σωστά τα στοιχεία.
Φυσικά δεν θα πρέπει να ξεχνάμε ένα dimension που όλα τα μοντέλα και γενικότερα οι ΒΙ λύσεις έχουν και δεν είναι άλλο από το Time Dimension αλλά αυτό θα αποτελέσει ξεχωριστό post.
Μέχρι το επόμενο post της σειράς αυτής να είστε καλά