Как безопасно повторно использовать записи базы данных в MySql из Django (в Apache) - PullRequest
0 голосов
/ 24 сентября 2019

Короче говоря: в веб-приложении Django для Apache2 (linux) и MySql (ISAM) нам нужно безопасно повторно использовать некоторые записи, помеченные как deleted, вместо создания новых.Даже если больше пользователей могут запросить такие действия одновременно, каждый из них должен получить различную запись для повторного использования.


Фон:

  • У нас есть веб-приложение, гдемногие пользователи могут делать что-то одновременно.
  • есть таблицы, которые растут до бесконечности, но активны лишь немногие записи (иногда, например, из 100 000 длинных записей активна 1.000, и нет никаких шансов для повторной активации любого «удаленного»).)
  • иногда передаются (в другие места) просто изменения, поэтому мы помечаем «удаленные» записи как таковые и переносим их для удаления записей на другой стороне
  • иногда требуется для переноса таблиц(частично) в целом, и это занимает слишком много времени
  • целостность данных во время передачи управляется другой частью проекта и не должна вызывать реальных проблем

Требуется:

  • повторно использовать некоторые старые и давно "удаленные" записи для новых данных
  • не проблема, иметь поле reuse_me в таблицах (по умолчанию)t False, установить True после долгого времени, удаленного некоторым скриптом).Можно смело предположить, что такие записи нигде не ссылаются и не ссылаются ни на что другое (скрипт может удалить все ссылки из записи и пометить только не ссылочные записи, поэтому древовидные структуры будут освобождены за большее количество шагов - нетциклические структуры для освобождения в любом случае, и если они станут, может быть другой способ отключить их как единое целое)
  • есть проблема, как выбрать их для использования, когда более чем один пользователь может попробовать этов то же время (как побочный эффект присутствия в сети)

Простое решение (не работает во многих случаях):

  • некоторые записи легкописать полностью за один раз с помощью чистого SQL (что-то вроде UPDATE car_owners_cross SET deleted=0, resuse_me=0, owner_id=123, car_type_id=456 WHERE deleted=1 AND resuse_me=1 LIMIT 1;), и он (должен) выбрал бы «произвольную свободную запись» и переписал бы ее, чтобы она больше не была свободной и не было никакого конфликта.(также это будет сделано только в том случае, если число бесплатных записей больше, чем, скажем, 100, в противном случае это будет просто ВСТАВЛЕНО - поэтому не беспокойтесь о том, что не найдете бесплатную запись в параллельном доступе)

Общее решение:

  • некоторые записи являются более сложными и требуют многократного обновления до тех пор, пока задача не будет выполнена (например, прикрепить файл, создать связанные записи, переписать его в зависимости от последующего веб-ввода ....), поэтому необходимознаю, какая запись была выбрана для задачи для повторного использования - и я не знаю, как это сделать
  • решением должна быть функция Django, возвращающая idповторно использованного / созданного объекта (или объекта с действительным идентификатором) - например, coc=reuse_or_create(models.Car_Owners_Cross, owner_id=123, car_type_id=456) или coc=models.Car_Owners_Cross.reuse_or_create(owner_id=123, car_type_id=456) - хотя для этого, вероятно, потребуется некоторое волшебство SQL / курсоры / и т.д. внутри
  • Я думаю, решение будет простым, если бы был способ получить идентификатор измененной записи - таким образом, он принял бы форму UPDATE car_owners_cross SET deleted=0, resuse_me=0 WHERE deleted=1 AND resuse_me=1 LIMIT 1; получить идентификатор этой записи , а затем выпустить UPDATE car_owners_cross SET owner_id=123, car_type_id=456 WHERE id=789 - но я не знаюкак получить идентификаторДля этой записи

Примечания:

  • существуют планы для новой функции, которая значительно усугубит проблему (создание и удаление тонны записейРегулярно, много раз без толку - пока пользователь просто «играет с настройками», оставляя лишь несколько не deleted записей после - так что было бы очень полезно иметь такую ​​функцию с самого начала
  • в приведенном выше примере - каждый владелец может иметь любое количество типов автомобилей (и любое количество идентичных типов автомобилей - поэтому многие записи будут иметь одинаковые значения, кроме уникального идентификатора), а также любой CarType может принадлежать любому количеству владельцев
  • реальные записи намного сложнее, но принцип тот же
  • количество (deleted) записей уже создает проблемы
  • цель состоит в том, чтобы улучшить соотношение valid к deleted записей, а не в том, чтобы исключать каждую «удаленную» запись (чтобы можно было сохранить пул reuse_me отмеченных записей, чтобы быть уверенным, что UPDATE получит свою жертву и сделает новые записи, даже если некоторые reuse_me все еще существуют - размер пула может быть настроен в коде, просто нужно быть "вменяемым" - скажем, как 3-кратное число ожидаемых одновременно вошедших в систему пользователей иличто-то в этом роде
  • есть возможность добавлять другие поля в затронутые таблицы, поддерживать reuse_me или делать reuse_me любого другого типа, кроме логического
  • , не все создание новой записи будетиспользуйте эту возможность (например, интерфейс администратора все равно будет просто использовать INSERT (coc=Car_Owners_Cross();...;coc.save();) и некоторые старые инструменты тоже)
  • если эта функция будет использоваться, все значения по умолчанию могут быть "вручную" установлены с помощью кодак допустимым значениям (было бы неплохо иметь их в значениях по умолчанию (просто для большей безопасности - но не совсем запрошено)
  • не все таблицы будут использоваться таким образом (и только таблицы из нашей ауn моделей будет, так что без аутентификации. * и т. д.)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...