2010-02-10 9 views
5

Giả sử chúng tôi có một trang web phổ biến. Chúng ta cần phải thực hiện nhắn tin giống như thư giữa người dùng. giải pháp điển hình là sử dụng 2 bảng:Cơ sở dữ liệu MySQL có thể mở rộng để nhắn tin giống như thư

Người dùng (user_id)

Tin nhắn (message_id, sender_id (tài liệu tham khảo user_id), receiver_id (tài liệu tham khảo user_id), chủ đề, cơ thể).

Phương pháp này có 2 hạn chế đáng kể

  1. Tất cả thông điệp của tất cả người dùng được lưu trữ trong một bảng dẫn đến nó tải cao và làm giảm hiệu suất cơ sở dữ liệu tổng thể.
  2. Khi ai đó cần gửi tin nhắn cho nhiều người dùng cùng lúc, tin nhắn sẽ được sao chép (recipient_count) lần.

Các giải pháp khác sử dụng 3 bảng:

Người dùng (user_id)

Sent_messages (sent_id, sender_id (tài liệu tham khảo user_id), chủ đề, cơ thể)

Received_messages (sent_id, receiver_id (tham chiếu user_id), chủ đề, nội dung)

chủ đề và nội dung của received_messages được sao chép từ các trường tương ứng của sent_messages.

Phương pháp này dẫn đến

  1. Denormalizing cơ sở dữ liệu bằng cách sao chép thông tin từ một bảng khác
  2. Người dùng thực sự có thể delete gửi/nhận tin nhắn mà không loại bỏ chúng ra khỏi máy thu/người gửi.
  3. Tin nhắn mất khoảng 2 lần nhiều không gian
  4. Mỗi bảng được tải ít hơn khoảng 2 lần.

Vì vậy, đây đi các câu hỏi:

  1. Mà một trong những thiết kế được coi là tốt hơn cho tải cao và khả năng mở rộng? (Tôi nghĩ nó là cái thứ hai)
  2. Có thiết kế cơ sở dữ liệu nào khác có thể xử lý tải cao không? Nó là gì? Những hạn chế là gì?

Cảm ơn!

P.S. Tôi hiểu rằng trước khi đến các vấn đề về khả năng mở rộng này, trang web phải rất thành công, nhưng tôi muốn biết phải làm gì nếu cần.

CẬP NHẬT

Hiện nay đối với các phiên bản đầu tiên tôi sẽ sử dụng thiết kế bởi Daniel Vassallo đề xuất.Nhưng nếu mọi thứ đều ổn trong tương lai, thiết kế sẽ được thay đổi thành thứ hai. Cảm ơn Evert vì đã làm tôi lo lắng về điều đó.

Trả lời

3

Bạn có thể muốn tránh sao chép nội dung thư nhiều lần trong trường hợp thư được gửi tới nhiều người nhận. Dưới đây là một lựa chọn mà bạn có thể muốn xem xét:

  • người dùng (user_id)

  • điệp (message_id, sender_id, chủ đề, cơ thể)

  • received_messages (message_id, user_id, address_mode, deleted)

Mô hình này có thể giống twitter giống như email nhưng có thể có một số lợi thế.

Các quy tắc được rằng:

  • Một thông điệp chỉ có thể được gửi bởi một người dùng, tham chiếu trong sender_id của mỗi tin nhắn.
  • Mỗi người nhận sẽ được xác định trong bảng received_messages. Trường address_mode có thể xác định xem thư được gửi trực tiếp đến người nhận hay CC hay có thể là BCC. Trường này rõ ràng là tùy chọn.
  • Thư đã xóa của người nhận sẽ đánh dấu cờ đã xóa trong bảng received_messages.
  • Tin nhắn được chuyển tiếp và trả lời cần phải được tạo lại với người gửi mới_id. Sau đó, nội dung thư có thể được sửa đổi.

Đây là một số trong những lợi thế:

  • này có không gian ít hơn so với hai lựa chọn được đề cập trong câu hỏi ban đầu, đặc biệt là nếu người dùng thông thường sẽ gửi tin nhắn đến nhiều người nhận.
  • Bộ nhớ đệm dễ dàng hơn của bảng thư, vì thư không bao giờ bị trùng lặp.
  • Người nhận xóa thư sẽ không xóa thông tin mà thư đã được gửi tới người dùng này. Nó sẽ đơn giản được đánh dấu là 'đã xóa' trong bảng received_messages.
  • Và bạn cũng có được một mô hình chuẩn hóa.

Đối với hầu hết các ứng dụng, nếu bạn sử dụng mức cô lập lạc quan với mô hình trên, bạn sẽ không gặp phải vấn đề về hiệu suất ngay cả khi bạn đang mong muốn trao đổi tin nhắn với tốc độ vài giây một giây. Nếu mặt khác, bạn đang mong đợi hàng trăm hoặc hàng ngàn tin nhắn mỗi giây, thì có thể thực sự là trường hợp để xem xét các tùy chọn khác.

+0

Cảm ơn!Tôi cũng xem thiết kế này. Trên thực tế sau khi đăng câu hỏi này tôi (về tinh thần :)) đã sửa đổi thiết kế đầu tiên thành Người dùng (user_id) Tin nhắn (message_id, sender_id, receiver_id, message_content_id) Message_content (message_content_id, subject, body) Vì vậy, cả hai thiết kế này đều tốt hơn đầu tiên (trong không gian thực hiện và hiệu suất bảng). Có lẽ câu hỏi về câu hỏi phải là một cái gì đó như: tốt hơn là lưu trữ tất cả thư trong một bảng hay sao chép chúng thành hai? Ảnh hưởng đến hiệu suất sẽ ảnh hưởng như thế nào? –

1

Trong kích thước cơ sở dữ liệu chung sẽ không có nhiều lo ngại. Tốc độ là quan trọng hơn nhiều.

Vì vậy, tôi sẽ bị cám dỗ để chọn tùy chọn hai. Cũng giống như bạn đã đề cập, nó làm cho những thứ như xóa tin nhắn dễ dàng hơn rất nhiều, và tôi khá chắc chắn đây là một cách rất phổ biến để làm điều này.