Suka atau suara untuk posting

10

Saya membuat program kecil di mana pengguna membuat posting atau menulis blog. Pada postingan tersebut, pengguna lain dapat menyukai atau tidak menyukai postingan seperti di facebook atau menaikkan atau menurunkan postingan seperti pada stackoverflow. Saya ingin tahu struktur database yang baik yang biasa digunakan & program bekerja secara efisien dengan struktur itu. Saya punya dua opsi

Pertama

Pos:

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

Dengan cara di atas, idadalah postid. Di kolom suka, 1,2,3adalah id pengguna yang menyukai atau meningkatkan posting atau blog. 7,55,44,3adalah id dari pengguna yang tidak menyukai atau menurunkan posting atau blog.

Kedua

Pos:

id    head  message   datepost
1     ab    anchdg     DATE

Suka:

id    postid    userid
1       1         1
2       2         2

Tidak suka:

id    postid    userid
1       1         7
2       1         55

Dengan cara ini, saya harus membuat dua tabel terpisah untuk suka & tidak suka untuk mendapatkan suka posting. Dengan cara ini, yaitu tabel Likes& Dislikesakan sangat diisi. Ini mungkin membuat tabel berat & pemrosesan lambat.

Jadi, saya ingin tahu mana cara yang lebih baik & standar untuk mencapai tugas ini?

Harshit Shrivastava
sumber
4
Saya berasumsi bahwa pengguna tidak dapat menyukai dan tidak menyukai pos? Jika demikian, saya akan punya satu meja untuk suka dan tidak suka, dengan kolom BIT (1 untuk suka, 0 untuk tidak suka).
dwjv
1
Atau 1 dan -1 untuk jumlah yang lebih mudah
jkavalik
1
@dwjv Pada contoh pertama, pengguna 3, pada kenyataannya, menyukai dan tidak menyukai posting.
Dan Henderson

Jawaban:

20

Masalah yang Anda hadapi dikenal sebagai "Bentuk normal" dari database, terutama bentuk normal pertama. https://en.wikipedia.org/wiki/First_normal_form .

Databse Anda dengan ID pengguna gabungan (versi pertama) tidak dalam bentuk normal pertama.

Lihat https://en.wikipedia.org/wiki/Database_normalization untuk alasan dan bagaimana normalisasi umumnya dianggap baik.

Dalam contoh pertama Anda, kueri untuk "pengguna 4 tidak menyukai pos lagi" menjadi rumit. Ini harus melakukan operasi string, yang harus mempertimbangkan efek samping dan kasus sudut (pengguna adalah satu-satunya "menyukai" pengguna, pengguna adalah pengguna yang menyukai yang terakhir, pengguna berada di tengah-tengah string pengguna yang menyukai). Saya akan menemukan ini buruk. Jangan lakukan itu. Gunakan desain yang dinormalisasi.

re: basis data semakin berat

Jika Anda memiliki posting yang memiliki 4 juta suka, dalam desain basis data 1 Anda akan memiliki satu baris dengan kolom "suka" dengan lebar minimal 4 juta karakter (karena Anda akan memerlukan koma sebagai karakter pemisah). Anda kemudian harus melakukan operasi string pada empat juta digit string lebar. Ini sangat tidak berkinerja dan lambat.

Di sisi lain, basis data dirancang untuk menangani jutaan baris. Kami memiliki basis data dengan beberapa ratus juta baris, dan hitung () - operasi cepat. Sangat cepat. Jadi tidak, ini tidak akan menjadi hambatan kinerja.

Masalah selanjutnya adalah keterbacaan dan pemeliharaan.

Misalnya, beri tahu saya apa yang dilakukan 2 pernyataan ini:

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
til_b
sumber
Seperti yang saya sebutkan, jika crores atau milyaran suka hadir di meja, maka tidak akan menjadi berat? Tidakkah butuh banyak waktu untuk mencari meja dengan crores catatan karena tabel akan terisi sangat cepat?
Harshit Shrivastava
6
@HarshitShrivastava mysql dapat menangani tabel sederhana dari miliaran baris, tetapi bayangkan milyaran tersebut (dis) suka sebagai string di tabel pengguna Anda - yang mungkin bahkan lebih besar dan sulit untuk dikerjakan.
jkavalik
3
Satu hal yang @til_b tidak sebutkan secara langsung (tetapi biasanya tersirat melalui penggunaan bentuk normal) adalah bahwa desain kedua, diimplementasikan dengan benar, akan memungkinkan mesin basis data untuk mempertahankan integritas referensial yang tidak dapat dilakukan dengan pola desain pertama. Itu pada dasarnya berarti, jika Pengguna 4 dihapus, basis data akan menghapus data tertaut karena tahu catatan mana yang bergantung pada catatan Pengguna 4. Desain pertama tidak mampu melakukan ini karena database tidak secara intuitif tahu bagaimana mengelola hubungan dalam string.
David Antaramian
9

Cara kedua jauh lebih baik karena Anda dapat dengan mudah menambah atau menghapus suka / tidak suka.

Tetapi Anda harus memodifikasi solusi kedua Anda dengan menggunakan satu tabel untuk suka atau tidak suka.
Kolom dari tabel suka / tidak suka harus berupa id, postid, userid dan lainnya untuk nilai suka atau tidak suka misalnya 1 untuk tidak suka dan -1 untuk suka.

Tetapkan post_id dan user_id sebagai kunci primer komposit dan berfungsi dengan baik.

Ukuran meja akan bertambah seiring waktu. tetapi Anda hanya memiliki dua kolom nyata di dalamnya. Id dan nilai suka / tidak suka. Postid dan userid hanya ditautkan dan disimpan dalam tabel posting dan pengguna Anda.

Julian S
sumber
3
Anda harus memiliki user_id, post_iddan valuedi atas meja. Tidak perlu idkolom terpisah .
jkavalik
3
Seperti komentar @ jkavalik pada pertanyaan yang disarankan, 1 dan -1 mungkin akan menjadi nilai yang lebih baik untuk suka dan tidak suka dari 1 dan 2, karena itu akan memungkinkan perhitungan skor total dengan cara jumlah tabel sederhana, daripada mengurangi jumlah baris dengan "2" dari hitungan baris dengan "1".
Dan Henderson
@DanHenderson: Sesuatu seperti suka - tidak suka bisa sedikit lebih cepat dari jumlah. (Meski begitu, itu juga bisa digunakan dengan 1 dan -1.)
cHao
terbalik, bagaimana Anda melakukan ini jika Anda mengatakan 2 tindakan lagi seperti cinta dan kemarahan? maksud saya 1 untuk suka dan -1 untuk tidak suka dengan 2 tindakan lebih
PirateApp
Jika Anda tidak ingin sumapa pun, Anda dapat menetapkan cinta = 2 dan kemarahan = 3
Julian S