Портирование приложения MySQL на MongoDB и размещение поля _id
У меня есть приложение PHP, которое может подключаться к нескольким бэкэндам (в настоящее время MySQL или XML) и которое я также пытаюсь заставить работать с MongoDB. Одна, казалось бы, незначительная проблема, с которой я явно борюсь, заключается в том, что мандаты Mongo '_id' - это имя первичного ключа. Бэкэнды, как правило, довольно хорошо абстрагируются приложением, но приложению необходимо работать с идентификатором довольно регулярно, поэтому я обращаюсь к нему с помощью кода, подобного $result['id']
, которая до сих пор хорошо зарекомендовала себя.
Но теперь я столкнулся с попыткой (эффективно!) Обработать БД, которая не позволит мне использовать 'id' в качестве ее первичного ключа, и я не уверен, какой вариант лучше. Вот что я подумала до сих пор:
Просто оставьте в монго значение _id и установите переменную приложения
$id
в"id"
или же"_id"
в зависимости от бэкэнда. Приложения должны использовать$id
для доступа к полю идентификатора, а не жестко"id"
, Обратите внимание, что все другие поля доступны по их именам строк, таким как$result['user']
и поэтому это будет нарушать нормы в приложении.Плюсы: позволяет объектам MongoCursor возвращаться напрямую, когда это возможно, обеспечивая минимальное использование памяти и быстрый доступ к данным.
Минусы: не обратно совместим, потребует (довольно утомительного) рефакторинга любого кода с использованием этого приложения.
Оберните возвращенные объекты MongoCursor в новый класс итератора, который возвращает каждый элемент с
"_id"
сопоставлены с"id"
соответственно. Приложение будет сопоставлять входящие звонки с"id"
вернуться к"_id"
при общении с монго.Плюсы: Сохраняет большую часть эффективности использования памяти 1., предотвращая при этом большинство проблем обратной совместимости.
Минусы: Не совсем уверен, как реализовать такой объект, не уверен, что это можно сделать чисто, или что он действительно будет работать так, как я себе представляю. Чтобы сделать это правильно, я бы хотел реализовать аналогичные оболочки итераторов и для других бэкэндов.
Загрузить результаты в память с
iterator_to_array()
как описано вMongoCollection.find()
, сделать соответствующие преобразования и вернуть массив.Плюсы: концептуально проще, чем 2., будет хорошо работать с остальной частью моего приложения.
Минусы: очевидно плохой выбор с точки зрения памяти. Не конец света, учитывая приложение, но все еще не идеальный.
Выделяются ли какие-либо из этих вариантов как конкретные разумные и надежные решения этой проблемы? Кто-нибудь может предложить другие альтернативы для обработки первичных ключей независимым от сервера способом? В будущем возможны дополнительные бэкэнды, поэтому приветствуются проблемы или преимущества данного метода, связанные с другими системами хранения данных.
Я в настоящее время склоняюсь к 2., но я приветствую ваши мысли.
1 ответ
В итоге я выбрал вариант 2, заключив в него итератор и скрыв существующее поле _id. Не чистый и не элегантный, но лучшее, что я мог сделать с тем, что у меня было. Работа над этим действительно заставила меня скучать по Python.