Hive — ελαφριά αποθήκη NoSQL για Flutter που λειτουργεί χωρίς native κώδικα. Σε αντίθεση με το SQLite ή το Firebase, το Hive δεν απαιτεί σύνδεση native βιβλιοθηκών και λειτουργεί αποκλειστικά μέσω Dart. Σύμφωνα με το Pub.dev, 2024, το Hive έχει ληφθεί πάνω από 10 εκατομμύρια φορές και χρησιμοποιείται σε κάθε τρίτο έργο Flutter που απαιτεί τοπική αποθήκευση δεδομένων χωρίς υποδομή διακομιστή.
Κύρια σημεία
Hive — είναι μια βάση δεδομένων NoSQL γραμμένη εξ ολοκλήρου σε Dart που δεν απαιτεί native βιβλιοθήκες. Δημιουργήθηκε από τον Simon Leiter το 2019 ως εναλλακτική λύση για το SQLite σε έργα Flutter. Το Hive αποθηκεύει δεδομένα σε δυαδική μορφή .hive, η οποία είναι βελτιστοποιημένη για γρήγορη ανάγνωση και εγγραφή σε κινητές συσκευές. Η μορφή .hive χρησιμοποιεί ένα προσαρμοσμένο σχήμα σειριοποίησης, όπου κάθε τύπος δεδομένων έχει το δικό του πρόθεμα byte, επιτρέποντας την ανάγνωση του αρχείου χωρίς προηγούμενη γνώση του σχήματος — σε αντίθεση με τα Protocol Buffers ή FlatBuffers.
Η κύρια ιδέα του Hive — μέγιστη απλότητα. Η βάση δεδομένων δεν απαιτεί αρχικοποίηση native μηχανών, δεν περιλαμβάνει αναλυτή SQL και δεν χρησιμοποιεί αντανάκλαση. Όλες οι λειτουργίες είναι άμεσες κλήσεις συναρτήσεων Dart με δυαδική σειριοποίηση μέσω WriteBuffer και ReadBuffer.
Σύμφωνα με έρευνα του Flutter Community (2023), το Hive βρίσκεται στην κορυφαία 5 πιο χρησιμοποιημένων πακέτων για αποθήκευση δεδομένων στο Flutter, δεύτερο μόνο μετά το shared_preferences σε δημοτικότητα, αλλά το ξεπερνά σε λειτουργικότητα και ταχύτητα.
Hive χρησιμοποιεί την έννοια του Box — ανάλογο πίνακα σε σχεσιακές βάσεις δεδομένων. Κάθε Box είναι ένα αρχείο στο δίσκο με ένα σύνολο ζευγών κλειδιού-τιμής. Το κλειδί μπορεί να είναι int ή String, η τιμή — οποιοσδήποτε πρωτόγονος τύπος, λίστα, Map ή προσαρμοσμένο αντικείμενο μέσω TypeAdapter. Τα Box είναι απομονωμένα μεταξύ τους και ανοίγουν ανεξάρτητα.
Hive δεν απαιτεί κανάλια πλατφόρμας (platform channels). Αυτό σημαίνει ότι λειτουργεί το ίδιο σε Android, iOS, Web, macOS, Windows και Linux χωρίς πρόσθετη ρύθμιση. Για έργα που στοχεύουν σε μεταγλώττιση για web, το Hive παραμένει η μόνη ελαφριά λύση NoSQL — το SQLite δεν λειτουργεί στο πρόγραμμα περιήγησης. Ταυτόχρονα, το Hive χρησιμοποιεί το IndexedDB ως backend για το web, εξασφαλίζοντας μονιμότητα δεδομένων και στο περιβάλλον περιηγητή.
Hive σειριοποιεί τα δεδομένα σε δυαδική μορφή κατά την εγγραφή και αποσειριοποιεί κατά την ανάγνωση. Ο εσωτερικός μηχανισμός βασίζεται στα BinaryWriter και BinaryReader, τα οποία συσκευάζουν τα δεδομένα σε συμπαγείς πίνακες byte. Το μέγεθος της αποθήκης στο δίσκο είναι κατά μέσο όρο 2-3 φορές μικρότερο από την αναπαράσταση JSON των ίδιων δεδομένων.
Κατά το άνοιγμα ενός Box, το Hive φορτώνει ολόκληρο το αρχείο στη RAM. Αυτό εξασφαλίζει υψηλή ταχύτητα ανάγνωσης (μικροδευτερόλεπτα), αλλά επιβάλλει περιορισμό στο μέγεθος των δεδομένων: συνιστάται η αποθήκευση όχι περισσότερων από 50-100 MB ανά Box. Για μεγαλύτερους όγκους, χρησιμοποιήστε το LazyBox — τεμπέλικη φόρτωση εγγραφών από το δίσκο.
Hive λειτουργεί μονονηματικά στην απομόνωση του Dart-isolate. Οι εγγραφές εκτελούνται σύγχρονα με κλείδωμα αρχείου. Για ασύγχρονη πρόσβαση, χρησιμοποιήστε το Hive.openBox() με await. Η ταυτόχρονη πρόσβαση από πολλαπλά isolates δεν υποστηρίζεται άμεσα — για αυτό χρειάζεται ξεχωριστός μηχανισμός συγχρονισμού.
Hive καταλαμβάνει μια θέση μεταξύ SharedPreferences και SQLite. Είναι πιο περίπλοκο από το SharedPreferences (υποστηρίζει προσαρμοσμένα αντικείμενα), αλλά πιο απλό από το SQLite (δεν απαιτεί ερωτήματα SQL). Ας συγκρίνουμε τα βασικά χαρακτηριστικά.
| Χαρακτηριστικό | Hive | SharedPreferences | SQLite |
|---|---|---|---|
| Τύποι δεδομένων | Οποιοιδήποτε (μέσω TypeAdapter) | Μόνο πρωτόγονοι | Τύποι SQL |
| Ταχύτητα ανάγνωσης | ~30.000 ops/s | ~5.000 ops/s | ~2.000 ops/s |
| Native κώδικας | Δεν απαιτείται | Απαιτείται (Android) | Απαιτείται |
| Υποστήριξη web | Ναι | Όχι | Όχι |
| Πολυπλοκότητα | Χαμηλή | Ελάχιστη | Μεσαία |
| Αντιδραστικότητα | WatchBox | Όχι | Μέσω ORM |
Hive είναι βέλτιστο για μικρούς όγκους δεδομένων: ρυθμίσεις εφαρμογής, cache αποκρίσεων API, τοπική ουρά συγχρονισμού, αγαπημένα και ιστορικό περιήγησης. Εάν τα δεδομένα δεν υπερβαίνουν τα 50 MB και δεν απαιτούν σχεσιακά ερωτήματα — το Hive είναι ταχύτερο και απλούστερο από το SQLite.
Hive δεν υποστηρίζει ερωτήματα με φιλτράρισμα σε πολλαπλά πεδία, JOIN, συναρτήσεις συνάθροισης. Εάν χρειάζεστε σύνθετα ερωτήματα όπως “επιλογή όλων των εργασιών για σήμερα με προτεραιότητα άνω του 3” — χρησιμοποιήστε SQLite με drift ή floor. Το Hive επίσης δεν είναι κατάλληλο για αποθήκευση πάνω από 100 MB δεδομένων λόγω φόρτωσης στη μνήμη.
Hive ξεκινά με αρχικοποίηση και άνοιγμα ενός Box. Παρακάτω παρουσιάζονται οι βασικές λειτουργίες για ένα τυπικό σενάριο — αποθήκευση λίστας εργασιών σε εφαρμογή Flutter. Όλα τα παραδείγματα λειτουργούν χωρίς native κλήσεις πλατφόρμας.
Πριν χρησιμοποιήσετε το Hive, πρέπει να καλέσετε το Hive.initFlutter() στη main συνάρτηση. Στη συνέχεια, ανοίξτε το Box μέσω Hive.openBox() — το αποτέλεσμα θα είναι ένα στιγμιότυπο Box έτοιμο για ανάγνωση και εγγραφή.
import 'package:hive/hive.dart';
import 'package:hive_flutter/hive_flutter.dart';
void async main() {
await Hive.initFlutter();
final settingsBox = await Hive.openBox('settings');
runApp(MyApp());
}
Box παρέχει μεθόδους put, get, delete και περιέχει έναν επαναλήπτη για περιήγηση σε όλες τις εγγραφές. Τα κλειδιά και οι τιμές τυποποιούνται μέσω generics — από προεπιλογή το Box<dynamic> επιτρέπει οποιουσδήποτε τύπους, αλλά συνιστάται να καθορίζεται συγκεκριμένος τύπος.
// Εγγραφή δεδομένων
final box = await Hive.openBox<String>('tasks');
await box.put('task_1', 'Αγορά προϊόντων');
// Ανάγνωση
final task = box.get('task_1');
// Όλα τα κλειδιά
final allTasks = box.values.toList();
// Διαγραφή
await box.delete('task_1');
// Εκκαθάριση Box
await box.clear();
WatchBox — επέκταση του Box που ειδοποιεί τους συνδρομητές για αλλαγές. Στο Flutter, αυτό ενσωματώνεται με το ValueListenableBuilder: όταν οποιαδήποτε τιμή στο Box αλλάξει, το widget ανακατασκευάζεται αυτόματα χωρίς κλήση setState.
final watchBox = await Hive.openBox('settings');
// Στο widget
ValueListenableBuilder(
valueListenable: watchBox.listenable(),
builder: (context, box, _) {
final counter = box.get('counter') ?? 0;
return Text('Μετρητής: $counter');
},
)
TypeAdapter — ο μηχανισμός του Hive για σειριοποίηση προσαρμοσμένων αντικειμένων Dart. Ο προσαρμογέας περιγράφει πώς να μετατρέψετε ένα αντικείμενο σε δυαδική μορφή (write) και πίσω (read). Σε αντίθεση με το json_serializable, το TypeAdapter δεν απαιτεί αντανάκλαση και λειτουργεί ταχύτερα.
Ο προσαρμογέας υλοποιεί τη διεπαφή TypeAdapter
// Μοντέλο δεδομένων
class Task {
final String title;
final bool isCompleted;
Task({required this.title, this.isCompleted = false});
}
// TypeAdapter
class TaskAdapter extends TypeAdapter<Task> {
@override
final int typeId = 0;
@override
Task read(BinaryReader reader) {
return Task(
title: reader.readString(),
isCompleted: reader.readBool(),
);
}
@override
void write(BinaryWriter writer, Task obj) {
writer.writeString(obj.title);
writer.writeBool(obj.isCompleted);
}
}
Για έργα με μεγάλο αριθμό μοντέλων, το Hive παρέχει hive_generator και build_runner. Ο σχολιασμός @HiveType στην κλάση και @HiveField στα πεδία δημιουργεί αυτόματα τον προσαρμογέα. Αυτό είναι βολικό όταν το μοντέλο περιέχει 10+ πεδία — η χειροκίνητη συγγραφή read/write γίνεται χρονοβόρα.
Hive εκτελεί ανάγνωση από τη μνήμη, όχι από το δίσκο, παρέχοντας ταχύτητα έως 30.000 λειτουργιών ανά δευτερόλεπτο. Για βελτιστοποίηση: ανοίξτε το Box μία φορά και επαναχρησιμοποιήστε το σε όλη την εφαρμογή, μην καλείτε ξανά το openBox. Χρησιμοποιήστε το Hive.box() (σύγχρονο getter) μετά την αρχικοποίηση — επιστρέφει ένα ήδη ανοιχτό Box χωρίς δημιουργία νέου στιγμιότυπου.
Hive ενσωματώνεται εύκολα με δημοφιλείς διαχειριστές κατάστασης Flutter. Για το Provider, χρησιμοποιήστε ChangeNotifierProvider που διαβάζει δεδομένα από το Box κατά την αρχικοποίηση και ενημερώνεται μέσω listenable. Για το Riverpod, είναι κατάλληλο το StreamProvider που είναι εγγεγραμμένο στο WatchBox. Ένας τέτοιος συνδυασμός παρέχει αντιδραστική ενημέρωση του UI σε κάθε αλλαγή δεδομένων στο Hive χωρίς χειροκίνητη κλήση setState. Σε ένα τυπικό έργο Flutter, μια τέτοια αρχιτεκτονική επιτρέπει τον συγχρονισμό κατάστασης μεταξύ οθονών χωρίς καθολικό singleton.
Συχνές Ερωτήσεις
Hive λειτουργεί σε καθαρό Dart, επομένως μπορεί να χρησιμοποιηθεί σε οποιοδήποτε έργο Dart: διακομιστή (Dart VM), κονσόλα ή AngularDart. Για Flutter, συνδέεται επιπλέον το hive_flutter με αρχικοποίηση διαδρομών αποθήκευσης.
Hive υποστηρίζει κρυπτογράφηση AES-256 μέσω της παραμέτρου encryptionKey κατά το άνοιγμα του Box. Το κλειδί πρέπει να είναι μια συμβολοσειρά 32 byte. Το κρυπτογραφημένο Box δεν μπορεί να διαβαστεί χωρίς κλειδί — τα δεδομένα προστατεύονται σε επίπεδο αρχείου.
Isar — ο διάδοχος του Hive από τον ίδιο συγγραφέα (Simon Leiter). Το Isar είναι ταχύτερο, υποστηρίζει ευρετήρια, σχέσεις και σύνθετα ερωτήματα. Ωστόσο, το Hive παραμένει σχετικό για απλά σενάρια όπου δεν χρειάζονται οι σχεσιακές δυνατότητες του Isar και για έργα όπου η ελάχιστη εξάρτηση είναι σημαντική.
Hive δεν έχει ενσωματωμένες μεταναστεύσεις. Εάν η δομή TypeAdapter άλλαξε, τα παλιά δεδομένα δεν θα αποσειριοποιηθούν. Λύση: αυξήστε το typeId του προσαρμογέα και γράψτε χειροκίνητη μετανάστευση στον κώδικα ή χρησιμοποιήστε delete για το παλιό κλειδί πριν γράψετε ένα νέο.
Hive φορτώνει το Box εξ ολοκλήρου στη μνήμη. Το συνιστώμενο όριο είναι 50-100 MB ανά Box. Σε περίπτωση υπέρβασης, είναι πιθανές καθυστερήσεις στο άνοιγμα του Box και αυξημένη κατανάλωση RAM. Για μεγαλύτερους όγκους, χρησιμοποιήστε πολλαπλά Box ή LazyBox με τεμπέλικη φόρτωση.
Σύνοψη
Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση
Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.
Διαβάστε επίσης