Προς το περιεχόμενο

Προτεινόμενες αναρτήσεις

Δημοσ.

Ας πούμε ότι έχουμε μια υποθετική web εφαρμογή όπου οι χρήστες μπορούν να καταχωρούν τραγούδια και συχνά πυκνά χρειάζεται να ξέρουμε τον αριθμό των τραγουδιών που έχει καταχωρήσει κάθε χρήστης.

Ποια είναι «σωστότερη» πρακτική και γιατί;

- Να κρατάμε ξεχωριστή μεταβλητή στο μοντέλο/πίνακα του χρήστη την οποία θα αυξάνουμε κάθε φορά που ένα τραγούδι προστίθεται.
- Όταν χρειαζόμαστε το νούμερο να κάνουμε ένα count query στην βάση;

Ευχαριστώ.
 

Δημοσ.

Εάν  κατάλαβα καλά τι λες, το 2ο. 

 

Θα έχεις στην βάση ένα table (π.χ.) users με ό,τι μπορεί να χρειαστείς για έναν user. 

 

Στο table songs, θα έχεις ένα πεδίο "user_id" και (optional) με comment "ID of the user who added the song". 

 

Το ποιος έβαλε το song είναι attribute του song αλλά και οι users έχουν songs. Οπότε, foreign key στο table songs. 

 

 

Με Laravel (π.χ.), μπορείς να βρεις αυτό που θες με μία γραμμή κώδικα (εάν έχεις φτιάξει σωστά τα relations):

$songs_amount = Auth::user()->songs->count();

Επίσης και πάλι με Laravel/Blade, εάν έχεις τα τραγούδια του χρήστη στο view σου κάνεις:

@foreach(Auth::user->songs as $song)
The song {{ $song->name }} added by {{ $song->user->name }} on {{ $song->created_at }}
@endforeach

ή

@foreach(Auth::user->songs as $song)
{{ trans('songs.entry', [ 'songname' => $song->name, 'useradd' => $song->user->name, 'on' => $song->created_at]) }}
@endforeach

και τελείωσες... στην 2η case έχεις και translation έτοιμο. 


Υ.Γ. Εάν δε, δουλέψεις και με RESTFul API, με μία γραμμή έχεις αυτόματα όλα τα routes για τα τραγούδια ανά χρήστη, με σωστό matching με μεθόδους του Controller και με αυτόματο τρόπο (dependency injection βασικά) τα url segments που σε νοιάζουν στον Controller (π.χ. userid, songid κτλ)... π.χ.

Routes::resource('user.songs', 'SongsController');
  • Like 1
Δημοσ. (επεξεργασμένο)

Μάλιστα.
Καταλαβαίνω ότι μιας και μιλάμε για relational database το ορθόδοξο είναι να δηλώσω την κατάλληλη σχέση.

Απλά η απορία που μου προκύπτει είναι ότι αν έχουμε ας πούμε βάσεις με 50k χρήστες και 500k τραγούδια, το 2ο query στη βάση (αυτό που περιέγραψες) δεν θα είναι πιο χρονοβόρο από ένα απλό query στον πίνακα του χρήστη για να πάρουμε την τιμή του πεδίου songs_number;

Edit:
Τώρα που σκέφτομαι τον κώδικα σε SQL, μάλλον το ίδιο θα είναι πάνω κάτω.

Edit 2:
Και ο τίτλος που έδωσα μάλλον δεν είναι σωστός, μιας και για query πρόκειται και στις δύο περιπτώσεις.

Επεξ/σία από Ilias95
Δημοσ.

Όταν το traffic είναι τόσο που δεν δημιουργεί πρακτικό πρόβλημα τότε πας με την θεωρητικά σωστότερη λύση που είναι η δεύτερη.

 

Όταν αρχίσεις να έχεις πρόβλημα τότε κάνεις το πρώτο που επίσης είναι πολύ γνωστή και στάνταρ τακτική.

 

Όταν το πρόβλημα λόγω load γίνει τεράστιο τότε κάνεις τελείως διαφορετικά πράγματα (π.χ. αποθηκεύεις την πληροφορία αυτή σε κάποια semi-permanent cache όπως Redis).

  • Like 1
Δημοσ.

Χμ...

 

Για πολύ load, θα πρότεινα ένα "pivot" το οποίο να γίνεται update σε κάθε insert από song. 

 

 

Η πρώτη λύση είναι εντελώς 2008.....

 

 

Υ.Γ. Με laravel, δεν θα άλλαζες κάτι στον κώδικα για access της πληροφορίας. ΕντελώςΣχεδόν τίποτα. Για update παίζει να άλλαζες ελάχιστα... Σίγουρα θα άλλαζες τα models όμως. 

Δημοσ.

 

Εάν κατάλαβα καλά τι λες, το 2ο.

 

Θα έχεις στην βάση ένα table (π.χ.) users με ό,τι μπορεί να χρειαστείς για έναν user.

 

Στο table songs, θα έχεις ένα πεδίο "user_id" και (optional) με comment "ID of the user who added the song".

 

Το ποιος έβαλε το song είναι attribute του song αλλά και οι users έχουν songs. Οπότε, foreign key στο table songs.

 

 

Με Laravel (π.χ.), μπορείς να βρεις αυτό που θες με μία γραμμή κώδικα (εάν έχεις φτιάξει σωστά τα relations):

$songs_amount = Auth::user()->songs->count();
Επίσης και πάλι με Laravel/Blade, εάν έχεις τα τραγούδια του χρήστη στο view σου κάνεις:
@foreach(Auth::user->songs as $song)
The song {{ $song->name }} added by {{ $song->user->name }} on {{ $song->created_at }}
@endforeach

ή
@foreach(Auth::user->songs as $song)
{{ trans('songs.entry', [ 'songname' => $song->name, 'useradd' => $song->user->name, 'on' => $song->created_at]) }}
@endforeach
και τελείωσες... στην 2η case έχεις και translation έτοιμο.

 

Υ.Γ. Εάν δε, δουλέψεις και με RESTFul API, με μία γραμμή έχεις αυτόματα όλα τα routes για τα τραγούδια ανά χρήστη, με σωστό matching με μεθόδους του Controller και με αυτόματο τρόπο (dependency injection βασικά) τα url segments που σε νοιάζουν στον Controller (π.χ. userid, songid κτλ)... π.χ.

Routes::resource('user.songs', 'SongsController');

Σωστά μεν όλα αυτά, αλλά ουσιαστικά του δίνεις μια λύση για php, laravel only. Φαντάζομαι ότι ήξερε πως να κάνει ένα select query, και δεν ήτανε καν αυτή η ερώτηση του.

Δημοσ.

Σωστά μεν όλα αυτά, αλλά ουσιαστικά του δίνεις μια λύση για php, laravel only. Φαντάζομαι ότι ήξερε πως να κάνει ένα select query, και δεν ήτανε καν αυτή η ερώτηση του.

 

 

Το δέχομαι αλλά με τόσα threads για έτοιμα CMS στο παραδίπλα section... με έπιασε κάτι και είπα να διαφημίσω το Laravel!

 

 

Anyway... θαρρώ πως απαντήθηκε η απορία του :P 

Δημοσ.

Για πολύ load, θα πρότεινα ένα "pivot" το οποίο να γίνεται update σε κάθε insert από song. 

 

 

Η πρώτη λύση είναι εντελώς 2008.....

 

Όταν λες pivot σε εισαγωγικά τι ακριβώς εννοείς;

Δημοσ.

Το δέχομαι αλλά με τόσα threads για έτοιμα CMS στο παραδίπλα section... με έπιασε κάτι και είπα να διαφημίσω το Laravel!

 

 

Anyway... θαρρώ πως απαντήθηκε η απορία του :P

Καλά το laravel με 60% προτίμηση που έχει δεν χρειάζεται και ιδιαίτερη διαφήμιση.

Επιπλέον θεωρώ ότι σε κάποιον που κάνει τα πρώτα του βήματα δεν πρέπει να ξεκινάει με orm λύσεις, επειδή έτσι δεν έχει όση τριβή με databases θα έπρεπε. Προσωπική άποψη πάντα,δεν υπάρχει σωστό ή λάθος.

Δημοσ.

Όταν λες pivot σε εισαγωγικά τι ακριβώς εννοείς;

 

 

Αυτό που εννοούσα αρχικά ήταν:

 

users_songs: id, user_id, songs_count

 

 

 

 

Αλλά... μετά δεν μου άρεσε και τόσο η ιδέα... 

Δημοσ.

Ε μα δεν έχει και πολύ νόημα να το κάνεις αυτό, εφόσον στο normalized schema έχεις κατάλληλα indexes το count που θα κάνεις είναι απειροελάχιστα αργό και το join που χρειάζεται είναι το ίδιο και στη normalized και στην περίπτωση που λες. Οπότε διαισθητικά περιμένω σχεδόν το ίδιο perf και στις δύο περιπτώσεις.

 

Αν τα βάλεις όμως στο user table τότε γλυτώνεις το join πράγμα που παίζει πολύ μεγάλο ρόλο.

Δημοσ.

Ε μα δεν έχει και πολύ νόημα να το κάνεις αυτό, εφόσον στο normalized schema έχεις κατάλληλα indexes το count που θα κάνεις είναι απειροελάχιστα αργό και το join που χρειάζεται είναι το ίδιο και στη normalized και στην περίπτωση που λες. Οπότε διαισθητικά περιμένω σχεδόν το ίδιο perf και στις δύο περιπτώσεις.

 

Αν τα βάλεις όμως στο user table τότε γλυτώνεις το join πράγμα που παίζει πολύ μεγάλο ρόλο.

 

 

yy....

 

You are δεξιά. 

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...