|
Îåêßíçóå áðü ôï ìÝëïò gspiros. Τελευταία δημοσίευση από το μέλος gspiros στις 16-08-2008, 19:01. Υπάρχουν 16 απαντήσεις.
-
13-08-2008, 20:52
|
-
gspiros
-
-
-
Μέλος από τις 23-03-2007
-
-
Δημοσιεύσεις 170
-
-
|
Έστω ότι έχουμε ένα site, όπου κάποιος μπορεί να προσθέσει comments σε photos, σε άρθρα, σε εστιατόρια, σε ξενοδοχεία κτλ... Τα comments θα αποθηκεύονται στην βάση δεδομένων. Τι από τα παρακάτω είναι καλύτερο από άποψη ταχύτητας, αλλά και από άποψη καλύτερης οργάνωσης και ευκολότερου προγραμματισμού (και εδώ αναφέρομαι για τον κώδικα που θα τρέχει στον server, πχ C#)?
1) Ξεxωριστούς πίνακες για κάθε κατηγορία? πχ. CommentPhotos, CommentHotels κτλ, όπου κάθε πίνακας θα έχει σαν κολώνες τα: commentID, photoID (ή hotelID ή articleID - αναλλόγως ποιός πίνακας είναι), comment_text, date, userID. Τα photoID, hotelID, articleID κτλ θα γίνουν indexed, για μεγαλύτερη ταχύτητα κατά το ανάλογο SELECT.
Ένα πρόβλημα που έχει αυτή η περίπτωση είναι ότι θα πρέπει να γραψω την
ΙΔΙΑ συνάρτηση (πχ σε C#) που θα κάνει INSERT ή την ίδια Stored Procedure για κάθε
πίνακα, με μόνη διαφορά το όνομα του πίνακα... Επίσης θα έχω πολλούς πίνακες με διαφορετικά ονόματα, αλλά ίδιες ουσιαστικά κολώνες...
2) Ένα πίνακα για όλες τις κατηγορίες? πχ. Comments, όπου θα έχει για κολώνες τα: commentID, comment_text, date, userID, typeID, mainID όπου mainID θα είναι είναι το photoID, είτε το hotelID αναλόγος τι typeID έχουμε. όπου typeID θα είναι το ID ενός άλλου πίνακα όπου θα περιέχει όλες τις κατηγορίες πχ. πίνακας Types με κολώνες: typeID, typeName όπου typeName θα είναι photos, restaurants κτλ... Σε αυτήν την περίπτωση η κολώνα typeID θα έχει γίνει indexed, για μεγαλύτερη ταχύτητα κατά το ανάλογο SELECT.
Σε αυτήν την περίπτωση, πως θα διαλέγεται ποιό typeID έχουμε? Θέλω να πω, πως θα γνωρίζει το πρόγραμμα αν κάνουμε add comment σε photo ή αν κάνουμε add comment σε άρθρο?
Μπορώ να καταλάβω τα θετικά και αρνητικά κάθε περίπτωσης (τα περισσότερα τουλάχιστον), αλλά ποιά μέθοδος χρησιμοποιείται περισσότερο σε μεγάλες εφαρμογές? Προφανώς μιλάμε για πολλά δεδομένα και όχι για μερικά δεκάδες.
Υπάρχουν και άλλοι τρόποι?
|
|
-
13-08-2008, 22:22
|
|
Απ: Πολλοί πίνακες ή ένας?
Θα πρότεινα τον 2ο τρόπο ελαφρώς τροποποιημένο:
- Από τις στήλες που έχεις θα σβήσεις την typeID - το σχόλιο είναι σχόλιο, είναι ένα κείμενο που θα αφήσεις ένας επώνυμος ή ανώμυμος χρήστης. Δεν έχει να κάνει με την κατηγορία του item που αναφέρεται, αλλά μόνο με το mainID, δηλαδή το συγκεκριμένο item που σχολιάζεται.
Νομίζω ότι πλέον είναι εύκολο να καταλάβεις μπορείς να αποθηκεύσεις ένα σχόλιο και στην συνέχεια να βρεις τα σχετικά σχόλια με ένα item μέσα στον πίνακα - με την στήλη typeID και μόνο...
George J.
|
|
-
14-08-2008, 05:12
|
-
MakisCE
-
-

