Всем привет. Это очередная история нашего регулярного сегмента «тестирование очевидных вещей по вторникам». И в этот раз мое внимание привлекла тема выбора базы данных для локального хранения данных во Flutter-приложении. Эта тема очень заезжена, и о ней написано множество статей, большинство из которых касается лишь практического сравнения трех альтернативных вариантов хранения данных: Hive, SQLite и SharedPreferences.
Я не буду тратить ваше время на описание каждого из них, поскольку, если вы читаете эту статью, вы, вероятно, уже знаете, что это такое. И я буду сравнивать Hive и SQLite только потому, что не могу считать SharedPreferences базой данных (можете кидать в меня лимонами, я уже налил себе текилы🤙).
Итак, как же выглядит среднестатистическая статья о выборе базы данных?
«Здравствуйте. Используйте Hive, не используйте SQLite. До свидания.”
И в подтверждение этому представлена вот такая интересная инфографика:
На самом деле это выглядит грустно, потому что любой, кто хоть раз видел, как устроен настоящий взрослый бэкенд, не будет сравнивать MongoDB и PostgreSQL только по производительности. Серьёзно, зачем вводить в заблуждение наивных новичков, которые хотят делать мобильные приложения?
Конечно, давайте воздержимся от выводов до конца статьи. Вы все увидите сами.
Для начала создадим файл с именем my_class.dart
, в котором опишем тестовый объект для чтения/записи из базы данных. В конце концов, мы хотим протестировать реальное использование, а не только целые числа и строки, как на скриншотах выше, верно ?
import 'package:hive/hive.dart'; class MyClass { int id; String name; MyClass(this.id, this.name); } class MyClassAdapter extends TypeAdapter<MyClass> { @override final typeId = 0; @override MyClass read(BinaryReader reader) { final id = reader.readInt(); final name = reader.readString(); return MyClass(id, name); } @override void write(BinaryWriter writer, MyClass obj) { writer.writeInt(obj.id); writer.writeString(obj.name); } }
Далее, как обычно, создадим файл _test
:
import 'package:flutter/widgets.dart'; import 'package:benchmarking/benchmarking.dart'; import 'package:hive/hive.dart'; import 'package:hive_flutter/hive_flutter.dart'; import 'package:sqflite/sqflite.dart'; import 'dart:math'; import 'package:path_provider/path_provider.dart'; import 'package:sqflite_common_ffi/sqflite_ffi.dart'; import 'my_class.dart'; void main() async { // Initialize Hive WidgetsFlutterBinding.ensureInitialized(); Hive.init('.'); // Register adapter if necessary Hive.registerAdapter(MyClassAdapter()); // Generate test data final testData = List.generate(1000, (index) => MyClass(index, 'test')); // Benchmark SQLite databaseFactory = databaseFactoryFfi; final db = await openDatabase('test.db', version: 1, onCreate: (Database db, int version) async { await db.execute('CREATE TABLE Test (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT)'); }); syncBenchmark('SQLite Insert', () async { for (int i = 0; i < testData.length; i++) { await db.insert('Test', {'id': testData[i].id, 'name': testData[i].name}); } }).report(); syncBenchmark('SQLite Select', () async { await db.rawQuery('SELECT * FROM Test'); }).report(); // Benchmark Hive syncBenchmark('Hive Insert', () async { final box = await Hive.openBox<MyClass>('benchmark'); for (int i = 0; i < testData.length; i++) { await box.put(i, testData[i]); } }).report(); syncBenchmark('Hive Select', () async { final box = await Hive.openBox<MyClass>('benchmark'); box.values.toList(); }).report(); // Clean up db.close(); Hive.deleteBoxFromDisk('benchmark'); }
В нашем эксперименте мы создали 1000 объектов класса MyClass
со случайными значениями, а затем выполнили вставку и выборку данных в SQLite и Hive.
Итак, давайте посмотрим на результат:
Чтобы вам было легче видеть, я переведу результаты в формат графика:
Хорошо, у меня есть один вопрос.
Серьезно
Хотя Hive показал лучшую производительность в этом тесте, разница в производительности между Hive и SQLite не настолько значительна, чтобы писать статью о Hive в религиозном безумии.
Основным преимуществом Hive является простота использования. Hive позволяет быстро создавать и использовать объекты. Это может быть особенно полезно для приложений, которые не требуют больших объемов данных и требуют быстрой реакции на ввод данных пользователем.
С другой стороны, SQLite — более мощный инструмент для управления данными, особенно для крупномасштабных проектов с большим объемом данных. SQLite может предоставить множество опций для управления данными, таких как ограничения целостности, триггеры и т. д.
Таким образом, при выборе между Hive и SQLite необходимо учитывать требования приложения и объем данных, которые необходимо обработать. Если требуется быстрое и простое решение для небольших объемов данных, Hive — лучший выбор. Если проект крупномасштабный, требует более сложного управления данными и включает в себя большие объемы данных, то SQLite — лучший выбор.
Вам также могут быть интересны другие мои тесты:
Технический персонал:
Или целая серия статей о работе с REST API (это настоящее дерьмо как Санта-Барбара):
Совместная работа Flutter и REST API — реализация фильтрации (часть 10)
Добро пожаловать в часть 10 серии «Совместная работа Flutter и REST API! Это особая веха, так как мы…medium.com»