2011-09-20 41 views
26

Tôi đã tự hỏi cách facebook quản lý thiết kế cơ sở dữ liệu cho tất cả những thứ khác nhau mà bạn có thể "thích". Nếu chỉ có một điều để thích, điều này rất đơn giản, chỉ là một chìa khóa nước ngoài cho những gì bạn thích và một chìa khóa nước ngoài cho bạn là ai.Cấu trúc dữ liệu "giống như" của Facebook

Nhưng phải có hàng trăm bảng khác nhau mà bạn có thể "thích" trên facebook. Làm cách nào để lưu trữ các lượt thích?

Trả lời

24

Nếu bạn muốn đại diện cho loại cấu trúc này trong cơ sở dữ liệu quan hệ, thì bạn cần phải sử dụng một hệ thống phân cấp thường được gọi là kế thừa bảng. Trong kế thừa bảng, bạn có một bảng duy nhất xác định loại cha mẹ, sau đó con các bảng có khóa chính cũng là khóa ngoài quay lại cha mẹ.

Sử dụng ví dụ Facebook, bạn có thể có một cái gì đó như thế này:

User 
------------ 
UserId (PK) 

Item 
------------- 
ItemId (PK) 
ItemType (discriminator column) 
OwnerId (FK to User) 

Status 
------------ 
ItemId (PK, FK to Item) 
StatusText 

RelationshipUpdate 
------------------ 
ItemId (PK, FK to Item) 
RelationshipStatus 
RelationTo (FK to User) 

Like 
------------ 
OwnerId (FK to User) 
ItemId (FK to Item) 
Compound PK of OwnerId, ItemId 

Trong tính đầy đủ sự quan tâm, nó có giá trị lưu ý rằng Facebook không sử dụng một RDBMS cho các loại điều này. Họ đã chọn giải pháp NoSQL cho loại lưu trữ này. Tuy nhiên, đây là một cách để lưu trữ thông tin được kết hợp lỏng lẻo đó trong một RDBMS.

+0

Đó có thể là một giải pháp, tôi nghĩ rằng vấn đề là "mọi thứ" phải là một "Item" bởi vì điều gì sẽ xảy ra nếu bạn có một bảng không phải là một Item và một ngày nào đó bạn muốn một cái gì đó cho nó? Tôi nghĩ rằng đôi khi đơn giản hơn là tốt hơn, tại sao không tạo ra sự thừa kế ngược lại? giống như là cha mẹ và bạn có một bảng like_for_status với một FK để tình trạng, và like_for_photo, vv bạn có thể mở rộng nó dễ dàng cho bất kỳ bảng, và truy vấn của bạn cũng nhanh hơn. – Enrique

+0

+1, mặc dù tôi nghĩ bạn có nghĩa là ** Bảng mỗi loại ** hoặc TPT. – Yuck

+0

@Yuck: Có, TPT (thay vì Bảng-Mỗi phân cấp), mặc dù TPT và TPH, theo như tôi biết, một phần của từ vựng Khung thực thể chứ không phải là SQL tổng quát hơn. –

0

Bạn có thể có bảng có Id, ForeignId và Type. Loại có thể là bất kỳ thứ gì như Ảnh, Trạng thái, Sự kiện, v.v ... ForeignId sẽ là id của bản ghi trong Loại bảng. Điều này có thể làm cho cả nhận xét và lượt thích. Bạn chỉ cần một bảng cho tất cả các lượt thích, một cho tất cả các nhận xét và bài bình luận mà tôi đã mô tả.

Ví dụ:

Items 
Id | Foreign Id | Type 
----+-------------+-------- 
    1 |   322 | Photo 
    4 |   346 | Status 

Likes 
Id | User Id  | Item Id 
----+-------------+-------- 
    1 |   111 | 1 

Ở đây, người dùng với Id 111 thích ảnh với Id 322.


Lưu ý: Tôi giả sử bạn đang sử dụng một RDBMS, nhưng xem câu trả lời Adron của. Facebook không không sử dụng RDBMS cho hầu hết dữ liệu của họ.

+0

Nhưng sau đó bạn không thể sử dụng hạn chế trong "Id Ngoại" – Enrique

+0

@Enrique bạn có thể xây dựng? Có những hạn chế chắc chắn về những gì có thể và không thể được thi hành trong một mẫu kế thừa bảng sử dụng các ràng buộc RI, nhưng nó không rõ ràng những gì bạn đang nói đến. –

+0

@Adam Robinson Cột "Foreign_Id" trong bảng "Items" không phải là FK thực, vì bạn không thể trỏ nó vào bất kỳ bảng nào, vì nó trỏ đến nhiều bảng thực sự (tùy thuộc vào cột "Loại"), vì vậy bạn không thể đặt một FK (và do đó một hạn chế) ở đó. Điều đó có thể làm cho dữ liệu của bạn không nhất quán. – Enrique

2

Facebook không có khóa ngoại truyền thống và như vậy, vì chúng không sử dụng cơ sở dữ liệu quan hệ cho hầu hết lưu trữ dữ liệu của chúng. Đơn giản, họ không cắt nó vì điều đó.

