Как выбирать в базе данных уникальные значения, сравнивая два массива?

База данных имеет таблицу "Контакты", в которой ~100.000 строк.
Пользователям №1 и 2 принадлежит по 1000 строк (контактов) из этой таблицы.
Примерно 30% контактов этих пользователей совпадают (то есть это одни и те же строки из таблицы "Контакты").

Нужно сделать так, чтобы пользователь №1 получил список тех контактов пользователя №2, которых нет у пользователя №1.

Пользователь №1 может быстро добавлять себе контакты пользователя №2, после чего список не совпадающих контактов нужно обновлять.

Какую базу данных для этого использовать и как это правильно реализовать?
Мне не приходит в голову ничего, кроме простых регулярных функций. Но вот проблема, если у этих пользователей по 10.000 контактов и 90% из них совпадает, то регулярная функция уже будет тяжела. А если добавлять к каждому контакту список пользователей, у которых есть этот контакт, то проблемы будут, когда 1000+ пользователей добавят этот контакт, так как придется каждый раз запрашивать полный список пользователей, имеющих этот контакт, добавлять еще одного пользователя и сохранять потом все это.
С NoSQL не работал, но если это то, что мне нужно - то я изучу это.
  • Вопрос задан
  • 438 просмотров
Решения вопроса 1
romy4
@romy4
Exception handler
решается например в посгресе внешним джойном
select *
from contacts c1
outer join contacts c2 on c1.id=c2.id
where c1.user_id=x and c2.user_id=y
Ответ написан
Пригласить эксперта
Ответы на вопрос 4
@lega
Нужно сделать так, чтобы пользователь №1 получил список тех контактов пользователя №2, которых нет у пользователя №1

В монге можно использовать $ne и $nin

Пример:
> db.x.insert({ name: 'linux', user_id: [1] })
> db.x.insert({ name: 'unix', user_id: [2] })
> db.x.insert({ name: 'ubuntu', user_id: [1, 2] })
> db.x.insert({ name: 'windows', user_id: [3] })
> db.x.ensureIndex({user_id: 1})   //  Делаем индекс

Сам запрос: все документы пользователя 2, но там где нет пользователя 1
> db.x.find({ user_id: { $eq: 2, $ne: 1 }})
{ "_id" : ObjectId("56695f1e9349d7e6c71d83f1"), "name" : "unix", "user_id" : [ 2 ] }
Ответ написан
bingo347
@bingo347
Crazy on performance...
Самая простая реализация будет как раз таки на sql:
SELECT id, cotact_id FROM contacts
WHERE user_id = 2
AND id NOT IN (SELECT id FROM contacts
WHERE user_id = 1)
Ответ написан
Комментировать
@nozzy
Symfony, Laravel, SQL
select 
contact_id
from contacts
where 1=1
and user_id = 1
and contact_id not in (
	select 
	distinct contact_id
	from contacts
	where user_id = 2
)
Ответ написан
Комментировать
alex1t
@alex1t
.net developer
В T-SQL (MS SQL) можно через операции над множествами:
WITH User1Contacts AS (
    SELECT id as cotact_id FROM contacts  WHERE user_id = 1
),
User2Contacts AS (
    SELECT id as cotact_id FROM contacts  WHERE user_id = 2
)
SELECT * FROM User1Contacts 
EXCEPT
SELECT * FROM User2Contacts


INTERSECT наоборот выберет только общие контакты
UNION - объединение контактов обоих пользователей (без дубликатов)

Т.е. говоря языком операций над множествами
INTERSECT = A ∩ B
UNION = A U B
EXCEPT = A \ B
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы