Lượt thích hoặc bình chọn cho bài viết


10

Tôi đang làm một chương trình nhỏ nơi người dùng tạo bài đăng hoặc viết blog. Trên các bài đăng đó, những người dùng khác có thể thích hoặc không thích bài đăng như trong facebook hoặc upvote hoặc downvote bài đăng như trong stackoverflow. Tôi muốn biết một cấu trúc cơ sở dữ liệu tốt thường được sử dụng và chương trình hoạt động hiệu quả với cấu trúc đó. Tôi có hai lựa chọn

Đầu tiên

Bài đăng:

id   head   message   datepost   likes   dislikes
1     ab    anchdg     DATE      1,2,3   7,55,44,3

Theo cách trên, idlà postid. Trong cột thích, 1,2,3là id người dùng thích hoặc nâng cấp bài đăng hoặc blog. 7,55,44,3là id của người dùng không thích hoặc đánh giá thấp bài đăng hoặc blog.

Thứ hai

Bài đăng:

id    head  message   datepost
1     ab    anchdg     DATE

Thích:

id    postid    userid
1       1         1
2       2         2

Không thích:

id    postid    userid
1       1         7
2       1         55

Theo cách này, tôi phải tạo hai bảng riêng biệt cho lượt thích & không thích để có lượt thích bài đăng. Theo cách này, các bảng tức là Likes& Dislikessẽ được lấp đầy. Điều này có thể làm cho bảng nặng và xử lý chậm.

Vì vậy, tôi muốn biết đâu là cách tốt hơn & tiêu chuẩn để đạt được nhiệm vụ này?


4
Tôi cho rằng người dùng không thể thích không thích bài đăng? Nếu vậy, tôi có một bảng cho thích và không thích, với cột BIT (1 cho thích, 0 cho không thích).
dwjv

1
Hoặc 1 và -1 để tính tổng dễ dàng hơn
jkavalik

1
@dwjv Trong ví dụ đầu tiên, trên thực tế, người dùng 3 có cả thích không thích bài đăng.
Dan Henderson

Câu trả lời:


20

Vấn đề bạn gặp phải được gọi là "Các dạng thông thường" của cơ sở dữ liệu, đặc biệt là dạng bình thường đầu tiên. https://en.wikipedia.org/wiki/First_n normal_form .

Cơ sở dữ liệu của bạn với ID người dùng được nối (phiên bản đầu tiên) không ở dạng bình thường đầu tiên.

Xem https://en.wikipedia.org/wiki/Database_n normalization để biết lý do và cách thức chuẩn hóa thường được coi là tốt.

Trong ví dụ đầu tiên của bạn, truy vấn "người dùng 4 không thích bài đăng nữa" trở nên phức tạp. Nó sẽ phải thực hiện các thao tác chuỗi, sẽ phải xem xét các tác dụng phụ và các trường hợp góc (người dùng là người dùng "thích" duy nhất, người dùng là người dùng thích cuối cùng, người dùng ở giữa chuỗi người dùng thích). Tôi sẽ tìm thấy điều này xấu. Đừng làm điều đó. Sử dụng một thiết kế chuẩn hóa.

re: cơ sở dữ liệu trở nên nặng nề

Nếu bạn có một bài đăng có 4 triệu lượt thích, trong thiết kế cơ sở dữ liệu 1, bạn sẽ có một hàng với cột "thích" rộng tối thiểu 4 triệu ký tự (vì bạn sẽ cần dấu phẩy dưới dạng ký tự ngăn cách). Sau đó, bạn sẽ phải thực hiện các thao tác chuỗi trên chuỗi rộng bốn triệu chữ số. Điều này rất không phù hợp và chậm.

Mặt khác, cơ sở dữ liệu được thiết kế để xử lý hàng triệu hàng. Chúng tôi có cơ sở dữ liệu với hàng trăm triệu hàng và hoạt động đếm () - hoạt động nhanh. Vô cùng nhanh chóng. Vì vậy, không, đây sẽ không phải là một nút cổ chai hiệu suất.

Vấn đề tiếp theo sẽ là khả năng đọc và bảo trì.

Ví dụ, cho tôi biết 2 câu lệnh này làm gì:

select count(*)
from posts
inner join likes on posts.postid = likes.postid
where postid = 7

select len(likes) - len(replace(likes, ',', ''))
from posts
where postid = 7

Như tôi đã đề cập, nếu các lõi hoặc hàng tỷ lượt thích xuất hiện trong bảng, thì bàn có trở nên nặng không? Sẽ không mất nhiều thời gian để tìm kiếm một bảng có các bản ghi vì bảng sẽ được điền rất nhanh?
Harshit Shrivastava

6
@HarshitShrivastava mysql có thể xử lý các bảng đơn hàng tỷ hàng, nhưng hãy tưởng tượng hàng tỷ lượt thích đó là các chuỗi trong bảng người dùng của bạn - điều đó có thể còn lớn hơn và khó làm việc hơn.
jkavalik

3
Một điều @til_b không đề cập trực tiếp (nhưng thường được ngụ ý thông qua việc sử dụng các biểu mẫu thông thường) là thiết kế thứ hai, được triển khai đúng cách, sẽ cho phép công cụ cơ sở dữ liệu cơ bản duy trì tính toàn vẹn tham chiếu không thể thực hiện được với mẫu thiết kế đầu tiên. Điều đó về cơ bản có nghĩa là, nếu Người dùng 4 bị xóa, cơ sở dữ liệu sẽ xóa dữ liệu được liên kết vì nó biết bản ghi nào phụ thuộc vào bản ghi Người dùng 4. Thiết kế đầu tiên không có khả năng này vì cơ sở dữ liệu không trực giác biết cách quản lý mối quan hệ trong chuỗi.
David Antaramian

9

Cách thứ hai tốt hơn nhiều vì bạn có thể dễ dàng thêm hoặc xóa lượt thích / không thích.

Nhưng bạn nên sửa đổi giải pháp thứ hai của mình bằng cách sử dụng một bảng để thích hoặc không thích.
Các cột của bảng like / dislike phải là id, postid, userid và một cột khác cho giá trị của một lượt thích hoặc không thích, ví dụ 1 cho không thích và -1 cho lượt thích.

Đặt post_id và user_id làm khóa chính tổng hợp và nó hoạt động tốt.

Kích thước của bảng sẽ phát triển theo thời gian. nhưng bạn chỉ có hai cột thực sự trong đó. Id và giá trị của thích / không thích. Postid và userid chỉ được liên kết với nó và được lưu trữ trong bảng người dùng và bài đăng của bạn.


3
Bạn nên có user_id, post_idvaluetrong bảng. Không cần một idcột riêng .
jkavalik

3
Như nhận xét của @ jkavalik về câu hỏi được đề xuất, 1 và -1 có thể là giá trị tốt hơn cho thích và không thích hơn 1 và 2, vì nó sẽ cho phép tính tổng số điểm bằng cách tính tổng của bảng đơn giản, thay vì trừ đi tổng số các hàng có "2" từ số hàng có "1".
Dan Henderson

@DanHenderson: Một cái gì đó giống như thích - không thích có thể nhanh hơn một chút so với một khoản tiền. (Tuy nhiên, điều đó nói rằng nó cũng sẽ hoạt động với 1 và -1.)
cHao

được khuyến khích, bạn sẽ làm điều này như thế nào nếu bạn nói thêm 2 hành động như yêu và giận? ý tôi là 1 cho thích và -1 cho không thích với 2 hành động nữa
PirateApp

Nếu bạn không muốn sumbất cứ điều gì bạn có thể đặt tình yêu = 2 và tức giận = 3
Julian S
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.