2014-06-05 4 views
0

소셜 네트워킹 웹 사이트를 구현하고 있으며 알림을 구현하려고합니다.소셜 네트워킹 웹 사이트에서 알림을 처리하는 방법

알림은 다음과 같은 요구 사항

  • 모든 사용자는 ... 등, 사용자가 게시물과 같은 특정 이벤트 (변경 프로필 사진을, 어떻게 수행 할 때마다 알림을받을 게시물을 작성, 댓글을 떠나이
  • 알림은 상태를 읽거나 사용자에 대한 통지의 집합 읽지 않은 경우. 다음 페이스 북처럼 사용자가 자신의 네비게이션 바에서

다음을 읽기 알림 아이콘이 표시 계속 (페이스 북 및 유래 등) 읽지 않은 입니다. 오우 내가 MySQL과 그것을 구현하는 생각입니다 :

알림 테이블 : type_of_event, event_id, message Notification_read 테이블 : user_id, notification_id, 사용자가 알림을 트리거하는 이벤트를 수행 할 때마다 read

  • 모든 추종자에게 을 전송하면 그 알림은 Notification 테이블에 저장됩니다.
  • 새 알림의 ID가 &이고 알림을 수신해야하는 각 사용자의 ID (알림 작성자의 팔로워)
  • 사용자가 알림을 수신하고 읽을 때마다 알림을 수신 할 때마다 Notification_read 테이블이 작성됩니다 매번 통지, 통지가 notification_read 테이블에 여러 번 기록 될 것이다 발생하기 때문에 read

이 솔루션으로 표시됩니다은 수

(사용자가 얼마나 많은 추종자에 따라) 나에게 정말 비효율적 인 것 같습니다 어어 이 문제에 대한 더 나은 해결책이 있는지 말해주십시오.

답변

5

이러한 종류의 문제로 트레이드 오프는 종종 읽기와 쓰기로 읽혀집니다.

이 경우 알림은 데이터베이스에 알림을 저장하는 데 걸리는 시간과 저장 비용으로 표현할 수 있습니다.

읽기의 경우 특정 사용자에 대한 알림을 얼마나 빨리 얻을 수 있는지에 대한 것입니다.

@kecebongsoft의 예제에서는 상대적으로 적은 수의 필드이기 때문에 쓰기가 매우 효율적이지만 읽기에는 많은 시간이 걸립니다. 데이터베이스의 텍스트 필드에서 검색하는 것은 종종 느립니다. 사용자의 경우 사용자가 나열되어 있으면 모든 알림과 해당 검사 필드를 검사해야하며, 그렇다면 상태는 무엇인지 검사해야합니다.

각 사용자에 대해 별도의 알림을 저장하면 저장 용량은 늘어나지 만 독서면에서는 많은 이익을 얻습니다. 즉, 사용자 ID를 사용하여 인덱싱 된 테이블을 검색하고 모든 알림 및 해당 상태를 신속하게 찾을 수 있기 때문입니다.

물론 복잡한 하이브리드 방법이 있습니다. 하지만 일반적으로 큰 웹 사이트는 그 비밀을 말하고 싶지 않습니다 :)

사이트로 시작하는 경우 필자는 비용을 걱정하지 않을 것입니다. 많은 알림이 포함 된 표를 채우는 것은 그리 비싸지 않습니다. 결국 그들은 모두 상대적으로 작을 것입니다. 오래된 알림을 제거하는 것에 대해서 생각할 수도 있습니다.

더 중요한 것은 읽는 속도입니다. 귀하의 사이트를 발견 한 사람들은 귀하의 효율적인 스토리지 어댑터에 깊은 인상을받지는 않지만 알림을받을 때 조명 속도에 주목할 것입니다.

내 조언 : 이제는 읽기 속도에 중점을두고 스토리지 효율성에 대해 걱정할 필요가있을 때.

마지막주의 사항 : 알림을 작성할 때 많은 데이터베이스 항목을 만드는 경우 주 웹 서버 스레드에서 전달하는 솔루션을 살펴보십시오. 그렇게하면 알림을 작성하는 사람이 빨리 계속할 수 있으며 백그라운드에서 값 비싼 SQL 작업을 수행 할 수 있습니다. 더 빠른 속도!

