На самом деле, я занимаюсь миграцией базы данных уже больше месяца, проект, который я сейчас разрабатываю, фактически использовал MySQL в качестве основной базы данных в древние времена, позже, по некоторым причинам бизнеса, я мигрировал с MySQL на MongoDB и использовал несколько After несколько месяцев, поскольку служба базы данных очень нестабильна и необслуживаема, а сама MongoDB представляет собой базу данных без схемы, проблема грязных данных в базе данных очень серьезна. В настоящее время у членов команды нет богатого опыта разработки на Rails, поэтому они все еще надеются использовать ActiveRecord и Migration для наложения жестких ограничений на данные для обеспечения легальности данных в базе данных.
В этой статье будут представлены некоторые проблемы, с которыми столкнулся автор в процессе переноса базы данных, и предоставлены читателям необходимые сведения.НеисправностьВыполнимое решение для переноса базы данных, если вам нужно перенести базу данных без простоев или вам нужны другие решения, представленное здесь решение предназначено для MongoDB с объемом данных в миллионы, расчетное время простоя составляет около двух часов, если объем данных находится на уровне уровень десятков миллионов Выше чрезмерное время простоя может быть неприемлемым, и должен быть разработан план непрерывной миграции; в любом случае, автор надеется, что эта статья может принести некоторые идеи разработчикам, которые хотят выполнить миграцию базы данных, и избежать некоторых подводные камни.
От отношения к документу
Хотя основное внимание в этой статье уделяется миграции с MongoDB на MySQL, автор все же хочет кратко упомянуть миграцию с MySQL на MongoDB.Если мы просто импортируем все данные из MySQL в MongoDB, на самом деле это относительно простое дело. важная причина в том, чтоТипы данных, поддерживаемые MySQL, являются подмножеством MongoDB.:
В процессе миграции все данные в MySQL можно экспортировать в формате csv, после чего можно будет использовать все данные в формате csv.mongoimport
Все импортировано в MongoDB:
$ mysqldump -u<username> -p<password> \
-T <output_directory> \
--fields-terminated-by ',' \
--fields-enclosed-by '\"' \
--fields-escaped-by '\' \
--no-create-info <database_name>
$ mongoimport --db <database_name> --collection <collection_name> \
--type csv \
--file <data.csv> \
--headerline
Хотя весь процесс кажется очень простым всего двумя командами, вы столкнетесь с массой проблем, когда очень захотите это сделать.У автора нет опыта миграции с MySQL или других реляционных баз данных на MongoDB, но в гугле есть много актуальной информации, так что это всегда проблема, на которую наступали бесчисленные предшественники, и опыт предшественников также может помочь нам сэкономить много времени.
Использование csv для экспорта данных не вызовет проблем в большинстве случаев, но если какие-то документы в БД хранят форматированный текст, то хотя при экспорте данных проблем не будет, но при финальном импорте могут возникнуть некоторые проблемы.Довольно странная ошибка.
От документа к отношениям
По сравнению с миграцией с MySQL на MongoDB, обратная миграция более чем удваивает проблему, главным образом потому, что в MySQL не существует связи между многими типами данных и коллекциями в MongoDB, такими как встроенные данные. В реализации типов коллекций, таких как структуры , массивы и хэши, а также отношения "многие ко многим", многие проблемы не могут быть решены только путем переноса данных. Перед переносом данных необходимо реконструировать некоторые структуры данных. Эта статья Во второй половине этого раздела будут представлены структуры данных и логика, которые необходимо обработать.
Прежде чем мы будем готовы полностью перенести базу данных на MySQL, нам необходимо выполнить некоторую подготовительную работу, чтобы максимально сократить работу, необходимую для окончательной миграции, чтобы гарантировать, что время простоя не будет слишком долгим. максимально исключить сложные данные в проекте.
предварительная обработка данных
Перед миграцией нужно выполнить большую подготовку, первое, что нужно сделать, это изменить все встроенные структуры данных на невстроенные структуры данных:
то есть положить всеembeds_many
а такжеembeds_one
отношения меняются наhas_many
а такжеhas_one
, в то время какembedded_in
заменены наbelongs_to
В то же время нам нужно изменить соответствующие тесты в проекте на это эталонное отношение, но только изменение отношения в коде на самом деле не меняет данные в MongoDB.
def embeds_many_to_has_many(parent, child)
child_key_name = child.to_s.underscore.pluralize
parent.collection.find({}).each do |parent_document|
next unless parent_document[child_key_name]
parent_document[child_key_name].each do |child_document|
new_child = child_document.merge "#{parent.to_s.underscore}_id": parent_document['_id']
child.collection.insert_one new_child
end
end
parent.all.unset(child_key_name.to_sym)
end
embeds_many_to_has_many(Person, Address)
Мы можем использовать приведенный выше код для преобразования всех встроенных моделей в ссылки, выравнивая все сложные отношения данных.Время выполнения этого кода зависит от количества двух моделей во встроенных отношениях.Следует отметить, что в MongoDB данные, встроенные в модель может показаться одинаковой по какой-то причине_id
Конфликты могут вызвать сбой при вставке, вы можетеinsert_one
использоватьresuce
Чтобы гарантировать, что выполнение этого кода не остановится по вышеуказанным причинам.
С помощью этого кода мы можем легко расширить все исходные встроенные отношения в ссылочные отношения и превратить встроенные отношения в ссылки.Кроме этих двух изменений, нам не нужно делать другие вещи, будь то запрос данных.Создание модели не нужно менять реализацию кода, но помните, что внешний ключ родительской модели должен быть в дочерней моделидобавить индекс, в противном случае это приведет к тому, что родительская модель вызоветполное сканирование таблицы:
class Comment
include Mongoid::Document
index post_id: 1
belongs_to :post
end
После того, как мы разобрались с уникальными встроенными отношениями в MongoDB, нам нужно решить некоторые сложные типы коллекций, такие как массивы и хэши, если мы используем MySQL 5.7 или PostgreSQL, нам не нужно с ними разбираться, т.к. последние версии MySQL и PostgreSQL уже поддерживает JSON, но автор превратил в проекте и массивы, и хэши в общие структуры данных.
В этом необязательном процессе на самом деле нет стандартного ответа Мы можем конвертировать разные данные в разные структуры данных по мере необходимости:
Например, преобразование массива в строку или отношение «один ко многим», преобразование хэша в пару «ключ-значение» текущего документа и т. д., как обращаться с этими данными коллекции, на самом деле зависит от нашей бизнес-логики. изменяя эти поля, старайтесь быть как Верхний слой обеспечивает прямое.tags
или.categories
API с тем же результатом:
class Post
...
def tag_titles
tags.map(&:title)
end
def split_categories
categories.split(',')
end
end
Этот шаг на самом деле необязателен. Приведенный выше код предназначен только для уменьшения нагрузки по модификации в других местах. Конечно, если вы хотите использовать базу данных MySQL 5.7 или PostgreSQL для поддержки JSON, большой проблемы нет, но есть некоторые проблемы при запросе поля сбора неудобно.
«Младшие братья» монгоида
Некоторые связанные плагины неизбежно будут использоваться во время разработки с Mongoid, напримерmongoid-enum,mongoid-slugа такжеmongoid-historyи т.д. Эти плагины реализованы с Плагины с одинаковым функционалом в ActiveRecord имеют очень разные реализации.
Для некоторых плагинов, таких как mongoid-slug, он вставляется только в документ модели, которая представила плагин._slugs
поля, нам нужно только игнорировать эти добавленные поля во время переноса данных и заменить все#slug
метод изменен на#id
, никаких других изменений во время предварительной обработки не требуется. Реализация перечисления полностью отличается в плагине Mongoid и ActiveRecord:
mongoid-enum использует строки и_status
для хранения полей типа перечисления, в то время как ActiveRecord использует целые числа иstatus
Представляет тип перечисления. У них есть некоторые различия в хранении базовой структуры данных. Мы решим эту проблему в более позднем сценарии миграции.
Если в проекте используется много плагинов Mongoid из-за их разных реализаций, мы можем только решить, как их мигрировать в соответствии с конкретной реализацией разных плагинов.Если используются некоторые плагины, поддерживающие специальные функции , это может быть сложно реализовать в ActiveRecord. Найдите соответствующую поддержку и рассмотрите возможность временного удаления некоторых неважных функций при миграции.
Первичный ключ и UUID
Еще одна важная причина, по которой мы хотим перейти с MongoDB на MySQL, заключается в том, что первичный ключ каждого документа в MongoDB слишком подробный, 32-байтовый первичный ключ._id
Не может предоставить нам много информации, это может только увеличить нашу дислексию, а кластер MongoDB не развернут в проекте, поэтому мы не можем воспользоваться преимуществами использования механизма генерации UUID по умолчанию.
Мы не только не воспользовались преимуществами UUID, но и доставили нам много проблем в процессе миграции MySQL, с одной стороны, из-за того, что первичный ключ ActiveRecord по умолчанию является целым числом и не поддерживает UUID. с длиной байта 32. Мы не хотим менять UUID MongoDB, и нет проблем с переносом его непосредственно в MySQL, но нам нужно изменить первичный ключ целочисленного типа по умолчанию на строковый тип, и в то же время используйте генератор UUID, чтобы убедиться, что все первичные ключи увеличиваются по времени и не конфликтуют.
Если вы собираетесь использовать метод генератора UUID плюс, это на самом деле сэкономит много времени на миграцию, но не кажется особенно элегантным.Как выбрать, все еще нужно взвесить и оценить, но если мы решим использоватьinteger
Когда используется тип самоинкрементного первичного ключа, необходимо проделать много дополнительной работы, во-первых, добавить все таблицы.uuid
поля, как для всех внешних ключей, например.post_id
создать соответствующийpost_uuid
поле, черезuuid
Соотнесите два:
В процессе переноса данных мы_id
сопоставить сuuid
середина,post_id
сопоставить сpost_uuid
на, мы держимuuid
а такжеpost_uuid
Связь между моделями гарантирует, что связь между моделями не будет потеряна в процессе переноса данных.id
а такжеpost_id
Нет абсолютно никакой связи.
когда мы следуем_id
Порядок проходит через весь документ, и когда данные в документе вставляются в таблицу, MySQL автоматически генерирует инкрементный первичный ключ для всех строк данных.id
,а такжеpost_id
На данный момент все пусто.
После того, как все данные были вставлены в MySQL, мы передаем#find_by_uuid
запрос будетuuid
а такжеpost_uuid
Отношения в Migrate toid
а такжеpost_id
, и будет сочетаться сuuid
Все соответствующие поля удаляются, чтобы мы могли гарантировать, что связь между моделями не исчезнет, а взаимное расположение строк данных будет точно таким же, как и до миграции.
миграция кода
Монгоид используетсяinclude
Загружайте соответствующие методы в текущую модель, а ActiveRecord делает это через наследование.ActiveRecord::Base
После завершения предварительной обработки данных мы можем изменить код существующего слоя модели.
Во-первых, конечно, изменить «родительский класс» модели, поставить всеMongoid::Document
изменился наActiveRecord::Base
, а затем создайте файл миграции, соответствующий классу:
# app/models/post.rb
class Post < ActiveRecord::Base
validate_presence_of :title, :content
end
# db/migrate/20170908075625_create_posts.rb
class CreatePosts < ActiveRecord::Migration[5.1]
def change
create_table :posts do |t|
t.string :title, null: false
t.text :content, null: false
t.string :uuid, null: false
t.timestamps null: false
end
add_index :posts, :uuid, unique: true
end
end
Примечание. Чтобы добавить строку типа в каждую таблицу
uuid
поле, такжеuuid
Создайте уникальный индекс для ускорения прохожденияuuid
Скорость построения взаимосвязей между разными моделями данных.
В дополнение к созданию файла миграции для базы данных и модификации базового класса нам также необходимо изменить некоторыеinclude
модули и запросы, уникальные для Mongoid, такие как использованиеgte
илиlte
Запросы даты и запросы, которые используют регулярные выражения для сопоставления с образцом, эти запросы используются в ActiveRecord совершенно по-другому, чем в Mongoid, и нам нужно решать эти проблемы с помощью написанного от руки SQL.
Кроме того, нам также нужно иметь дело с некоторыми сложными модельными отношениями, такими как Mongoid вinverse_of
вызывается в ActiveRecordforeign_key
Подождите, эти модификации на самом деле не сложные, но если вы хотите разобраться со всем кодом в этой части, вам нужно детально протестировать бизнес-логику, чтобы убедиться, что не останется проблем, что также является тестом нашего проекта. Покрытие предъявляет относительно высокие требования, но я считаю, что большинство проектов Rails имеют очень хорошее тестовое покрытие, которое может гарантировать плавную миграцию этой части кода и логики, но если в проекте нет теста или тестовое покрытие очень высокое низкое, вы можете испытать только человеческую плоть или искать больше благословений, илиНе делайте миграций, пишите больше тестов и учитывайте эти рефакторинги..
перенос данных
Создание соответствующего файла миграции для каждой модели и построение таблицы на самом деле является ручной работой, которую необходимо выполнить.Хотя есть некоторые задачи, которые мы не можем пропустить, мы можем рассмотреть возможность автоматизации всех моделей.uuid
полей и индексов, но и для подобныхpost_id
поля добавляют соответствующиеpost_uuid
Список:
class AddUuidColumns < ActiveRecord::Migration[5.1]
def change
Rails.application.eager_load!
ActiveRecord::Base.descendants.map do |klass|
# add `uuid` column and create unique index on `uuid`.
add_column klass.table_name, :uuid, :string, unique: true
add_index klass.table_name, unique: true
# add `xxx_uuid` columns, ex: `post_uuid`, `comment_uuid` and etc.
uuids = klass.attribute_names
.select { |attr| attr.include? '_id' }
.map { |attr| attr.gsub '_id', '_uuid' }
next unless uuids.present?
uuids.each do |uuid|
add_column klass.table_name, uuid, :string
end
end
end
end
в добавленииuuid
После того, как столбцы и индексы установлены, мы можем начать миграцию базы данных.Если мы решим изменить первичный ключ исходных данных в процессе миграции, мы разделим миграцию на два этапа: миграция данных и восстановление отношений, бывший относится только к переносу всех данных в MongoDB в соответствующую таблицу в MySQL и передаче всех данных в соответствующую таблицу в MySQL._id
Перевести вuuid
,xx_id
Перевести вxx_uuid
, а последний упоминался ранее: byuuid
а такжеxx_uuid
Ассоциация восстанавливает отношения между моделями и в конце удаляет всеuuid
поле.
Мы можем использовать следующий код для миграции данных.Этот код просматривает все данные в коллекции из MongoDB, а затем передает документ в качестве параметра в блок, а затем передаетDatabaseTransformer#delete_obsolete_columns
а такжеDatabaseTransformer#update_rename_columns
Метод удаляет некоторые существующие столбцы, обновляет некоторые столбцы данных и, наконец, помещает всеid
столбцы становятсяuuid
:
module DatabaseTransformer
def import(collection_name, *obsolete_columns, **rename_columns)
collection = Mongoid::Clients.default.collections.select do |c|
c.namespace == "#{database}.#{collection_name.to_s.pluralize}"
end.first
unless collection.present?
STDOUT.puts "#{collection_name.to_s.yellow}: skipped"
STDOUT.puts
return
end
constant = collection_name.to_s.singularize.camelcase.constantize
reset_callbacks constant
DatabaseTransformer.profiling do
collection_count = collection.find.count
collection.find.each_with_index do |document, index|
document = yield document if block_given?
delete_obsolete_columns document, obsolete_columns
update_rename_columns document, rename_columns
update_id_columns document
insert_record constant, document
STDOUT.puts "#{index}/#{collection_count}\n" if (index % 1000).zero?
end
end
end
end
После выполнения различных операций над документом этот метод будет вызываться напрямуюDatabaseTransformer#insert_record
Вставьте данные в соответствующую таблицу в MySQL; мы можем напрямую использовать следующий код для переноса всех документов в коллекции в MySQL:
transformer = DatabaseTransformer.new 'draven_production'
transformer.import :post, :_slugs, name: :title, _status: :status
Приведенный выше код будет объединять каждый документ_slugs
все поля игнорируются, аname
переименован вtitle
,_status
переименован вstatus
, хотя поле mongoid-enum как тип перечисления полностью отличается от типа перечисления ActiveRecord, здесь нет проблем с прямой вставкой, модель ActiveRecord сама обработает преобразование между строками и целыми числами при ее создании:
def insert_record(constant, params)
model = constant.new params
model.save! validate: false
rescue Exception => exception
STDERR.puts "Import Error: #{exception}"
raise exception
end
Чтобы ускорить вставку данных и избежать всех побочных эффектов операций вставки, мы сбрасываем все обратные вызовы во время переноса данных:
def reset_callbacks(constant)
%i(create save update).each do |callback|
constant.reset_callbacks callback
end
end
Функция этого кода вступит в силу только во время работы скрипта и не окажет никакого влияния на другие части проекта; в то же время скрипт будет печатать текущий прогресс в стандартный вывод после того, как каждая 1000 моделей будет успешно завершена. Помогите нам быстро определить проблемы и оценить время миграции.
ты сможешьdatabase_transformer.rbНайдите полный код переноса данных.
После вставки всех данных в таблицу MySQL явной связи между моделями нет, нам также нужно пройтиuuid
Подключенная модель преобразуется для использованияid
К отношениям между объектами можно получить доступ только напрямую через точечный синтаксис.Установление отношения на самом деле очень просто.Мы получаем все окончания текущего класса как_uuid
свойства, затем выполняет итерацию по всем строкам данных в соответствии сuuid
стоимость иpost_uuid
Часть атрибута «post» получает имя таблицы и, наконец, получает соответствующую модель ассоциации.Здесь мы также имеем дело с особыми случаями, такими как полиморфизм:
module RelationBuilder
def build_relations(class_name, polymorphic_associations = [], rename_associations = {})
uuids = class_name.attribute_names.select { |name| name.end_with? '_uuid' }
unless uuids.present?
STDOUT.puts "#{class_name.to_s.yellow}: skipped"
STDOUT.puts
return
end
reset_callbacks class_name
RelationBuilder.profiling do
models_count = class_name.count
class_name.unscoped.all.each_with_index do |model, index|
update_params = uuids.map do |uuid|
original_association_name = uuid[0...-5]
association_model = association_model(
original_association_name,
model[uuid],
polymorphic_associations,
rename_associations
)
[original_association_name.to_s, association_model]
end.compact
begin
Hash[update_params].each do |key, value|
model.send "#{key}=", value
end
model.save! validate: false
rescue Exception => e
STDERR.puts e
raise e
end
STDOUT.puts "#{index}/#{models_count}\n" if (counter % 1000).zero?
end
end
end
end
После нахождения соответствующей строки данных это очень просто, мы вызываем соответствующуюpost=
После обновления внешнего ключа другими методами значение внешнего ключа напрямую сохраняется в базе данных.Как и в процессе переноса данных, мы также будем печатать текущий прогресс во время выполнения этого кода.
в инициализацииRelationBuilder
, если мы перейдемconstants
, затем вызовRelationBuilder#build!
Все отношения в нем будут перестроены, но если его не передать, все подклассы в ActiveRecord будут загружены по умолчанию, а все подклассы в ActiveRecord будут по умолчанию удалены.::
модель, которая используется в ActiveRecordhas_and_belongs_to_many
Созданный промежуточный класс мы опишем в следующем разделе, как обрабатывать отношения «многие ко многим» по отдельности:
def initialize(constants = [])
if constants.present?
@constants = constants
else
Rails.application.eager_load!
@constants = ActiveRecord::Base.descendants
.reject { |constant| constant.to_s.include?('::') }
end
end
Код, связанный с восстановлением отношений, можно найти вrelation_builder.rbНайдите полный код для переноса отношений.
builder = RelationBuilder.new([Post, Comment])
builder.build!
Большинство проблем миграции данных можно решить с помощью двухэтапной миграции данных и восстановления отношений.Однако, поскольку обработка отношений «многие ко многим» в MongoDB и ActiveRecord особенная, нам нужно решать их отдельно.Если все миграции Здесь проблема решена, теперь мы можем использовать следующий файл миграции для переноса базы данных вuuid
Все соответствующие столбцы удаляются:
class RemoveAllUuidColumns < ActiveRecord::Migration[5.1]
def change
Rails.application.eager_load!
ActiveRecord::Base.descendants.map do |klass|
attrs = klass.attribute_names.select { |n| n.include? 'uuid' }
next unless attrs.present?
remove_columns klass.table_name, *attrs
end
end
end
На этом весь процесс миграции в основном завершен, а затем возникают другие вопросы, связанные со всем процессом миграции, такие как взаимосвязь между многими парами, важность тестирования и другие темы.
Обработка отношений «многие ко многим»
Отношение «многие ко многим» на самом деле немного сложнее в процессе переноса данных, оно используется в Mongoid.has_and_belongs_to_many
добавитtag_ids
илиpost_ids
множество:
# The post document.
{
"_id" : ObjectId("4d3ed089fb60ab534684b7e9"),
"tag_ids" : [
ObjectId("4d3ed089fb60ab534684b7f2"),
ObjectId("4d3ed089fb60ab53468831f1")
],
"title": "xxx",
"content": "xxx"
}
В ActiveRecord будет создана отдельная таблица, имя которой представляет собой конкатенацию двух имен таблиц в алфавитном порядке.Post
а такжеTag
, соответствующая таблица «многие ко многим»posts_tags
, помимо создания таблицы «многие ко многим»,has_and_belongs_to_many
также создаст дваActiveRecord::Base
подклассTag::HABTM_Posts
а такжеPost::HABTM_Tags
, мы можем просто поэкспериментировать со следующим кодом:
require 'active_record'
class Tag < ActiveRecord::Base; end
class Post < ActiveRecord::Base
has_and_belongs_to_many :tags
end
class Tag < ActiveRecord::Base
has_and_belongs_to_many :posts
end
puts ActiveRecord::Base.descendants
# => [Tag, Post, Post::HABTM_Tags, Tag::HABTM_Posts]
Приведенный выше код выводит дваhas_and_belongs_to_many
сгенерированный классTag::HABTM_Posts
а такжеPost::HABTM_Tags
, у них точно такая же таблицаposts_tags
, при работе с отношениями «многие ко многим» нам нужно использовать толькоDatabaseTransformer
После импорта всех данных в таблицу, затем путем обходаposts_tags
Данные в таблице можно обновить в таблице отношений «многие ко многим»:
class PostsTag < ActiveRecord::Base; end
# migrate data from mongodb to mysql.
transformer = DatabaseTransformer.new 'draven_production'
transformer.import :posts_tags
# establish association between posts and tags.
PostsTag.unscoped.all.each do |model|
post = Post.find_by_uuid model.post_uuid
tag = Tag.find_by_uuid model.tag_uuid
next unless post.present? && tag.present?
model.update_columns post_id: post.id, tag_id: tag.id
end
все используютhas_and_belongs_to_many
Отношения «многие ко многим» необходимо перенести с помощью приведенного выше кода, на этом шаге необходимо удалить всеuuid
поля заполняются раньше.
Важность тестирования
Прежде чем приступить к миграции онлайн-сервисов, нам действительно необходимо выполнить частичное и полное тестирование существующих данных в базе данных.На этапе тестирования мы можем подготовить локальный объем данных, который составляет 1/10 или 1 от объема данных производственной среды. ./100 MongoDB путем локального моделирования среды MongoDB и MySQL перед миграцией, чтобы мы могли найти ошибки в сценарии миграции как можно скорее.
Способ подготовки тестовой базы данных заключается в удалении некоторых строк данных основной модели через отношения, которые можно удалить через MongoDB.dependent: :destroy
Удалите связанные модели, чтобы максимально обеспечить непротиворечивость и целостность данных, но перед миграцией онлайн-базы данных нам все равно нужно выполнить полный тест миграции для всех данных в MongoDB, чтобы мы могли найти еще несколько скрытых данных. проблема заключается в том, чтобы гарантировать, что меньше ситуаций может произойти, когда он действительно находится в сети.
Миграция базы данных на самом деле является реконструкцией.Перед миграцией базы данных MongoDB мы должны убедиться, что проект имеет полную тестовую систему и тестовые случаи, чтобы мы могли быть уверены, что после проекта не возникнет проблем, которые мы не можем предсказать. реконструируется.Проект управляемый,если тестов мало или вообще нет тестов в проекте,то о рефакторинге не говорите -Модульные тесты — основа рефакторинга.
Суммировать
Миграция с MongoDB на MySQL на самом деле является инженерной проблемой: нам нужно постоянно искать возможные ошибки во всем процессе, разделять относительно сложную задачу и минимизировать влияние миграции на доступность и стабильность сервиса до фактической миграции. секс.
Кроме того, выбор между MongoDB и MySQL не обязательно стоит того или иного.Большую часть данных в проекте мы мигрировали в MySQL, но часть данных для расчета и анализа оставили в MongoDB, чтобы она могла обеспечить выполнение основных задачи проекта не пострадают после того, как MongoDB выйдет из строя, и в то же время скорость резервного копирования и восстановления MySQL будет очень высокой, потому что база данных станет меньше.
И последнее, тестирование действительно важно, без тестирования никто не может этого сделать.Не потерять бизнес-логику в процессе модификации большого количества бизнес-кодов, и даже без тестирования большая часть бизнес-логики могла быть потеряна в день ее разработки.
Если у вас есть какие-либо вопросы по содержанию статьи или вопросы, связанные с миграцией MongoDB, вы можете оставить сообщение в комментариях.Системе комментариев нужна лестница для использования Disqus.
Оригинальная ссылка:Как перейти с MongoDB на MySQL
Follow: Draveness · GitHub