-
Μέλος από τις 26-01-2008
-
-
Δημοσιεύσεις 12
-
-
|
Απ: Πολλοί πίνακες ή ένας?
Γιώργο, ή δεν κατάλαβα καλά την απάντησή σου, ή υπάρχει το εξής πρόβλημα.
αν δεν έχουμε typeID, παρά μόνο mainID, τότε το mainID με value=1 ας πούμε, δεν θα ξέρουμε αν είναι το PhotoID=1, ή το hotelID=1, κλπ
σε παρόμοιο πρόβλημα, έχω 'κληρονομήσει' μια βάση που το λύνει με τον 2ο τρόπο του gspirou, αλλά πρέπει συνέχεια να βάζεις "WHERE typeID=3" (για Hotels ας πούμε) κλπ -- Ο πίνακας Types με κολώνες: typeID, typeName είναι σχεδόν προεραιτκός, απλά πληροφοριακός δεν μου είχε αρέσει αυτή η λύση...
ίσως επανέλθω με κάτι ποιο επικοδομητικό!
|
|
-
14-08-2008, 06:01
|
-
MakisCE
-
-

-
Μέλος από τις 26-01-2008
-
-
Δημοσιεύσεις 12
-
-
|
Απ: Πολλοί πίνακες ή ένας?
μια λύση (δεν ξέρω πόσο valid είναι) θα μπορούσε να είναι η εξής:
CommentableEntities -- id
Hotels -- CommentableEntityID, name, rooms, location, ...
Articles -- CommentableEntityID, title, content, publishDate, ...
Comments -- id, CommentableEntityID, userID, content, ...
Τοποθετούμε μια έξτρα ιεραρχία δηλαδή, όπου όλα τα entities που παίρνουν comments είναι CommentableEntities, και έτσι πάιρνουν ένα εννιαίο id (unique, auto), κι έτσι το schema είναι κάπως έτσι:
Comments <-- CommentableEntities <--> Hotels, Articles, etc
δεν έχω ιδέα πόσο στέκει το design αυτό, και λαμβάνοντας υπόψιν οτι ξημερώνει, δεν έχει και πολλές πιθανότητες
από τα enities (Hotels, κλπ) παίρνουμε κατευθείαν τα Comments (join στο CommentableEntityID), δεν ξέρω κατά πόσο θα είναι πονοκέφαλος στα insert ενός "CommentableEntity"
|
|
-
14-08-2008, 12:16
|
-
gspiros
-
-
-
Μέλος από τις 23-03-2007
-
-
Δημοσιεύσεις 170
-
-
|
Απ: Πολλοί πίνακες ή ένας?
Καλημέρα! Ο λόγος που έβαλα το typeID είναι ακριβώς αυτός που είπε ο MakisCE!
Βασικά θα ήθελα να ξέρω αν υπάρχουν και άλλα μειωνεκτήματα με αυτούς τους τρόπους. MakisCE, αν μπορείς εξήγησε λίγο περισσότερο το τελευταίο σου post, διότι με μπέρδεψες...
Εγώ σκοφτόμουν ότι ο 1ος τρόπος που ανέφερα είναι πιο γρήγορος και σίγουρα με αυτόν είναι πιο οργανωμένα τα δεδομένα, διότι έχουμε τα comments σε διαφορετικούσ πίνακες. Θα μπορούσα να γράψω μια συνάρτηση (ή stored procedure) όπου να παίρνει σαν όρισμα ένα string (όπως hotels, articles κτλ) κάπως έτσι: function mpla(string x) "INSERT INTO "+x+"VALUES ........" είναι όμως σωστός προγραμματισμός αυτός?
Με τον δεύτερο τρόπο, όλα είναι πιο αυτοματοποιημένα, αλλά και πάλι θα πρέπει να παιρνιέται μια παράμετρος string (όπως παραπάνω), αναλόγως αν κάνω add comment σε photo ή σε article. Έχει κανείς καμιά ιδέα?
|
|
-
14-08-2008, 14:13
|
|
Απ: Πολλοί πίνακες ή ένας?
Η δεν κατάλαβα καλά, ή δεν έχει ξεκαθαριστεί το ζητούμενο:
- Ωραία και έχω ένα σχόλιο. Τι είναι αυτό που με ενδιαφέρει σχετικά με το σχόλιο;
- Να μπορώ να βρω για ένα item σε σχέση με το mainID του τι σχόλια έχει;
- Να μπορώ να ξέρω πόσα σχόλια υπάρχουν σε κάθε κατηγορία;
- Να μπορώ να δω ξεκάρφωτα σχόλια;
- Υπάρχει κάτι άλλο που με ενδιαφέρει;
Δεν μπορώ να δω το λόγο που σώνει και καλά πρέπει να υπάρχει το typeID, με την προυπόθεση ότι κάθε τύπος έχει δικό table και όλα τα σχόλια ένα table...
George J.
|
|
-
14-08-2008, 14:34
|
-
gspiros
-
-
-
Μέλος από τις 23-03-2007
-
-
Δημοσιεύσεις 170
-
-
|
Απ: Πολλοί πίνακες ή ένας?
Λοιπόν, σε κάποια σελίδα πχ Photos.aspx υπάρχουν φωτογραφίες όπου κάποιος μπορεί να βάλει comments, σε κάποια άλλη σελίδα πχ Hotels.aspx (τα hotels είναι άσχετα με τις photos), κάποιος μπορεί να βάλει comments σε ξενοδοχεία, σε κάποια άλλη σελίδα υπάρχουν άρθρ, όπου κάποιος μπορεί να βάλει comments (τα άρθρα είναι άσχετα με τα ξενοδοχεία και τις φωτογραφίες...) κτλ.... Προφανώς όταν κάποιος ανοίγει κάποια σελίδα, εκτός από τις φωτογραφίες ή τα ξενοδοχεία κτλ, θα εμφανίζονται και τα comments που έχουν σχέση με το αντικείμενο που βλέπει (photo ή hotel ή article κτλ).
Αν τελικά χρησιμοποιήσουμε την δεύτερη μέθοδο, θα πρέπει να υπάρχει κάποιο ID, όπου να μας λέει ότι θέλουμε τα comments για photos (πχ ID=2) και επίσης ότι θέλουμε τα comments για την συγκεκριμένη photo (πχ photoID=3). Δεν μπορούμε να βάλουμε απλά ID=5, διότι μπορεί να υπάρχει photoID=5, αλλά και HotelID=5. Κάτι σαν 2 Keys σε ένα πίνακα (τον Comment). Ελπίζω να σε διαφώτησα...
Η βασική μου ερώτηση είναι πως μπορεί να υλοποιηθεί κάτι παρόμοιο. Ποιά είναι η καλύτερη μέθοδος?
|
|
-
14-08-2008, 14:54
|
-
cap
-
-

-
Μέλος από τις 14-01-2005
-
Βύρωνας, Αθήνα
-
Δημοσιεύσεις 2.750
-
-
|
Απ: Πολλοί πίνακες ή ένας?
Δεν υπάρχει, κατά την άποψή μου, καλύτερος και χειρότερος τρόπος, όλα εξαρτώνται από τις δυνητικές απαιτήσεις του περιβάλλοντος το οποίο θέλεις να υλοποιήσεις. Ας δούμε λίγο τα δεδομένα μας: Το πρόβλημά σου είναι οτι έχεις ένα μάτσο πίνακες με διάφορες οντότητες (ξενοδοχεία, φωτογραφίες κλπ) οπου, φυσικά, ο καθένας έχει primary key αλλά αυτό το primary key δεν είναι μοναδικό στο σύνολο των πινάκων, με αποτέλεσμα δυο διαφορετικές οντότητες (που εκφράζονται από δύο διαφορετικούς πίνακες) να ενδέχεται να έχουν το ίδιο primary key. Γι'αυτό και η λύση του να χρησιμοποιήσεις το id της οντότητας σε ένα και μοναδικό πίνακα που κρατάει τα σχόλια δεν είναι εφικτή. Οι πιθανές λύσεις είναι: 1. Αλλαγή του data type των primary keys των οντοτήτων που σε ενδιαφέρουν σε κάτι πραγματικά unique (uniqueidentifier ή ένα calculated field που θα προκύπτει από το identity αλλά θα παίρνει και κάποιο πρόθεμα ανάλογα με τον πίνακα - τζιζ). Αν έχεις ένα πραγματικα μοναδικό, database-wide primary key το οποίο δεν υπάρχει περίπτωση να επαναληφθεί πουθενά, τότε μπορείς να χρησιμοποιήσεις αυτό το key ως foreign key στον πίνακα των σχολίων σου και να υλοποιήσεις τα σχόλια με τη χρήση ενός και μόνο πίνακα. 2. Χρήση ενός πίνακα σχολίων για κάθε οντότητα που σχολιάζεται, στην ουσία δηλαδή "ζευγάρια" πινάκων - ενας για την οντότητα, ένας για τα σχόλια. Πρακτικό μεν, πολύ δουλειά όμως για τα διαφορετικά queries στα οποία τελικά αλλάζουν μόνο δύο ονόματα πινάκων, συν καθόλου ελαστικότητα στην περίπτωση προσθήκης νέων οντοτήτων στο σύστημα. 3. Χρήση ενός πίνακα σχολίων για όλες τις οντότητες, αλλά με αρκετές κολώνες που λειτουργούν σαν foreign keys, μια για κάθε οντότητα που έχεις στο σύστημά σου και μπορεί να σχολιαστεί. Πρακτικά επαρκές, ανελαστικό όμως όπως και το (2) συν το οτι έχεις λιγοστούς τρόπους να εξασφαλίσεις integrity αν τυχόν γραφτεί τιμή σε παραπάνω από ένα πεδίο σε ένα record. 4. Χρήση ενός πίνακα σχολίων για όλες τις οντότητες, με ένα επιπρόσθετο πεδίο το οποίο υποδεικνύει την οντότητα που αφορά η συγκεκριμένη γραμμή (και απαραίτητα ένα index εκεί επάνω). Π.χ. "H" για ξενοδοχεία, "P" για φωτογραφίες. Ετσι, ανάλογα με ποιά οντότητα ασχολείσαι, μπορείς να έχεις ένα WHERE στα queries σου του στυλ WHERE id=xxx AND type=y οπου θα είσαι σίγουρος οτι θα επιστρέφεται μόνο μια εγγραφή τη φορά. Ευέλικτο, ανοικτό στην προσθήκη νέων οντοτήτων, αλλά απαιτεί την αυθαίρετη παραδοχή οτι θα συμβολίζεις κάθε οντότητα με ένα "καρφωτό" σύμβολο (γραμμα, αριθμό κλπ). Προσωπικά, αν είχα τη δυνατότητα, θα προτιμούσα τη λύση (1), ενώ αν δεν την είχα λόγω συνθηκών θα προτιμούσα αμέσως μετά τη λύση (4).
Σωτήρης Φιλιππίδης DotSee Web Services
|
|
-
14-08-2008, 15:38
|
-
gspiros
-
-
-
Μέλος από τις 23-03-2007
-
-
Δημοσιεύσεις 170
-
-
|
Απ: Πολλοί πίνακες ή ένας?
Σας ευχαριστώ όλους!
Αυτό όμως που δεν έχω καταλάβει είναι ο τρόπος που πρότεινε ο MakisCE... Αν μπορείς εξήγησέ τον!
|
|
-
14-08-2008, 18:19
|
-
MakisCE
-
-

