Начальная загрузка базы данных
Рассмотрим инициализацию игры. В методе start() нужно заполнить спейсы
Tarantool данными о покемонах. Почему бы не хранить все игровые данные в
памяти? Зачем использовать базу данных?
Ответ: долговременное хранение.
Без базы данных есть риск потерять данные, например, при отключении питания. Но если хранить
данные в базе данных в оперативной памяти, Tarantool обеспечивает их
сохранение на диске при каждом изменении. Это даёт ещё одно
преимущество: быстрый запуск в случае сбоя.
В Tarantool используется интеллектуальный алгоритм,
который при запуске быстро загружает все данные с диска в оперативную память,
поэтому прогрев занимает немного времени.
Мы будем использовать функции из встроенного модуля Tarantool box:
box.schema.create_space('pokemons')— создание спейса с именемpokemonдля хранения информации о покемонах (аналогичный спейс для игроков не создаётся, поскольку информацию об игроках планируется только отправлять и получать через API-вызовы, поэтому хранить её не нужно);box.space.pokemons:create_index('primary', {type = 'hash', parts = {1, 'unsigned'}})— создание первичного HASH-индекса по идентификатору покемона;box.space.pokemons:create_index('status', {type = 'tree', parts = {2, 'str'}})— создание вторичного TREE-индекса по статусу покемона.
Обратите внимание на аргумент parts = в спецификации индекса.
Идентификатор покемона является первым полем в кортеже Tarantool,
поскольку это первый элемент соответствующего типа Avro. То же относится
и к статусу покемона. В самом JSON-документе поля ID или status могут
находиться в любой позиции JSON-объекта.
Реализация метода start() выглядит так:
-- create game objectstart = function(self)-- create spaces and indexesbox.once('init', function()box.schema.create_space('pokemons')box.space.pokemons:create_index("primary", {type = 'hash', parts = {1, 'unsigned'}})box.space.pokemons:create_index("status", {type = "tree", parts = {2, 'str'}})end)-- create modelslocal ok_m, pokemon = avro.create(schema.pokemon)local ok_p, player = avro.create(schema.player)if ok_m and ok_p then-- compile modelslocal ok_cm, compiled_pokemon = avro.compile(pokemon)local ok_cp, compiled_player = avro.compile(player)if ok_cm and ok_cp then-- start the game<...>elselog.error('Schema compilation failed')endelselog.info('Schema creation failed')endreturn falseend