Ilias95 Δημοσ. 4 Αυγούστου 2015 Δημοσ. 4 Αυγούστου 2015 Ας πούμε ότι έχουμε μια υποθετική web εφαρμογή όπου οι χρήστες μπορούν να καταχωρούν τραγούδια και συχνά πυκνά χρειάζεται να ξέρουμε τον αριθμό των τραγουδιών που έχει καταχωρήσει κάθε χρήστης.Ποια είναι «σωστότερη» πρακτική και γιατί;- Να κρατάμε ξεχωριστή μεταβλητή στο μοντέλο/πίνακα του χρήστη την οποία θα αυξάνουμε κάθε φορά που ένα τραγούδι προστίθεται.- Όταν χρειαζόμαστε το νούμερο να κάνουμε ένα count query στην βάση;Ευχαριστώ.
groot Δημοσ. 5 Αυγούστου 2015 Δημοσ. 5 Αυγούστου 2015 Εάν κατάλαβα καλά τι λες, το 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'); 1
Ilias95 Δημοσ. 5 Αυγούστου 2015 Μέλος Δημοσ. 5 Αυγούστου 2015 (επεξεργασμένο) Μάλιστα.Καταλαβαίνω ότι μιας και μιλάμε για relational database το ορθόδοξο είναι να δηλώσω την κατάλληλη σχέση.Απλά η απορία που μου προκύπτει είναι ότι αν έχουμε ας πούμε βάσεις με 50k χρήστες και 500k τραγούδια, το 2ο query στη βάση (αυτό που περιέγραψες) δεν θα είναι πιο χρονοβόρο από ένα απλό query στον πίνακα του χρήστη για να πάρουμε την τιμή του πεδίου songs_number;Edit:Τώρα που σκέφτομαι τον κώδικα σε SQL, μάλλον το ίδιο θα είναι πάνω κάτω.Edit 2:Και ο τίτλος που έδωσα μάλλον δεν είναι σωστός, μιας και για query πρόκειται και στις δύο περιπτώσεις. Επεξ/σία 5 Αυγούστου 2015 από Ilias95
defacer Δημοσ. 5 Αυγούστου 2015 Δημοσ. 5 Αυγούστου 2015 Όταν το traffic είναι τόσο που δεν δημιουργεί πρακτικό πρόβλημα τότε πας με την θεωρητικά σωστότερη λύση που είναι η δεύτερη. Όταν αρχίσεις να έχεις πρόβλημα τότε κάνεις το πρώτο που επίσης είναι πολύ γνωστή και στάνταρ τακτική. Όταν το πρόβλημα λόγω load γίνει τεράστιο τότε κάνεις τελείως διαφορετικά πράγματα (π.χ. αποθηκεύεις την πληροφορία αυτή σε κάποια semi-permanent cache όπως Redis). 1
groot Δημοσ. 5 Αυγούστου 2015 Δημοσ. 5 Αυγούστου 2015 Χμ... Για πολύ load, θα πρότεινα ένα "pivot" το οποίο να γίνεται update σε κάθε insert από song. Η πρώτη λύση είναι εντελώς 2008..... Υ.Γ. Με laravel, δεν θα άλλαζες κάτι στον κώδικα για access της πληροφορίας. ΕντελώςΣχεδόν τίποτα. Για update παίζει να άλλαζες ελάχιστα... Σίγουρα θα άλλαζες τα models όμως.
Papakaliati Δημοσ. 5 Αυγούστου 2015 Δημοσ. 5 Αυγούστου 2015 Εάν κατάλαβα καλά τι λες, το 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, και δεν ήτανε καν αυτή η ερώτηση του.
groot Δημοσ. 5 Αυγούστου 2015 Δημοσ. 5 Αυγούστου 2015 Σωστά μεν όλα αυτά, αλλά ουσιαστικά του δίνεις μια λύση για php, laravel only. Φαντάζομαι ότι ήξερε πως να κάνει ένα select query, και δεν ήτανε καν αυτή η ερώτηση του. Το δέχομαι αλλά με τόσα threads για έτοιμα CMS στο παραδίπλα section... με έπιασε κάτι και είπα να διαφημίσω το Laravel! Anyway... θαρρώ πως απαντήθηκε η απορία του
defacer Δημοσ. 5 Αυγούστου 2015 Δημοσ. 5 Αυγούστου 2015 Για πολύ load, θα πρότεινα ένα "pivot" το οποίο να γίνεται update σε κάθε insert από song. Η πρώτη λύση είναι εντελώς 2008..... Όταν λες pivot σε εισαγωγικά τι ακριβώς εννοείς;
Papakaliati Δημοσ. 5 Αυγούστου 2015 Δημοσ. 5 Αυγούστου 2015 Το δέχομαι αλλά με τόσα threads για έτοιμα CMS στο παραδίπλα section... με έπιασε κάτι και είπα να διαφημίσω το Laravel! Anyway... θαρρώ πως απαντήθηκε η απορία του Καλά το laravel με 60% προτίμηση που έχει δεν χρειάζεται και ιδιαίτερη διαφήμιση. Επιπλέον θεωρώ ότι σε κάποιον που κάνει τα πρώτα του βήματα δεν πρέπει να ξεκινάει με orm λύσεις, επειδή έτσι δεν έχει όση τριβή με databases θα έπρεπε. Προσωπική άποψη πάντα,δεν υπάρχει σωστό ή λάθος.
Ilias95 Δημοσ. 5 Αυγούστου 2015 Μέλος Δημοσ. 5 Αυγούστου 2015 Ευχαριστώ για τις απαντήσεις.Έχω ήδη κάποια τριβή με rdbms, οπότε θα πάω με το built-in orm του django. 1
groot Δημοσ. 5 Αυγούστου 2015 Δημοσ. 5 Αυγούστου 2015 Όταν λες pivot σε εισαγωγικά τι ακριβώς εννοείς; Αυτό που εννοούσα αρχικά ήταν: users_songs: id, user_id, songs_count Αλλά... μετά δεν μου άρεσε και τόσο η ιδέα...
defacer Δημοσ. 5 Αυγούστου 2015 Δημοσ. 5 Αυγούστου 2015 Ε μα δεν έχει και πολύ νόημα να το κάνεις αυτό, εφόσον στο normalized schema έχεις κατάλληλα indexes το count που θα κάνεις είναι απειροελάχιστα αργό και το join που χρειάζεται είναι το ίδιο και στη normalized και στην περίπτωση που λες. Οπότε διαισθητικά περιμένω σχεδόν το ίδιο perf και στις δύο περιπτώσεις. Αν τα βάλεις όμως στο user table τότε γλυτώνεις το join πράγμα που παίζει πολύ μεγάλο ρόλο.
groot Δημοσ. 6 Αυγούστου 2015 Δημοσ. 6 Αυγούστου 2015 Ε μα δεν έχει και πολύ νόημα να το κάνεις αυτό, εφόσον στο normalized schema έχεις κατάλληλα indexes το count που θα κάνεις είναι απειροελάχιστα αργό και το join που χρειάζεται είναι το ίδιο και στη normalized και στην περίπτωση που λες. Οπότε διαισθητικά περιμένω σχεδόν το ίδιο perf και στις δύο περιπτώσεις. Αν τα βάλεις όμως στο user table τότε γλυτώνεις το join πράγμα που παίζει πολύ μεγάλο ρόλο. yy.... You are δεξιά.
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα