Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ΣΥΣΤΗΜΑΤΑ ΔΙΑΧΕΙΡΙΣΗΣ ΒΑΣΕΩΝ ΔΕΔΟΜΕΝΩΝ - Π20201, Π20195, Π20174 #210

Open
wants to merge 8 commits into
base: master
Choose a base branch
from

Conversation

marfotop
Copy link

Documentation εργασίας:
miniDB.pdf

Μέλη Ομάδας:
Μαριάμ Φωτοπούλου - Π20201
Ελένη Αλεξάνδρα Τσιωτάκη - Π20195
Ελένη Σίμου - Π20174

ΘΕΜΑ 1:

a)NOT and BETWEEN operators:

Για την υλοποίηση του NOT operator προσθέσαμε την εξής συνθήκη στο αρχείο misc.py:
image
Εάν υπάρχει το not στο condition, αυτό που γίνεται είναι να αφαιρεθεί από τη συνθήκη, και στη συνέχεια γίνεται αντιστροφή της συνθήκης μέσω της παρακάτω συνάρτησης not_op():
image
Ακολουθεί screenshot εκτέλεσης query με not operator:
image
image

Για την υλοποίηση του BETWEEN operator, έγινε η εξής προσθήκη στο αρχείο misc.py:
image
Εάν υπάρχει το between στο condition, γίνεται split και παίρνουμε το όνομα της στήλης πάνω στην οποία υπάρχει η συνθήκη. Στη συνέχεια, υπάρχει η εξής τροποποίηση κώδικα στο αρχείο table.py:
image
Σύμφωνα με τα παραπάνω, εάν υπάρχει το between στη συνθήκη, αυτό που γίνεται είναι να την χωρίζουμε σε δύο υποσυνθήκες, και να κάνουμε έπειτα ξεχωριστούς ελέγχους με την _parse_condition().
Ακολουθεί screenshot εκτέλεσης query με between operator:
image

(b)AND and OR operators:

Για την υλοποίηση του AND operator προσθέσαμε στη συνάρτηση _select_where() του αρχείου table.py τον εξής κώδικα, ο οποίος κάνει split τη συνθήκη με βάση το “and” και τη διασπάει σε 2 υποσυνθήκες, τις οποίες χειρίζεται μετά ξεχωριστά σαν κανονικές συνθήκες, χρησιμοποιώντας την _parse_condition(). Τέλος συνδέει τις δύο συνθήκες αναδεικνύοντας τα «κοινά» τους, μέσω της συνάρτησης intersect:
image
Έγινε επίσης η εξής προσθήκη στη συνάρτηση select του αρχείου database.py:
image
Ακολουθούν screenshots εκτέλεσης query με τη χρήση του and operator:

image
image
image
image

Για την υλοποίηση του or operator ακολουθήσαμε λογική παρόμοια με αυτή του and. Προσθέσαμε στη συνάρτηση _select_where() του αρχείου table.py τον εξής κώδικα, ο οποίος κάνει split τη συνθήκη με βάση το “or” και τη διασπάει σε 2 υποσυνθήκες, τις οποίες χειρίζεται μετά ξεχωριστά σαν κανονικές συνθήκες, χρησιμοποιώντας την _parse_condition(). Αντίστοιχα με το “and” συνδέονται οι δύο συνθήκες αυτή τη φορά μέσω της συνάρτησης union, και όχι της intersect γιατί πρέπει να αναδειχθεί η ένωση των δύο συνθηκών, και όχι τα κοινά τους:
image
Παράλληλα, έγινε η προσθήκη που αναφέρουμε πιο πάνω στη συνάρτηση select του αρχείου database.py.
Ακολουθούν screenshots εκτέλεσης query με τη χρήση του or operator:

image
image
image

ΘΕΜΑ 2

Πριν προχωρήσουμε στην υλοποίηση των BTREE και HASH indexes, έπρεπε να προσθέσουμε τη λειτουργία του UNIQUE constraint.
Συγκεκριμένα, στη συνάρτηση create_table() του αρχείου database.py έγινε η προσθήκη του unique_cols ορίσματος, που αντιπροσωπεύει τις στήλες που θα οριστούν ως unique. Η ίδια προσθήκη έγινε και στη συνάρτηση init() του αρχείου table.py, ενώ στο ίδιο αρχείο προστέθηκε και ο εξής κώδικας:
image
Στον παραπάνω κώδικα ελέγχουμε εάν η στήλη έχει το unique constraint και αν ταυτόχρονα η τιμή που προσπαθούμε να εισάγουμε στο πεδίο υπάρχει ήδη στον πίνακα. Εάν συμβαίνει κάτι τέτοιο, εμφανίζεται το κατάλληλο μήνυμα και η εισαγωγή αποτυγχάνει. Έπρεπε, επίσης, να προσθέσουμε άλλον έναν έλεγχο για να εξασφαλίσουμε ότι η στήλη πάνω στην οποία γίνεται ο έλεγχος δεν αφορά metadata.
Έγινε επίσης η εξής τροποποίηση όσον αφορά τον meta_indexes πίνακα, γι΄αυτό και απαιτήθηκε στη συνέχεια η κατασκευή καινούργιας βάσης test2:
image
Ακολουθεί screenshot δημιουργίας πίνακα με UNIQUE constraint και προσπάθειας εισαγωγής διπλοτύπου στη unique column:
image

(a)BTREE INDEX:

Αρχικά, προσθέσαμε στη συνάρτηση interpret(query) του αρχείου mdb.py το κλειδί ‘create index’ στο λεξικό kw_per_action, ώστε να αναγνωρίζεται το query δημιουργίας ευρετηρίου. Στο ίδιο αρχείο, στη συνάρτηση create_query_plan() προστέθηκε ο εξής κώδικας, όπου προσθέτουμε στο κατάλληλο λεξικό το όνομα του πίνακα πάνω στον οποίο δημιουργείται index, τη στήλη και τον τύπο του ευρετηρίου που χρησιμοποιήσαμε:
image
Στο αρχείο database.py στη συνάρτηση create_index() προσθέσαμε το όρισμα column_name, που αφορά τη στήλη πάνω στην οποία θέλουμε να δημιουργήσουμε ευρετήριο. Στη συνέχεια, μέσα στο σώμα της ίδιας συνάρτησης τροποποιήσαμε τον κώδικα έτσι ώστε να ελέγχεται εάν η στήλη έχει unique ή primary key constraint και στη συνέχεια, ανάλογα με τον index_type που δηλώνουμε, δημιουργείται btree ή hash index. Σε αντίθετη περίπτωση, δημιουργείται ένα Exception και δε δημιουργείται ευρετήριο, ή αν δεν υπάρχει unique constraint, δημιουργείται ευρετήριο πάνω στο primary key.
image
Στη συνάρτηση _construct_index() προσθέσαμε τα ορίσματα column_name και index_type, για να προσδιορίσουμε τη στήλη που θα δημιουργήσουμε ευρετήριο και τον τύπο του ευρετηρίου. Στη συνέχεια προσθέσαμε τον εξής κώδικα, ο οποίος ελέγχει εάν η στήλη έχει unique ή primary key, και στη συνέχεια φτιάχνει το ευρετήριο, δημιουργώντας ένα αντικείμενο της κλάσης Btree.
image
Ακολουθεί screenshot δημιουργίας btree index πάνω στη unique στήλη username του πίνακα account που δημιουργήσαμε προηγουμένως.
image

Όσον αφορά στη συνέχεια την τροποποίηση της μεθόδου select, ώστε να χρησιμοποιείται επιλογή μέσω ευρετηρίου, εάν αυτό είναι εφικτό, τροποποιήσαμε την μέθοδο select() του αρχείου database.py, προσθέτοντας τον εξής κώδικα για την επιλογή του select μέσω btree, εάν η στήλη της συνθήκης έχει unique ή primary key constraint.
image
image
Ακολουθούν screenshots αναζήτησης με και χωρίς Btree:
image
image

(b)HASH INDEX:

Δημιουργήσαμε αρχικά τις κλάσεις Hash και Bucket στο αρχείο hash.py για τη δημιουργία hash index χρησιμοποιώντας τον επεκτάσιμο κατακερματισμό με LSB και το modulo % για τη συνάρτηση κατακερματισμού.
Κλάση Hash:
Όταν εισάγεται ένα νέο ζεύγος κλειδιού-τιμής στον πίνακα κατακερματισμού χρησιμοποιώντας τη μέθοδο insert(), η κλάση Hash υπολογίζει πρώτα την τιμή κατακερματισμού για το δοσμένο κλειδί χρησιμοποιώντας τη μέθοδο hash_function(). Η τιμή κατακερματισμού χρησιμοποιείται ως δείκτης για να αποκτηθεί πρόσβαση στο αντίστοιχο κάδο στη λίστα. Εάν ο κάδος είναι άδειος, δημιουργείται μια νέα περίπτωση της κλάσης Bucket στον κάδο. Το ζεύγος κλειδιού-τιμής εισάγεται στον κάδο χρησιμοποιώντας τη μέθοδο insert() της κλάσης Bucket.
Όταν ζητείται ένα κλειδί χρησιμοποιώντας τη μέθοδο select(), η κλάση Hash υπολογίζει την τιμή κατακερματισμού για το κλειδί και τη χρησιμοποιεί ως δείκτη για να αποκτήσει πρόσβαση στον αντίστοιχο κάδο στη λίστα. Εάν ο κάδος δεν είναι άδειος, καλείται η μέθοδος select() της κλάσης Bucket για να ανακτηθεί η τιμή που συσχετίζεται με το κλειδί.
Αντίστοιχα, όταν διαγράφεται ένα κλειδί χρησιμοποιώντας τη μέθοδο delete(), η κλάση Hash υπολογίζει την τιμή κατακερματισμού για το κλειδί και τη χρησιμοποιεί ως δείκτη για να αποκτήσει πρόσβαση στο αντίστοιχο κάδο στη λίστα. Εάν ο κάδος δεν είναι κενός, καλείται η μέθοδος delete() της κλάσης Bucket για την αφαίρεση του ζευγαριού κλειδιού-τιμής από τον κάδο.
Επιπλέον, η μέθοδος show() της κλάσης Hash χρησιμοποιείται για την εμφάνιση των περιεχομένων του πίνακα κατακερματισμού, όπου κάθε μη-κενός κάδος εμφανίζεται ως μια λίστα ζευγαριών κλειδιού-τιμής.
Τέλος, η μέθοδος get() έχει προστεθεί στην κλάση Hash για τη δυνατότητα άμεσης πρόσβασης στις τιμές του πίνακα κατακερματισμού χρησιμοποιώντας έναν δείκτη κλειδιού, όπου ο δείκτης βασίζεται στην τιμή κατακερματισμού του κλειδιού. Η μέθοδος get() χρησιμοποιεί τη μέθοδο get() της κλάσης Bucket για την ανάκτηση της τιμής στο συγκεκριμένο δείκτη.
Κλάση Bucket:
Η κλάση Bucket είναι μια βοηθητική κλάση που χρησιμοποιείται από την κλάση Hash για την αποθήκευση ζευγαριών κλειδιού-τιμής σε ένα κάδο. Η κλάση Bucket διαθέτει τις ακόλουθες μεθόδους:
Η μέθοδος insert() λαμβάνει ένα ζευγάρι κλειδιού-τιμής και το προσθέτει στο τέλος της λίστας αντικειμένων στον κάδο.
Η μέθοδος delete() λαμβάνει ένα κλειδί και αναζητά το ζευγάρι κλειδιού-τιμής με αυτό το κλειδί στη λίστα αντικειμένων. Αν βρεθεί, η μέθοδος αφαιρεί το ζευγάρι κλειδιού-τιμής από τη λίστα και επιστρέφει True. Αν το κλειδί δεν βρεθεί, η μέθοδος επιστρέφει False.
Η μέθοδος select() λαμβάνει ένα κλειδί και αναζητά το ζευγάρι κλειδιού-τιμής με αυτό το κλειδί στη λίστα αντικειμένων. Αν βρεθεί, η μέθοδος επιστρέφει την τιμή που συσχετίζεται με το κλειδί. Αν το κλειδί δεν βρεθεί, επιστρέφεται None.
Η μέθοδος get() παίρνει ένα δείκτη και επιστρέφει την τιμή του ζευγαριού κλειδιού-τιμής σε αυτόν τον δείκτη στη λίστα στοιχείων. Εάν ο δείκτης είναι εκτός ορίων, η μέθοδος επιστρέφει None.
Συνολικά, η κλάση Bucket παρέχει έναν τρόπο στην κλάση Hash για να αποθηκεύσει τα ζευγάρια κλειδιού-τιμής σε ένα κάδο και να εκτελεί αποτελεσματικά λειτουργίες πάνω σε αυτά.
image
image
image
Όσον αφορά τα υπόλοιπα αρχεία, έχουν γίνει αλλαγές παρόμοιες με αυτές που απαιτούνταν για το Btree index.
Στο αρχείο database.py στη συνάρτηση create_index() προσθέσαμε κώδικα αντίστοιχο με αυτόν του btree, για να δημιουργείται hash index σε unique ή primary key, εφόσον έχουμε δηλώσει το index_type να είναι hash:
image
Αντίστοιχες αλλαγές υπάρχουν και στη συνάρτηση _construct_index():
image
Ακολουθεί screenshot δημιουργίας hash ευρετηρίου στο unique πεδίο username του πίνακα account:
image
Όσον αφορά στη συνέχεια την τροποποίηση της μεθόδου select, ώστε να χρησιμοποιείται επιλογή μέσω ευρετηρίου, εάν αυτό είναι εφικτό, τροποποιήσαμε την μέθοδο select() του αρχείου database.py, προσθέτοντας τον εξής κώδικα για την επιλογή του select μέσω hash index, εάν η στήλη της συνθήκης έχει unique ή primary key constraint.
image
Στο αρχείο table.py, τέλος, δημιουργήσαμε τη συνάρτηση _select_where_with_hash(), η οποία έχει παρόμοια υλοποίηση με αυτή του Btree, προκειμένου να υλοποιηθεί η δυνατότητα επιλογής μέσω hash ευρετηρίου. Υπάρχει, ωστόσο, η διαφορά ότι εάν ο operator της συνθήκης δεν είναι “=”. τότε να πραγματοποιείται σειριακή αναζήτηση, καθώς τα ευρετήρια κατακερματισμού δεν υποστηρίζουν ερωτήσεις διαστήματος.
image
image
Ακολουθούν screenshots αναζήτησης με και χωρίς Hash index:
image
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants