Yayınları beğenir veya oylar


10

Kullanıcıların yayın yaptığı veya blog yazdığı küçük bir program yapıyorum. Bu yayınlarda, diğer kullanıcılar gönderiyi facebook'ta olduğu gibi beğenebilir veya beğenmeyebilir veya yığını stackoverflow'daki gibi yükseltebilir veya küçültebilir. Ben yaygın olarak kullanılan iyi bir veritabanı yapısı bilmek istiyorum & program bu yapı ile verimli çalışır. İki seçeneğim var

İlk

İleti:

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

Yukarıdaki şekilde, idpostid. Sütunu sever olarak, 1,2,3beğendiği veya yazı veya blog upvoted kullanıcının kimliğidir. 7,55,44,3yayını veya blog'u beğenmeyen veya reddeden kullanıcıların kimliği.

İkinci

İleti:

id    head  message   datepost
1     ab    anchdg     DATE

Seviyor:

id    postid    userid
1       1         1
2       2         2

Beğenmeme

id    postid    userid
1       1         7
2       1         55

Bu şekilde, gönderilerin beğenilerini almak için beğeniler ve beğenmemeler için iki ayrı tablo oluşturmam gerekiyor. Bu şekilde, tablolar yani Likes& Dislikesyoğun doldurulur. Bu, tablonun ağır ve işlenmesini yavaşlatabilir.

Peki, bu görevi yerine getirmenin en iyi ve standart yolunun hangisi olduğunu bilmek istiyorum


4
Bir kullanıcının bir gönderiyi beğenemeyeceğini ve beğenmediğini varsayıyorum ? Eğer öyleyse, bir BIT sütunu ile (beğenme için 1, beğenmeme için 0) bir beğeni ve beğenmeme için bir tablo olurdu.
dwjv

1
Veya daha kolay toplamlar için 1 ve -1
jkavalik

1
@dwjv İlk örnekte, kullanıcı 3 aslında yayını sevdi ve sevmedi.
Dan Henderson

Yanıtlar:


20

Karşılaştığınız sorun veritabanlarının "Normal formları", özellikle de ilk normal form olarak bilinir. https://en.wikipedia.org/wiki/First_normal_form .

Birleştirilmiş kullanıcı kimliklerine (ilk sürüm) sahip veritabanınız ilk normal formda değil.

Normalleştirmenin neden iyi ve genel olarak iyi kabul edildiği konusunda https://en.wikipedia.org/wiki/Database_normalization adresine bakın .

İlk örneğinizde, "kullanıcı 4 artık yayını sevmiyor" sorgusu karmaşık hale geliyor. Yan etkileri ve köşe durumlarını dikkate alması gereken dize işlemleri yapmak zorunda kalacak (kullanıcı tek "beğenen" kullanıcı, kullanıcı son beğenen kullanıcı, kullanıcı beğenen kullanıcı dizesinin ortasında). Bunu kötü bulurdum. Yapma. Normalleştirilmiş bir tasarım kullanın.

re: veritabanı ağırlaşıyor

4 milyon beğeni olan bir yazınız varsa, veritabanı tasarımı 1'de en az 4 milyon karakter genişliğinde bir "beğeniler" sütununa sahip bir satırınız olacaktır (çünkü ayırıcı karakter olarak virgül kullanmanız gerekir). Daha sonra, dört milyon haneli geniş dizelerde dize işlemleri gerçekleştirmeniz gerekecektir. Bu çok sağlam ve yavaş.

Öte yandan, veritabanları milyonlarca satırı işlemek için tasarlanmıştır. Birkaç yüz milyon sıralı veritabanlarımız var ve count () - işlemler hızlı. Son derece hızlı. Yani hayır, bu bir performans darboğazı olmayacak.

Bir sonraki konu okunabilirlik ve sürdürülebilirlik olacaktır.

Örneğin, bu 2 ifadenin ne yaptığını söyle:

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

Bahsettiğim gibi, eğer masaya crores veya milyarlarca beğeni gelirse, masa ağır olmaz mı? Tablo çok hızlı doldurulacağından, kayıtların yer aldığı bir tabloyu aramak fazla zaman almaz mı?
Harshit Shrivastava

6
@HarshitShrivastava mysql, milyar satırlık basit tabloları işleyebilir, ancak bu milyar (dis) beğenilerinizi kullanıcı tablonuzda dizeler olarak hayal edin - bu daha da büyük ve çalışması zor olabilir.
jkavalik

3
@Til_b'in doğrudan bahsetmediği bir şey (ancak normal formların kullanılmasıyla ima edilir), düzgün bir şekilde uygulanan ikinci tasarımın, alttaki veritabanı motorunun, ilk tasarım deseni ile yapılamayan referans bütünlüğünü korumasına izin vermesidir. Bu, Kullanıcı 4 silinirse, hangi kayıtların Kullanıcı 4 kaydına bağlı olduğunu bildiğinden, veritabanı bağlantılı verileri temizleyeceği anlamına gelir. Veritabanı dize ilişkisinin nasıl yönetileceğini sezgisel olarak bilmediğinden, ilk tasarım bunu yapamaz.
David Antaramian

9

İkinci yol çok daha iyidir çünkü kolayca beğen / beğenme ekleyebilir veya kaldırabilirsiniz.

Ancak ikinci çözümünüzü, beğenme veya beğenmeme için bir tablo kullanarak değiştirmeniz gerekir.
Benzer / beğenmeme tablosunun sütunları id, postid, userid ve beğen veya beğenmeme değeri için başka bir sütun, örneğin beğenmeme için 1 ve beğenme için -1 olmalıdır.

Post_id ve user_id öğelerini bileşik birincil anahtar olarak ayarlayın ve sorunsuz çalışır.

Tablonun boyutu zamanla büyüyecektir. ancak içinde sadece iki gerçek sütun var. Beğen / beğenmeme kimliği ve değeri. Postid ve userid yalnızca ona bağlıdır ve kullanıcı ve posta tablonuzda saklanır.


3
Sen sahip olmalıdır user_id, post_idve valuetabloda. Ayrı bir idsütuna gerek yok .
jkavalik

3
@ Jkavalik'in önerdiği soru üzerine yorum yaptığı gibi, 1 ve -1 muhtemelen 1 ve 2'den hoşlanma ve beğenmeme için daha iyi değerler olacaktır, çünkü toplam sayının basit bir tablo toplamı yoluyla hesaplanmasını çıkarmak yerine basit bir tablo toplamıyla hesaplanmasını sağlayacaktır. "1" olan satırların sayısından "2" olan satırlar.
Dan Henderson

@DanHenderson: Beğeniler - beğenmeme gibi bir şey bir miktardan biraz daha hızlı olabilir. (Bununla birlikte, 1 ve -1 ile de işe yarayacağını söyledi.)
cHao

oy verildi, aşk ve öfke gibi 2 eylem daha söyleseydin bunu nasıl yapardın? 2 daha fazla eylem ile beğeniler için 1 ve beğenmeme için -1 demek
PirateApp

sumHiçbir şey istemiyorsanız aşk = 2 ve öfke = 3 ayarlayabilirsiniz
Julian S
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.