Я работаю с механизмом приложения Google (GAE) для Java. Я изо всех сил пытаюсь разработать модель данных, которая подыгрывает достоинствам и недостаткам большой таблицы, это два предыдущих связанных сообщения:
Я предварительно выбрал полностью нормализованную магистраль с денормализованными свойствами, добавленными в объекты так, чтобы большинство клиентских запросов могло быть обслужено только с одним запросом.
Я обосновываю, что полностью нормализованная магистраль будет:
В то время как денормализованные данные будут:
Я посмотрел видео механизма приложения описание техники, называемой "разветвлением на выходе". Идея состоит в том, чтобы сделать быстрые записи к нормализованным данным и затем использовать очередь задачи для завершения денормализации негласно без клиента, имеющего необходимость ожидать. Я включал видео здесь для ссылки, но его один час длиной и нет никакой потребности наблюдать его для понимания этого вопроса: http://code.google.com/events/io/2010/sessions/high-throughput-data-pipelines-appengine.html
Если бы я использую этот метод "разветвления на выходе", каждый раз, когда клиент изменяет некоторые данные, приложение обновило бы нормализованную модель в одной быстрой записи и затем исчерпало бы инструкции по денормализации очереди задачи, таким образом, клиент не должен ожидать их для завершения также.
Проблема с использованием очереди задачи для обновления денормализованной версии данных состоит в том, что клиент мог выполнить запрос чтения на данных, которые они просто изменили, прежде чем очередь задачи завершила денормализацию на тех данных. Это предоставило бы клиенту устаревшие данные, которые инконгруэнтны с их недавним запросом, смущающим клиент, и подающий заявку кажутся ошибочными.
Как средство, я предлагаю разветвиться операции денормализации параллельно через асинхронные вызовы к другим URL в приложении через URLFetch: http://code.google.com/appengine/docs/java/urlfetch/ приложение ожидало бы до всех асинхронных вызовов, был завершен прежде, чем ответить на клиентский запрос.
Например, если у меня есть объект "Назначения" и "Клиентский" объект. Каждое назначение включало бы денормализованную копию информации о клиенте для кто его запланированное для. Если бы клиент изменил их имя, то приложение выполнило бы 30 асинхронных вызовов; один к каждому затронутому ресурсу назначения для изменения копии имени клиента в каждом.
В теории это могло все быть сделано параллельно. Вся эта информация могла быть обновлена примерно во время, которое требуется для создания 1 или 2 записей к хранилищу данных. Своевременный ответ мог быть сделан клиенту после того, как денормализация была завершена, устранив возможность клиента, подвергаемого инконгруэнтным данным.
Самая большая потенциальная проблема, которую я вижу с этим, состоит в том, что приложение не может иметь больше чем 10 асинхронных вызовов запроса, идущих в любой момент (зарегистрированный здесь): http://code.google.com/appengine/docs/java/urlfetch/overview.html).
Мое предложенное средство состоит в том, чтобы отправить указания по денормализации к другому ресурсу, который рекурсивно разделяет инструкции на меньшие блоки равного размера, называя себя с меньшими блоками как параметры, пока количество инструкций в каждом блоке не является достаточно небольшим, чтобы быть выполненным напрямую. Например, если клиент с 30 связанными назначениями изменил написание их имени. Я назвал бы ресурс денормализации с инструкциями обновить все 30 назначений. Это затем разделило бы те инструкции на 10 наборов 3 инструкций и выполнило бы 10 асинхронных запросов к его собственному URL с каждым набором 3 инструкций. После того как система команд была меньше чем 10, ресурс затем выполнит асинхронные запросы напрямую согласно каждой инструкции.
Мои проблемы с этим подходом:
Я был бы очень признателен за некоторый вход на этом подходе.
Это звучит ужасно сложно, и чем сложнее дизайн, тем сложнее его кодировать и поддерживать.
Предполагая, что вам нужно денормализовать данные, я бы предложил просто использовать базовую технику денормализации, но следить за тем, какие объекты обновляются. Если клиент запрашивает обновляемый объект, вы знаете, что вам нужно запросить базу данных, чтобы получить обновленные данные; в противном случае вы можете полагаться на денормализованные данные. После завершения очереди задач она может удалить объект из списка «обновляемых», и все будет полагаться на денормализованные данные.
Сложная версия может даже отслеживать, когда каждый объект был отредактирован, чтобы данный объект знал, был ли он уже обновлен в очереди задач.
Похоже, вы повторно реализуете материализованные представления http://en.wikipedia.org/wiki/Materialized_view .