Tuy nhiên, họ sử dụng một số kho lưu trữ dữ liệu loại NoSQL. "Giống như" có nhiều khả năng được phân bổ dựa trên một dịch vụ, có thể được thiết lập theo cách thức kiểu SOA trong toàn bộ cơ sở hạ tầng của họ. Bằng cách này, "Like" về cơ bản có thể được quy cho bất cứ điều gì họ muốn nó được liên kết với. Tất cả điều này, với khả năng mở rộng rộng lớn và không có vấn đề quan hệ chặt chẽ chặt chẽ để giải quyết. Một cái gì đó mà Facebook, không thể thực sự đủ khả năng để đối phó với khối lượng họ hoạt động.

Họ cũng có thể sử dụng cơ chế xử lý kiểu AOP (Aspect Oriented Programming) để "đính kèm" một "Thích" vào bất kỳ thứ gì có thể cần một lúc hiển thị trang, nhưng tôi nhận được khái niệm rằng nó là xử lý không đồng bộ qua JavaScript chống lại một dịch vụ web kiểu SOA hoặc cơ chế phân phối khác.

Dù bằng cách nào, tôi cũng muốn nghe cách họ tự thiết lập cài đặt này từ góc độ kiến ​​trúc. Xem xét khối lượng của chúng, ngay cả nút "Like" đơn giản cũng trở thành một công nghệ đáng kể.

+0

-1. "Họ không cắt nó vì điều đó" là vấn đề về ý kiến ​​và nhiều suy đoán. Phần duy nhất của câu trả lời này thực sự giải quyết câu hỏi (những thứ như thế có thể được lưu trữ) là đoạn thứ hai của bạn. –

+0

+1 @adam, thực tế công nghệ đơn giản, không có ý kiến ​​liên quan. RDBMS được thiết kế cho một mô hình sử dụng khác nhau. –

+0

Giống như @StephanEggermont tuyên bố Adam họ là cho một mô hình khác nhau, một mục đích khác nhau, Facebook cần nhiều hơn nữa. Tôi không suy đoán và cộng đồng cơ sở dữ liệu chung, và cộng đồng khoa học, đồng ý. Đó là lý do giải pháp khác tồn tại. #justsayin Đối với xác nhận của bạn ở trên, các phím không được căn chỉnh theo cách đó. Đó là một cách làm việc cho một RDBMS, nhưng RDBMS không thể cung cấp hoặc xử lý dữ liệu mà Facebook xử lý. Facebook đã không thử và thả RDBMS chỉ vì họ muốn viết một cái gì đó khác. – Adron

-5

Tôi chắc rằng Facebook không lưu trữ thông tin "như" như cách một số người khác đề xuất nó bằng RDBMS. Với hàng triệu người dùng và có thể hàng nghìn lượt thích, chúng tôi đang xem xét hàng nghìn hàng để tham gia ở đây sẽ ảnh hưởng đến hiệu suất.

Cách tiếp cận tốt nhất ở đây là nối thêm tất cả "lượt thích" trong một hàng. Ví dụ, một bảng với cột user_like_id của kiểu dữ liệu văn bản. Sau đó, tất cả id của những người thích bài viết được nối thêm. Trong trường hợp này, bạn chỉ truy vấn một hàng và bạn có mọi thứ. Điều này sẽ nhanh hơn rất nhiều so với việc tham gia các bảng và nhận được số lượng.

EDIT: Gần đây tôi chưa ở đây trên trang web này và tôi vừa phát hiện ra câu trả lời này đã được giảm giá. Vâng, đây là example post with like count and their avatars. Đây là thiết kế của tôi, nơi tôi chỉ thực hiện những gì tôi đang nói về.

Hai thành phần ở đây là 1.) Bảng XREF và 2.) Đối tượng JSON.

Các lượt thích vẫn được lưu trữ trên bảng XREF. Nhưng đồng thời, dữ liệu được nối thêm vào đối tượng JSON và được lưu trữ trên một cột văn bản trên bảng đăng bài.

Tại sao tôi lưu trữ thông tin thích trên cột văn bản dưới dạng JSON? Vì vậy, không cần phải tìm kiếm/tham gia db cho các lượt thích. Nếu ai đó không giống như bài đăng, đối tượng JSON chỉ được cập nhật.

Bây giờ tôi không biết tại sao câu trả lời này lại bị một số người dùng bỏ phiếu ở đây. Câu trả lời này cung cấp truy xuất dữ liệu nhanh chóng. Điều này gần với phương pháp NoSQL, đó là cách truy cập dữ liệu FB. Trong trường hợp này, không cần phải tham gia thêm/tra cứu để nhận thông tin về lượt thích.

Và đây là bảng chứa các lượt thích. Nó chỉ là một ánh xạ XREF đơn giản giữa bảng người dùng và mục.

enter image description here

+0

sau đó làm thế nào để bạn biết 'có bao nhiêu người thích điều này'? truy vấn tất cả các hàng trong bảng người dùng? – Wint

+0

giải pháp tồi tệ nhất;) – Pars

+0

@Pars trả lời tồi tệ nhất;) – Ross

Các vấn đề liên quan