0

has_many through 연관을 사용할 수 있습니다. 이 상황에 완벽하게 맞을 것입니다. 또한 모델 알림 belongs_to :event을 만들 수 있으며 이벤트 유형을 이벤트 모델에 저장해야합니다. 자세한 내용은 다음을 참조하십시오. http://guides.rubyonrails.org/association_basics.html

+0

이벤트가 동일한 모델에 저장되지 않습니다.나는'Like','Post','Comment' 등과 같은 것들을위한 별도의 모델을 원합니다. 또한, 저는 has_many를 할 수 있다는 것을 알고 있지만, 실제로 많은 중복을 저장해야합니다 (has_many를 통해 notification_read를 사용하거나, 또는 알림에 모두 저장). 사용자가 간단한 일정을 수행하고 팔로어가 1,000 명인 경우 모든 작은 이벤트에 대해 1,000 개의 새 레코드가 있기 때문에 그리고 사건은 자주 일어날 것입니다. – user2158382

2

이벤트의 수신자를 직렬화하여 필드에 저장할 수 있습니다. 그렇게하면 추종자가 아무리 많아도 한 가지 사건에 대한 통보가 항상 하나가됩니다.

Actor ObjectType ObjectID Date  Recipients 
-------------------------------------------------------------------------------------- 
UserA Post   1   2014-03-02 [ 
              {'u': 1, 'r': False, 'dr': None}, 
              {'u': 2, 'r': True, 'dr': '2013-03-02'}, 
              {'u': 3, 'r': False, 'dr': None}, 
              {'u': 4, 'r': False, 'dr': None}, 
              ] 
UserB Photo   2   2014-03-02 [ 
              {'u': 4, 'r': False, 'dr': None}, 
              {'u': 5, 'r': True, 'dr': '2013-03-02'}, 
              {'u': 6, 'r': False, 'dr': None}, 
              {'u': 8, 'r': False, 'dr': None}, 
              ] 

u

r는 읽기 플래그이며, dr 읽기의 날짜입니다, 수신자 ID입니다. 이렇게하면 많은 I/O를 수행 할 필요없이 일부 조회 (예 : ShowBuilder에 대한 알림 표시)를 수행 할 수 있지만, 사용자는 알림을 후 처리하기 위해 도우미 클래스를 만들어야 만합니다. LOC 및 CPU 자원.

하지만 이렇게하기 전에 '비효율적 인'우려에 대해 다시 생각해보십시오.그렇다면 적절한 색인 생성이 문제가되지 않아야합니다. 적절한 인덱싱 및 쿼리가 있으면 MySQL 및 Postgres와 같은 데이터베이스가 수백만 (심지어 수천만)의 행을 올바르게 처리 할 수 ​​있습니다. 관심사가 글쓰기에 관한 것이라면,이를 배경 작업으로 넣고 사용자가 프로세스에 의해 차단되지 않고 계속 활동하도록 할 수 있습니다. 위의 솔루션을 사용하면 I/O가 적어 질 수 있지만 특히 나중에 기능을 다시 보거나 확장하려는 경우 단순함이 희생됩니다.

0

JMS, STOMP, AMQP, MQTT와 같은 프로토콜을 사용하여 일반적으로 비동기 메시징 중개자 및 ActiveMQ, RabbitMQ 등과 같은 프로토콜을 사용하는 대규모 사이트는 계속 진행됩니다. 그리고에.

어쨌든, 각 사용자 세션에 해당 사용자 알림 대기열에 가입 된 메시지 수신기가 있다는 것을 어떻게 구현할 것입니까? 문제의 프로토콜에 따라 정확히 어떻게 할지를 결정할 수 있지만, 가장 간단한 방법은 모든 사용자가 자신의 큐를 확보하는 것입니다. 메시지 브로커는 이러한 목적으로 관계형 데이터베이스보다 훨씬 빠른 파일 시스템과 저널 파일의 조합을 통해 메시지 지속성을 처리하는 경향이 있습니다 (이 데이터는 관계형이 아닙니다).

Ruby이고 JRuby를 사용하고 있다고 말하지 않았으므로, 다른 메시징이 STOMP 또는 MQTT에 더 적합 할 수 있습니다.

관련 문제