Derecelendirme sistemi için verimli MySQL tablo yapısı

5 Cevap php

Bu yazı, bu cevap bir soru takip şöyledir: Best method for storing a list of user IDs.

Ben Cletus'u ve normalleştirilmiş bir veritabanı yaklaşımı kullanarak Mehrdad afshari destansı tavsiye aldı. Aşağıdaki tablolarda doğru düzgün optimizasyonu için kurulur? Ben tür yeni MySQL verimliliği değilim, bu yüzden bu etkili olduğundan emin olmak istiyorum.

Bu bir oyun ve toplam oy sayısı için ortalama notunu bulmaya gelince de, ben sırasıyla aşağıdaki iki sorgu kullanmalıyım?

SELECT avg(vote) FROM votes WHERE uid = $uid AND gid = $gid;    
SELECT count(uid) FROM votes WHERE uid = $uid AND gid = $gid;

CREATE TABLE IF NOT EXISTS `games` (
  `id` int(8) NOT NULL auto_increment,
  `title` varchar(50) NOT NULL,
  PRIMARY KEY  (`id`)
) AUTO_INCREMENT=1 ;

CREATE TABLE IF NOT EXISTS `users` (
  `id` int(8) NOT NULL auto_increment,
  `username` varchar(20) NOT NULL,
  PRIMARY KEY  (`id`)
) AUTO_INCREMENT=1 ;


CREATE TABLE IF NOT EXISTS `votes` (
  `uid` int(8) NOT NULL,
  `gid` int(8) NOT NULL,
  `vote` int(1) NOT NULL,
  KEY `uid` (`uid`,`gid`)
) ;

5 Cevap

Bir oyun için ortalama oy: SELECT avg(vote) FROM votes WHERE gid = $gid;

Bir oyun için oy sayısı: SELECT count(uid) FROM votes WHERE gid = $gid;

Eğer herhangi bir kullanıcı veya oyun kimlikleri daha küçük daha sonra 0 Onları imzasız tamsayı yapabilir olmayacak gibi (int(8) unsigned NOT NULL).

Bir kullanıcı sadece bir birincil uid ve gid üzerinde tuşuna votes tablodaki yerine oluşturun, sonra bir oyun için tek bir oy yapabilirsiniz zorlamak istiyorsanız sadece normal bir dizin.

CREATE TABLE IF NOT EXISTS `votes` (
  `uid` int(8) unsigned NOT NULL,
  `gid` int(8) unsigned NOT NULL,
  `vote` int(1) NOT NULL,
  PRIMARY KEY (`gid`, `uid`)
) ;

Index gid İlk sıralanır böylece birincil anahtarın alanlarının sırası (ilk gid, sonra da uid) önemlidir. Bununla seçer için endeks özellikle yararlı kılan verilen bir gid. Tüm oy seçmek istiyorsanız, belirli bir kullanıcı sonra sadece uid ile başka bir dizin eklemek yaptı.

Özellikle yüksek yük ayarlarında tablo kilitleri performans öldürecek çünkü depolama motoru için InnoDB öneriyoruz. Okuma performansı için APC, Memcached veya başkalarını kullanan bir önbellek sistemi uygulayabilirsiniz.

Iyi görünüyor.

Ben users_id & kullanılabilir olurdu games_id yerine gid ve küresel kimliği ve benzersiz id gibi geliyor uid

Şimdiye kadar iyi görünüyor. Endeksleri ve yabancı anahtarları unutmayın. Benim durumumda en konular değil-so-iyi düşünülmüş tasarımları ama endeksleri ve yabancı anahtarların eksikliğinden ortaya çıkmaz.

Ayrıca, depolama motoru seçimi konusunda ben InnoDB kullanmamak için bir sebep (bir boy / makul karmaşık app) değil, sırf işlem semantik henüz görmedik.

Yapıyorsun sonunda ne olursa olsun, (Kullanıcıların büyük bir sayıda olan düşünmüyorsanız bile) Emin büyük bir veri-seti ile test yapmak

100.000 oyunları, 50.000 kullanıcı ve bir milyon oy üreten bir senaryo yazın. Biraz aşırı olabilir, ancak sorgular öğeleri bu sayı ile saat yapmayız, eğer bir sorun asla

Siz de bir voted_on (DATETIME) sütun eklemek isteyebilirsiniz. Bu şekilde, diyelim ki, belli bir zaman bir oyunun eğilim görebiliyordu, ya da sadece bir gün bir oy Spam oldu durumda, doğru bir istenmeyen oy silmek olabilir.