-
Μέλος από τις 26-01-2008
-
-
Δημοσιεύσεις 12
-
-
|
Απ: Πολλοί πίνακες ή ένας?
spiro, αυτό που πρότεινα, υλοποιεί στην ουσία αυτό που περιέγραψε και ο cap sto 1)
"Αν έχεις ένα πραγματικα μοναδικό, database-wide primary key το οποίο δεν υπάρχει περίπτωση να επαναληφθεί πουθενά, τότε μπορείς να χρησιμοποιήσεις αυτό το key ως foreign key στον πίνακα των σχολίων σου και να υλοποιήσεις τα σχόλια με τη χρήση ενός και μόνο πίνακα."
O CommentableEntities πίνακας , με πεδίο μόνο ένα ID, δίνει ένα database-wide primary key σε όσες οντότητες θέλουμε να παίρνουν comments.
αργότερα θα ανεβάσω κάπου κι ενα database diagram που είχα φτιάξει εχθές
|
|
-
14-08-2008, 18:23
|
-
gspiros
-
-
-
Μέλος από τις 23-03-2007
-
-
Δημοσιεύσεις 170
-
-
|
Απ: Πολλοί πίνακες ή ένας?
Αχαα, κατάλαβα! Απλά θα πρέπει το ID αυτού του πίνακα να αυξάνεται κάθε φορά που προσθέτουμε οτιδήποτε. Είναι πιο εύχρηστη αυτή η μέθοδος από την 4 του cap? Χρησιμοποιείται σε μεγάλες εφαρμογές?
|
|
-
14-08-2008, 18:35
|
-
MakisCE
-
-

-
Μέλος από τις 26-01-2008
-
-
Δημοσιεύσεις 12
-
-
|
Απ: Πολλοί πίνακες ή ένας?

