#android #firebase #firebase-realtime-database #nosql
#Android #firebase #firebase-realtime-база данных #nosql
Вопрос:
Я все еще на Firebase, и на этот раз у меня есть вопрос, связанный с удалением объектов.
У меня есть структура, подобная следующей:
users: {
UsErId1:{
name: "Jack",
email: "m@i.l"
},
UsErId2: { },
UsErId3: { }
},
user_contacts: {
UsErId1:{
UsErId2: true,
UsErId3: true
},
UsErId2: {
UsErId1: true
}
}
Поэтому, если я хочу удалить пользователя, я должен:
- Удаление пользовательского объекта
- Удалите объект user в ветке user_contacts
- Удалите все индексы из user_contacts, которые указывают на этого пользователя
Мои проблемы с производительностью возникают из пункта 3, потому что мне нужно перебрать все записи user_contacts, чтобы узнать, присутствует ли пользователь в дочерних элементах.
Пример кода выглядит следующим образом:
private void deleteUser(String userId) {
firebaseDatabase.getReference("users").child(userId).removeValue();
firebaseDatabase.getReference("users_contacts").child(userId).removeValue();
firebaseDatabase.getReference("users_contacts").addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot usersSnapshot : dataSnapshot.getChildren()) {
for( DataSnapshot contactSnapshot : usersSnapshot.getChildren() ){
String contactId = contactSnapshot.getValue(String.class);
if( contactId.equals(userId) ){
contactSnapshot.getRef().removeValue();
}
}
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
Я подумал о двух возможных решениях:
-
Решение 1: не удаляйте индексы из
user_contacts
, и когда мне нужно загрузить пользовательские контакты, я должен позвонить каждому пользователю, чтобы узнать, является ли пользователь null (был удален), и в этом случае не показывайте его. Кстати, это приводит к загрязнению базы данных. -
Решение 2. создайте обратный индекс
contacts_users
, в котором я сохраняю пользователей, на которых ссылается пользователь, которого я пытаюсь удалить. Как показано ниже:contacts_user: { UsErId1: { UsErId2: true }, UsErId2: { UsErId1: true }, UsErId3: { UsErId1: true } }
Итак, когда мне нужно удалить пользователя, я посмотрю на его дочерние contacts_users
элементы и узнаю всех пользователей, у которых он есть в контактах, и приступлю к его удалению (теперь, когда я могу знать весь путь). Мне кажется, это более похожий на NoSQL подход.
Что вы думаете? Есть ли другой способ сделать это?
Ответ №1:
Ваше второе решение — это то, как я бы предложил это сделать, не нужно искать. Вы можете хранить эту информацию для каждого пользователя, но если она становится слишком большой, лучше использовать ее в другом месте.
Аналогично, удаление в другом направлении также становится проще.
Комментарии:
1. То же самое здесь: всякий раз, когда вам нужно выполнить цикл filter, вам, вероятно, лучше создать обратный индекс.