0

Моя команда пишет приложение с GAE (Java), которое привело меня к вопросу о масштабируемости моделирования отношений сущностей (в частности, многих ко многим) в объектно-ориентированных базах данных, таких как BigTable.Возможно ли моделирование бесконечных связей в NoSQL/BigTable (GAE)?

Предпочитаемое решение для моделирования неавторизованных отношений «один ко многим» и «многие ко многим» в хранилище данных App Engine (см. Entity Relationships in JDO), похоже, является списком ключей. Тем не менее, Google предупреждает:

«Есть несколько ограничений для реализации многих ко многим отношения таким образом Во-первых, вы должны явно получить значения на стороне коллекции, где список хранится с тех пор. все, что вам есть доступны ключевые объекты. еще более важным является то, что вы хотите избегать хранения чрезмерно больших списков ключей ...»

Говоря о чрезмерно больших списков ключей, если вы пытаетесь модель таким образом и предположим, что вы храните o ne Длинные для каждого ключа, тогда с лимитом на единицу сущности 1MB теоретическое максимальное количество отношений на объект составляет ~ 130k. Для платформы, основным преимуществом которой является масштабируемость, на самом деле это не так много отношений. Итак, теперь мы рассматриваем возможно оштукатующие объекты, которые требуют более 130 тыс. Отношений.

Другой подход (Модель отношения) описан в статье Modeling Entity Relationships как часть серии мастеринга хранилища данных в ресурсах разработчика AppEngine. Тем не менее, даже здесь Google предупреждает о производительности реляционных моделей:.

«Тем не менее, вы должны быть очень осторожными, потому что пересекая соединения коллекции потребуется больше звонков на датасторе Используйте этот вид многих -to-many только тогда, когда вам действительно нужно , и делайте это с осторожностью при выполнении вашего приложения ».

Итак, вы спрашиваете: «Зачем вам требуется более 130 тыс. Отношений для каждого объекта?» Ну, я рад, что вы спросили. Возьмем, к примеру, приложение CMS с сказать, 1 млн пользователей (Эй, я могу мечтать правильно ?!)

Пользователи могут загружать контент и делиться им с: 1. общественные 2. лиц 3. группы 4 любая комбинация

Теперь кто-то входит в систему и переходит к панели управления, которая показывает новые закачки от людей, к которым они подключены в любой группе. Эта панель должна включать общедоступный контент и контент, совместно используемый этим пользователем или группой, членом которой является этот пользователь. Не так уж плохо? Давайте копаем в него.

public class Content { 
    private Long id; 
    private Long authorId; 
    private List<Long> sharedWith; //can be individual ids or group ids 
} 

Теперь мой запрос, чтобы получить все идентификационная разрешено видеть может выглядеть следующим образом:

List<Long> idsThatGiveMeAccess = new ArrayList<Long>(); 
idsThatGiveMeAccess.add(myId); 
idsThatGiveMeAccess.add(publicId); //Let's say that sharing with 0L makes it public 
for (Group g : groupsImIn) 
    idsThatGiveMeAccess.add(g.getId()); 

List<Long> authorIdsThatIWantToSee = new ArrayList<Long>(); 
//Add a bunch of authorIds 

Query q = new Query("Content") 
      .addFilter("authorId", Query.FilterOperator.IN, authorIdsThatIWantToSee) 
      .addFilter("sharedWith", Query.FilterOperator.IN, idsThatGiveMeAccess); 

Очевидно, я уже сломаны несколько правил. А именно, использование двух фильтров IN взорвется. Даже один фильтр IN любого размера, приближающийся к пределам, о которых мы говорим, взорвется. Помимо всего этого, допустим, я хочу ограничить и пропустить результаты ... нет! Вы не можете этого сделать, если используете фильтр IN.Я не могу придумать какой-либо способ сделать эту операцию в одном запросе, что означает, что вы не можете разбивать ее на страницы без большой обработки времени на чтение и управления несколькими курсорами.

Итак, вот инструменты, которые я могу придумать для этого: денормализация, очертание или отношения. Однако даже с этими понятиями я не вижу, как можно моделировать эти данные таким образом, чтобы они могли масштабироваться. Очевидно, это возможно. Google и другие делают это все время. Я просто не понимаю, как это сделать. Может ли кто-нибудь пролить свет на то, как смоделировать это или указать мне на любые хорошие ресурсы для управления доступом в стиле cms на базе NoSQL DB?

ответ

1

хранение списка идентификаторов как свойства не будет масштабироваться. Почему бы просто не сохранить новый объект для каждого нового отношения? (Как в sql). Этот объект будет хранить для ваших cms два свойства: идентификатор общего элемента и идентификатор пользователя. Если его общий доступ к 1000 пользователям, у вас будет 1000 из них. Запросить его для данного пользователя тривиально. Разрешения листинга для данного элемента или список того, что пользователь поделил с ними, тоже легки.

Смежные вопросы