σχεδιάγραμμα αυτού που πρότεινα
το 4) του cap το έχω χρησιμοποιήσει και μου έχει σπάσει τα νεύρα με τα where typeID=X Που πρέπει να βάζεις συνέχεια.
αυτό που προτείνω δεν το έχω χρησιμοποιήσει (!) πιθανόν να είναι μπελάς στο insert ενός Article/Hotel/etc, μιας και πρώτα πρέπει να μπει εγγραφή στο CommentableEntities και το ID Που θα πάρει εκεί, θα είναι το uniqueID (foreign key) στον Articles πχ.
Το δικό σου (1) πάντως (ξεχωριστοί Comments πίνακες για κάθε οντότητα), είναι κατά τη γνώμη μου το χειρότερο.. -- εντελώς αντίθετο από DRY (Dont repeat yourself) principles, και το βρίσκεις συνέχεια μπροστά σου να σου θυμίζει τη μ...ία επιλογή που έκανες! LOL
|
|
-
14-08-2008, 18:37
|
-
MakisCE
-
-

-
Μέλος από τις 26-01-2008
-
-
Δημοσιεύσεις 12
-
-
|
Απ: Πολλοί πίνακες ή ένας?
αλήθεια, υπάρχει άλλος τρόπος να έχεις "unique keys across (some) tables"? (χωρίς χρήση stored proc, triggers, κλπ)
-- edit--
απαντάω μόνος μου για να μη κάνω κι άλλο post
με χρήση GUID είναι ένας τρόπος έχει το κόστος του όμως, και είναι άσχημος αν πρέπει να εμφανίσεις το GUID, πχ. articles.aspx?id=7BE3D24CE5-F2A0-4B16-A39C-7AB17525F07C 
|
|
-
15-08-2008, 11:34
|
|
Απ: Πολλοί πίνακες ή ένας?
MakisCE:
με χρήση GUID είναι ένας τρόπος έχει το κόστος του όμως, και είναι άσχημος αν πρέπει να εμφανίσεις το GUID, πχ. articles.aspx?id=7BE3D24CE5-F2A0-4B16-A39C-7AB17525F07C 
Μπορείς να κάνεις και άλλα πράγματα:
- Για να φτάσεις σε μια εγγραφή πρέπει να έχεις ένα μοναδικό κλειδί. Σε αυτή την περίπτωση, αυτό που έχεις "έτοιμο και σερβιρισμένο" είναι το primary key του table σου. Αυτό δεν σε εμποδίζει να φτιάξεις ένα δεύτερο, ή ένα τρίτο μοναδικό κλειδί. Θα μπορούσες να χρησιμοποιήσεις ένα τίτλο, περιγραφή, για να φτιάξεις κάτι που είναι καλύτερα human readable unique key, και από το unique intendifier και από αριθμό. Είναι μια στάνταρντ τεχνική που όλο και περισσότερα weblog engines υιοθετούν τον τελευταίο καιρό...
George J.
|
|
-
15-08-2008, 12:48
|
-
MakisCE
-
-

-
Μέλος από τις 26-01-2008
-
-
Δημοσιεύσεις 12
-
-
|
Απ: Πολλοί πίνακες ή ένας?
Συμφωνώ και επαυξάνω
αν και η τάση είναι για [user|search]-friendly-urls που ενδείκνυνται για web εφαρμογές.. αλλά αυτό προχωράει ακόμα περισσότερο π.χ. /hotels.aspx?id=141 (int, OK) /hotels.aspx?id=7BE3D24CE5-F2A0-4B16-A39C-7AB17525F07C (guid, ugly) /hotels.aspx?hid=dotnetseaview (human readable unique key, made automatically or by human entry, better) /hotels/dotnetseaview (url rewriting, mvc frameworks & routing, nice & friendly)
οπότε μια καλή λύση είναι τα GUIDs, χωρίς έξτρα πίνακες, (μόνο Comments και Hotels/Articles/...) αρκεί να μπορείς να έχεις και custom κλειδιά
Η απορία μου παραμένει, αν αυτό που πρότεινα (βλ. διάγραμμα) έχει δυσκολία στο Insert
"πιθανόν να είναι μπελάς στο insert ενός Article/Hotel/etc, μιας και πρώτα πρέπει να μπει εγγραφή στο CommentableEntities και το ID Που θα πάρει εκεί, θα είναι το uniqueID (foreign key) στον Articles πχ."
|
|
Σελίδα 1 από 2 (17 εγγραφές)
1
|
|
|