Η απόδοση είναι μία από τις πιο σημαντικές πτυχές που πρέπει να λαμβάνονται υπόψη κατά την ανάπτυξη εφαρμογών ιστού. Η ανάλυση του τρόπου άντλησης των δεδομένων από μια βάση δεδομένων είναι ένα καλό σημείο εκκίνησης κατά την αναζήτηση βελτιώσεων. Σε αυτό το άρθρο, θα βρείτε παραδείγματα για το πώς μπορείτε να βελτιώσετε την απόδοση με τη χρήση συγκεντρωτικών συναρτήσεων και το φιλτράρισμα δεδομένων σε επίπεδο βάσης δεδομένων.
Κάποιο πλαίσιο για να ξεκινήσουμε
Αυτό το άρθρο είναι εμπνευσμένο από ένα πραγματικό πρόβλημα που μου είχε ανατεθεί κάποτε. Η αντιμετώπισή του με δίδαξε πολλά, και το έχω ακόμα ως αναφορά στο μυαλό μου. Νομίζω ότι τα παραδείγματα είναι μια καλή πηγή μάθησης, μπορούν να διευκρινίσουν πολλά. Σε αυτό το άρθρο, θα ήθελα να μοιραστώ μαζί σας μερικά παραδείγματα χρήσης των μεθόδων αναζήτησης Active Record.
Προκειμένου να μην εισαγάγω λεπτομέρειες που αφορούν συγκεκριμένο τομέα, θα χρησιμοποιήσω ένα δείγμα εφαρμογής για μια βιβλιοθήκη για να παρουσιάσω παραδείγματα. Όλα είναι αρκετά απλά, όπως φαίνεται στο παρακάτω διάγραμμα. Έχουμε τέσσερις πίνακες: συγγραφείς, βιβλία, χρήστες και ενοικιάσεις. Ένας χρήστης μπορεί να δανειστεί πολλά βιβλία και ένα βιβλίο μπορεί να δανειστεί από πολλούς χρήστες, οπότε χρειαζόμαστε έναν πίνακα σύνδεσης για να μοντελοποιήσουμε τις σχέσεις πολλά προς πολλά. Στην περίπτωσή μας είναι ο πίνακας rentals. Εκεί αποθηκεύουμε επίσης κάποιες πρόσθετες πληροφορίες, οι οποίες είναι οι ημερομηνίες δανεισμού και επιστροφής. Ένας συγγραφέας μπορεί να έχει πολλά βιβλία αντιστοιχισμένα στο όνομά του. Ένα βιβλίο έχει επίσης ένα χαρακτηριστικό που ορίζει το είδος του.
Στατιστικά στοιχεία ανάγνωσης χρηστών
Το καθήκον ήταν να ετοιμάσουμε στατιστικά στοιχεία για έναν μεμονωμένο χρήστη, ώστε να μπορούμε να πούμε πόσα βιβλία από κάθε είδος δανείστηκαν. Η πρώτη μου σκέψη ήταν να αντλήσω όλα τα βιβλία που έχει δανειστεί ο χρήστης, να τα ομαδοποιήσω με βάση το είδος τους και στη συνέχεια να κάνω την αντιστοίχιση, έτσι ώστε σε κάθε είδος να αντιστοιχίζεται ένας αριθμός βιβλίων αντί για μια λίστα. Ακολουθεί αυτό που σκέφτηκα:
Αν και αυτή η προσέγγιση λειτουργεί και φαίνεται καθαρή, δεν χρησιμοποιεί όλες τις δυνατότητες που προσφέρουν οι μέθοδοι αναζήτησης Active Record. Χάρη σε αυτές, είμαστε σε θέση να φιλτράρουμε και να αθροίζουμε δεδομένα σε επίπεδο βάσης δεδομένων χωρίς να χρησιμοποιούμε απευθείας την ακατέργαστη SQL στο κωδικός. Η λειτουργία σε επίπεδο db αυξάνει επίσης την αποδοτικότητά μας.
Στο παραπάνω παράδειγμα, μπορούμε να χρησιμοποιήσουμε τη μέθοδο group αντί της ομάδας της Rubyμε τη μέθοδο. Θα εφαρμόσει την ΟΜΑΔΑBY στο ερώτημα tSQL. Επιπλέον, η μέθοδος αντιστοίχισης και μεγέθους μπορεί να αντικατασταθεί με μια συνάρτηση συνάθροισης αριθμού. Στο τέλος, μας μένει ένα ερώτημα που μοιάζει ως εξής:
Book.joins(:rentals).where(rentals: { user: user }).group(:genre).count(:books)
Φαίνεται ακόμα πιο απλό!
Άλλα χρήσιμα παραδείγματα
Παρακάτω θα βρείτε μερικούς άλλους τρόπους χρήσης των μεθόδων αναζήτησης που θεωρώ ότι αξίζει να γνωρίζετε.
Πρόσκληση για ανενεργούς χρήστες
ΕΡΓΑΣΙΑ: Φιλτράρετε τους χρήστες που δεν έχουν δανειστεί ποτέ ένα βιβλίο ή το έκαναν πριν από περισσότερο από ένα χρόνο.
Θα μπορούσαμε να αντλήσουμε όλους τους χρήστες συμπεριλαμβάνοντας τα σχετικά ενοίκια και στη συνέχεια να τους φιλτράρουμε χρησιμοποιώντας τη μέθοδο select.
User.includes(:rentals).select do |user|
user.rentals.empty? || user.rentals.none? { |rental| rental.start_date >= Date.today - 1.year }
end
Αλλά, φυσικά, δεν είναι ανάγκη να τα μαζέψετε όλα. Χρησιμοποιώντας τις μεθόδους ερωτημάτων, μπορούμε να τα φιλτράρουμε σε επίπεδο db. Αρχικά, ας επιλέξουμε τους χρήστες που έχουν δανειστεί κάποια βιβλία τον τελευταίο χρόνο και στη συνέχεια ας τους αποκλείσουμε από την τελική επιλογή.
ΕΡΓΑΣΙΑ: Βρείτε συγγραφείς με ένα ή μηδέν δανεισμένα βιβλία
Το να το κάνετε με τη μέθοδο select είναι εξαιρετικά απλό, αλλά και πάλι - δεν υπάρχει ανάγκη να λειτουργήσετε σε ένα τόσο μεγάλο σύνολο δεδομένων, καθώς η db μπορεί να το φιλτράρει για εμάς:
Είναι σημαντικό να θυμάστε ένα πράγμα κατά τη χρήση των left_joins (και των outer joins γενικά). Εάν υπάρχουν εγγραφές στον αριστερό πίνακα (εδώ: συγγραφείς) που δεν έχουν αντίστοιχες εγγραφές στον δεξιό πίνακα (εδώ: βιβλία), τότε ως αποτέλεσμα οι στήλες του δεξιού πίνακα θα συμπληρωθούν με μηδενικές τιμές.
Καθώς χρειαζόμαστε επίσης συγγραφείς με ένα βιβλίο που έχει εκχωρηθεί στο σύστημα, υπάρχουν μερικές ακόμη λειτουργίες που πρέπει να γίνουν. Θα πρέπει να κάνουμε την ομαδοποίηση, την καταμέτρηση και την προσθήκη μιας συνθήκης. Ακολουθεί ο τρόπος με τον οποίο θα τα βάλουμε όλα μαζί:
Η συνθήκη έρχεται μετά τη συνάρτηση συνάθροισης, οπότε πρέπει να χρησιμοποιήσουμε τη ρήτρα HAVING αντί της ρήτρας WHERE για να την καθορίσουμε.
Οι μέθοδοι ερωτημάτων Active Record αξίζει να ελεγχθούν όταν σκέφτεστε την απόδοση της εφαρμογής. Μπορούν να απλοποιήσουν τον κώδικά σας και να τον κάνουν να λειτουργεί ταχύτερα. Ελπίζω ότι τα κοινά παραδείγματα θα σας βοηθήσουν να εξερευνήσετε τις δυνατότητες που προσφέρουν οι μέθοδοι ερωτημάτων.