Συζήτηση για σχεδιασμό βάσης που θα παρέχει στατιστικά στοιχεία πωλήσεων

Συζητήσεις για την βάση δεδομένων MySQL και το phpMyAdmin

Συντονιστές: WebDev Moderators, Super-Moderators

Απάντηση
alou
Script Master
Δημοσιεύσεις: 1374
Εγγραφή: 24 Αύγ 2007 19:52
Επικοινωνία:

Συζήτηση για σχεδιασμό βάσης που θα παρέχει στατιστικά στοιχεία πωλήσεων

Δημοσίευση από alou » 02 Ιούλ 2014 15:31

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

Η λογική είναι η εξής: υπάρχει ένα σταθερό κομμάτι της βάσης, με αρκετές χιλιάδες προϊόντα (30 περίπου) κατηγοριοποιημένα (4 επίπεδα κατηγορίας, brand, εταιρεία) που είναι πάντα το σημείο αναφοράς.

Ο χρήστης, μπορεί να κάνει εισαγωγή των raw πωλήσεών του (ημερομηνία, barcode, αξία, κόστος) από ένα excel.

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

πωλήσεις από τότε μέχρι τότε, σύνολο
πωλήσεις από τότε μέχρι τότε με σύγκριση 2 εταιρειών ή brand
πωλήσεις από τότε μέχρι τότε για την / τις τάδε κατηγορίες / υποκατηγορίες
κερδοφορία με οποιαδήποτε κριτήρια όπως τα παραπάνω

κλπ κλπ, τα οποία παρουσιάζονται σαν raw πίνακες και με διαγράμματα (μάλλον d3js).

Η ερώτηση είναι: αφού γίνει το raw import των στοιχείων πώλησης του χρήστη, τι πίνακες θα βόλευε να δημιουργηθούν αυτόματα - ή με ποια λογική να διαχωριστούν τα στοιχεία, ώστε να είναι σχετικά εύκολα τα queries για την άντληση των στοιχείων για τα παραπάνω στατιστικά? (άσχετα αν θα γίνουν cached κάποια από αυτά)

Άβαταρ μέλους
burnmind
Script Master
Δημοσιεύσεις: 954
Εγγραφή: 26 Σεπ 2009 02:14
Τοποθεσία: UK
Επικοινωνία:

Συζήτηση για σχεδιασμό βάσης που θα παρέχει στατιστικά στοιχεία πωλήσεων

Δημοσίευση από burnmind » 03 Ιούλ 2014 15:50

Κατ' αρχήν, θα βόλευε αν έβαζες το schema της βάσης που έχεις σχεδιάσει ώστε οποιαδήποτε απάντηση να έχει αυτό ως αναφορά.

Από εκεί και πέρα, πέρα από το θεωρητικό σχεδιασμό της βάσης, θα πρότεινα να δουλέψεις με δοκιμαστικά δεδομένα* ώστε να δεις πραγματικά τι βολεύει, τι bottlenecks υπάρχουν σε queries, κλπ, ώστε να κάνεις τις απαραίτητες αλλαγές πριν ολοκληρώσεις τη σχεδίασή της και φυσικά προτού φτάσεις στο production stage.

*Αν έχεις έστω και λίγα από τα προϊόντα και τις πωλήσεις θα είναι ό,τι καλύτερο, καθώς θα μπορέσεις να φτάσεις όσο πιο κοντά γίνεται σε πραγματικές συνθήκες. Αν πχ έχεις 1000 προϊόντα βάλε τα ίδια επί Χ φορές ώστε να φτάσεις (μη σου πω και να ξεπεράσεις κατά πολύ) τα 30 χιλιάδες προϊόντα που θα υπάρχουν υπό κανονικές συνθήκες και ακολούθησε την ίδια λογική με τα δεδομένα των πωλήσεων.
alou έγραψε:(...) ώστε να είναι σχετικά εύκολα τα queries για την άντληση των στοιχείων για τα παραπάνω στατιστικά? (άσχετα αν θα γίνουν cached κάποια από αυτά)
Τι εννοείς "εύκολα"; Να μην είναι πολύπλοκο στο να δημιουργηθούν προγραμματιστικά, ή κάτι άλλο;

alou
Script Master
Δημοσιεύσεις: 1374
Εγγραφή: 24 Αύγ 2007 19:52
Επικοινωνία:

Συζήτηση για σχεδιασμό βάσης που θα παρέχει στατιστικά στοιχεία πωλήσεων

Δημοσίευση από alou » 03 Ιούλ 2014 19:10

Thanks για την απάντηση burnmind, αυτό ακριβώς κάνω και παίζοντας προσπαθώ να δω τι βολεύει κάνοντας δοκιμαστικά queries.

Υπάρχουν ας πούμε 30.000 προϊόντα, με:
id--name--barcode--category--subcat--subsubcat--subsubsubcat--brand--etaireia
αυτό μπορεί να μείνει ώς έχει ή να σπάσει σε όσους πίνακες χρειάζεται.

Αυτά υπάρχουν ήδη μέσα στη βάση.

Ο χρήστης, κάνει εξαγωγή από το εμπορικό του πρόγραμμα ένα excel με
barcode--sale date--sale price--cost
και το εισάγει στην εφαρμογή.

Η κατάληξη είναι η εφαρμογή να μπορεί να παρουσιάσει οτιδήποτε report θα μπορούσε να του προσφέρει ο συνδυασμός αυτών των στοιχείων, είτε σε πίνακες είτε σε διαγράμματα.

Δηλαδή, τα raw στοιχεία πωλήσεών του, κατηγοριοποιούνται, μπαίνουν κάτω από brand / εταιρεία / κατηγοριοποίηση 4 επιπέδων και μπορεί να πατήσει να δει
σύγκριση coca cola με pepsi σε τεμάχια ή σε πωλήσεις ή σε κερδοφορία για ένα χρονικό διάστημα
σύγκριση φέτα με κασέρι όλα τα brand σε όλη τη χρονιά
κερδοφορία coca cola vs pepsi
και πάει λέγοντας

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

Σωτά λες βέβαια, το εύκολο δεν είναι αυτονόητο, εννοώ λιγότερο επίπονο για την βάση και κατ'επέκταση πιο γρήγορο συνολικά.

Εκείνο που προσπαθώ να διαμορφώσω αλλά δεν έχω καταλήξει, είναι να φτιάξω μια δομή που θα είναι η βέλτιστη για ότι φαντάζομαι πως θα είναι συνηθισμένο ερώτημα.

Πχ, σύγκρινε 2 κατηγορίες από 1/1/2014 έως 30/4/2014 σε τεμάχια, τζίρο και κερδοφορία
που οδηγεί σε ένα query:
$catA = βρές όλα τα barcode της Α κατηγορίας (από τα μόνιμα στοιχεία)
$catB = βρές όλα τα barcode της B κατηγορίας

Φέρε: τεμάχια, τζίρο, τζίρο - κόστος από τις πωλήσεις του χρήστη, όπου η ημερομηνία είναι 1/1/2014 έως 30/4/2014 και έχουν barcode IN ($catA), group by date κλπ
και αντίστοιχα για catB.

Έχω φτιάξει λοιπόν καμμία 10ριά τέτοια παραδείγματα διαφορετικών query και προσπαθώ με παραλλαγές στους πίνακες να δω ποια δομή θα ήταν η πιο αποδοτική σε χρόνο και πόρους.

Αν ξέρει κάποιος / σκέφτεται μια γενική λογική που θα μπορούσε να βοηθήσει σε μια τέτοια δομή ώστε να είναι όσο το δυνατόν πιο αποδοτική και λιγότερο επίπονη για τον server, θα ήμουν πολύ χαρούμενος να την ακούσω.

ΥΓ μόλις διάβαζα ένα ενδιαφέρον post για WAI-ARIA ;)

Άβαταρ μέλους
burnmind
Script Master
Δημοσιεύσεις: 954
Εγγραφή: 26 Σεπ 2009 02:14
Τοποθεσία: UK
Επικοινωνία:

Συζήτηση για σχεδιασμό βάσης που θα παρέχει στατιστικά στοιχεία πωλήσεων

Δημοσίευση από burnmind » 04 Ιούλ 2014 15:38

Σε θεωρητικό επίπεδο, πιστεύω πως σε καλύπτουν οι βασικοί πίνακες που περιέγραψες (με ένα καλύτερο normalisation που υποθέτω έχεις σκεφτεί ήδη). Γι' αυτό ρώτησα τι έχεις φτιάξει ήδη και αν έχεις κάνει δοκιμές, ώστε αν βρήκες συγκεκριμένο bottleneck να το συζητήσουμε, καθώς πιστεύω πως είναι δύσκολη ερώτηση για κάποιον που δεν έχει ασχοληθεί σε βάθος με τη συγκεκριμένη εφαρμογή.

Ας αναφέρω τη σχεδίαση που σκέφτηκα κι εγώ (χωρίς πολύ πολύ ανάλυση βέβαια, οπότε αν θεωρείς πως κάτι είναι λάθος ή δε σε βολεύει στην περίπτωσή σου μάλλον θα έχεις δίκιο :Ρ).

Products table: id (pk), name, barcode, brand_id (fk)*, company_id (fk), category_id (fk)**

*Θεωρώ πως τα brands, companies, categories έχουν δικούς τους πίνακες με πληροφορίες (τίτλους, κλπ).

**Για λόγους απλότητας και χωρίς να ξέρω τι παίζει με τη σχεδίαση των κατηγοριών σου, έχω βάλει πως το κάθε product ανήκει απλά σε μία κατηγορία και έχω βάλει το field εκεί, όπως έκανες με τα category, subcat, κλπ. Μερικές φορές ίσως βολεύει αυτή η λύση, αλλά σκέψου αν θα σε βόλευε καλύτερα ένας ενδιάμεσος πίνακας του στυλ: products_categories: product_id (pk, fk), category_id (pk, fk).

Sales table: id (pk)*, barcode (fk)**, sale_date, price, cost

*Θεωρώντας πως μπορεί να υπάρχουν sales με ακριβώς τα ίδια στοιχεία, δεν υπάρχει λόγος για primary keys, αλλά μια και μπορεί να χρειαστεί, λογικά θα έβαζα κάποιο auto-increment primary key.

**Εφόσον θα χρησιμοποιήσεις αυτό και όχι το product_id, να κάνεις index το barcode column και εδώ, αλλά και στον products table.

Με την παραπάνω σχεδίαση, αν θες για παράδειγμα να επιλέξεις τον τζίρο, το κόστος, και το κέρδος για κάθε product της κατηγορίας Χ για πωλήσεις που πραγματοποιήθηκαν τον προηγούμενο μήνα, γίνεται με το παρακάτω (πιθανό να έχει errors καθώς δεν το δοκίμασα κάπου):

Κώδικας: Επιλογή όλων

SELECT products.name, COUNT(sales.barcode), SUM(sales.price), SUM(sales.cost), SUM(sales.price) - SUM(sales.cost)
FROM products
LEFT JOIN sales
ON products.barcode = sales.barcode
WHERE products.category_id = 1 AND sales.sale_date BETWEEN '2014-06-01' AND '2014-06-30'
GROUP BY sales.barcode
Συνέχισε λοιπόν αυτό που σωστά κάνεις με τις δοκιμές ώστε να διαπιστώσεις αν κάποιο query έχει πρόβλημα απόδοσης, ώστε να εξετάσεις τις πιθανές λύσεις. Αν πχ πρέπει να κάνεις κάποια αλλαγή στη σχεδίασή σου (μερικές φορές ακόμα και το indexing ενός πίνακα μπορεί να επιφέρει τρομακτική βελτίωση σε ένα query), αν βολεύει να δημιουργήσεις κάποιον βοηθητικό πίνακα που θα μαζεύει υπολογισμούς που θα κάνουν τη διαδικασία γρηγορότερη για ένα συγκεκριμένο query πχ με κάποιο trigger καθώς θα εισάγονται τα sales στη βάση, ή αν βολεύει να σπάσεις τα queries σε μικρότερα και να κάνεις υπολογισμούς ή άλλες επεξεργασίες στο application layer (πχ php).
alou έγραψε:ΥΓ μόλις διάβαζα ένα ενδιαφέρον post για WAI-ARIA ;)
:lol: Ευχαριστώ και ελπίζω να μοιραστείς την πηγή με κόσμο που πιστεύεις πως θα τους ενδιέφερε! ;)

alou
Script Master
Δημοσιεύσεις: 1374
Εγγραφή: 24 Αύγ 2007 19:52
Επικοινωνία:

Συζήτηση για σχεδιασμό βάσης που θα παρέχει στατιστικά στοιχεία πωλήσεων

Δημοσίευση από alou » 04 Ιούλ 2014 19:15

Thanks again για τις ιδέες, το indexing και τα constraints πραγματικά κάνουν τη διαφορά σε αρκετές περιπτώσεις και η δομή που σκέφτηκες είναι πολύ κοντά σε αυτό που έχω αυτή τη στιγμή, με τη διαφορά των κατηγοριών, όπου για την ώρα έχω προτιμήσει ένα pivot με barcode - category id όπου το barcode έχει entry για κάθε επίπεδο κατηγορίας (δηλαδή 1 έως 4 που είναι τα επίπεδα αντί να είναι ένα και να συσχετίσω parent-child categories). Δεν είμαι σίγουρος τι θα σημαίνει αυτό σε πιο πολύπλοκα ερωτήματα, θα δούμε.

Για τα brand / εταιρεία, όπως είπες και εσύ όπου το κάθε προϊόν είναι σίγουρο ότι "ανήκει" σε 1 μόνο id, βολεύει να είναι στον πίνακα των προϊόντων.
Η γενική λογική ήταν μάλλον κλασική, pivot για many to many και στο ίδιο table one-to-many σχέσεις με λίγο ως πολύ τα pk / fk που αναφέρεις.

Για να το πιάσω και από την άλλη μεριά, λέω πριν κάνω άλλες δοκιμές να πάρει πιο λειτουργική μορφή το front end και να γίνουν σε ~πραγματικές συνθήκες τα επόμενα πειράματα γιατί το ui πολλές φορές σε οδηγεί από μόνο του σε κάποιο ζητούμενο που πιθανότατα δεν σκέφτομαι τώρα και θα παίξουν ρόλο, ειδικά σε queries που θα επιστρέψουν πολυδιάστατους ή με συγκεκριμένες απαιτήσεις πίνακες / json ...

Άβαταρ μέλους
grigorakis4
Δημοσιεύσεις: 126
Εγγραφή: 16 Οκτ 2012 14:15
Τοποθεσία: ATHENS
Επικοινωνία:

Συζήτηση για σχεδιασμό βάσης που θα παρέχει στατιστικά στοιχεία πωλήσεων

Δημοσίευση από grigorakis4 » 14 Ιούλ 2014 19:28

Χωρίς να είμαι ο πλέον ειδικός για να σου απαντήσω σκεφτομαι οτι ειναι καλυτερα να δημιούργησες εναν πίνακα με το ονομα του brand και ενα για τις πωλήσεις.

Ο πρωτος πίνακας θα εχει Id, name, κ οτι αλλο χρειαζεται.

Ο δεύτερος πίνακας θα περιέχει τα στοιχεια καθε πωλήσεις κ σε ενα field θα προσθέτεις το Id της μάρκας.

Ετσι με ενα απλο ερώτημα θα μπορεις να εξαγεις ολες της πωλήσεις της συγκεκριμένης μάρκας απο ημερομηνια απο τάδε μεχρι τάδε. Δεν νομιζω οτι χρειαζεσαι κατι αλλο κ με μια γραμμη κώδικα περνεις τις τιμές κ της μετατρέπεις σε ποσοστό επι της 100 κ ολα καλα... Κ αν θες να πας ενα βήμα παρα περα βαλε ενα script μεσω cron προωθεί τα στοιχεια αυτα μεσω μειλ στους λογαριασμους τους...
Εικόνα

alou
Script Master
Δημοσιεύσεις: 1374
Εγγραφή: 24 Αύγ 2007 19:52
Επικοινωνία:

Συζήτηση για σχεδιασμό βάσης που θα παρέχει στατιστικά στοιχεία πωλήσεων

Δημοσίευση από alou » 14 Ιούλ 2014 22:37

@grigorakis4, thanks για την άποψη. Το ζητούμενο δεν είναι η απλότητα των queries αλλά η ευελιξία τους και η ταχύτητα απάντησης. Μην ξεχνάς ότι δε μιλάμε για ένα set δεδομένων απλά για τις πωλήσεις αλλά για τον συνδυασμό των πωλήσεων (1 η παραπάνω πίνακες) σε σχέση με άλλους πίνακες, με κατηγοριοποιήσεις σε διάφορα επίπεδα, ξεχωριστά για κάθε χρήστη.

Η λογική που ακολουθώ για την ώρα είναι να μην κάνω καθόλου optimization γιατί θέλω πρώτα να οριστικοποιήσω τα data structure που θα παράγονται σε διάφορες περιπτώσεις (για τα γραφικά κυρίως που είναι svg) και να καταλήξω στα πιθανά πιο συχνά queries ώστε να έχω μια καλύτερη άποψη.

Δεν κατάλαβα τι νόημε θα μπορούσε να είχε το cron που λες, ίσως δεν το έπιασα?

Άβαταρ μέλους
grigorakis4
Δημοσιεύσεις: 126
Εγγραφή: 16 Οκτ 2012 14:15
Τοποθεσία: ATHENS
Επικοινωνία:

Συζήτηση για σχεδιασμό βάσης που θα παρέχει στατιστικά στοιχεία πωλήσεων

Δημοσίευση από grigorakis4 » 14 Ιούλ 2014 22:49

Ειμαι της απόψεις οτι με 2-3 πίνακες μπορεις βα εξαγεις τα δεδομένα σου με 2-3 απλα ερωτήματα. Στην συνεχεια να της περνας με μεταβλητες php και να μετατρέπεις τα δεδομένα σου σε στατιστικά μεσω των μεταβλητων. Οταν λεω cron εννοουσα το cron job, εγω σε μια σελίδα με προγνωστικά ειχα βαλει ενα script να τρεχει με cron job άκου διάβαζε τα στατιστικά καθε παίκτη ενα εβδομάδα ανα μηνα κ ολη την σεζόν κ τα έστελνε μεσω της mail() στο email του. Πιστευω για την συχνή παρακολουθήσει των στατιστικών που θελεις να εξαγεις θα σου φανεί πολυ έξυπνο να δέχεται ο καθε χρήστης στατιστικά των πωλήσεων που κανει μεσω email. Επεισης θα σου πρότεινα να ψάξεις για js library για την εξαγωγή στατιστικών που ειναι πολυ εύκολη γενικα στην χρήση της κ χρησιμοποιούν ολες τους json δεδομένα κ στην ουσία θα εχεις βα κανεις μια απλή μετατροπή στα δεδομένα κ καθάρισες για την εξαγωγή στατιστικών γραφηματων.
Εικόνα

geomagas
Δημοσιεύσεις: 667
Εγγραφή: 06 Απρ 2013 13:36
Τοποθεσία: Ηράκλειο Κρήτης
Επικοινωνία:

Συζήτηση για σχεδιασμό βάσης που θα παρέχει στατιστικά στοιχεία πωλήσεων

Δημοσίευση από geomagas » 15 Ιούλ 2014 11:12

Το σχήμα είναι μικρό, και θεωρώ ότι δεν έχει και μεγάλα περιθώρια αποκλίσεων από μία τυπική κανονικοποίηση. Συνεπώς, με μικρές παραλλαγές του σχήματος του burnmind (αλλά και του δικού σου, απ' ότι κατάλαβα) εγώ θα κατέληγα σε κάτι σαν το παρακάτω:

Κώδικας: Επιλογή όλων

create table brand (id int AUTO_INCREMENT primary key, name varchar(200) not null);
create table company (id int AUTO_INCREMENT primary key, name varchar(200) not null);
create table category (id int AUTO_INCREMENT primary key, name varchar(200) not null);

create table category_tree (
  category int not null primary key references category(id),
  parent int not null references category(id)
  );

create table product (
  id char(13) primary key,
  name varchar(200) not null,
  brand int not null references brand(id),
  company int not null references company(id)
  );

create table product_category (
  product int not null references product(id),
  category int not null references category(id),
  primary key (product,category)
  );

create table sale (
  id int AUTO_INCREMENT primary key,
  product char(13) references product(id),
  sale_date timestamp not null,
  price decimal(10,2) not null default 0,
  cost decimal(10,2) not null default 0
  );

create index idx_sale_date on sale(sale_date);
Σχετικά με τις κατηγορίες, έχω υποθέσει ότι ένα προϊόν θα μπορεί να ανήκει σε πάνω από μία, κι επίσης ότι η σχέση των κατηγοριών/υποκατηγοριών ορίζεται από μία ή περισσότερες δενδροειδείς δομές, που αποθηκεύονται στον category_tree. Επίσης, ένα προϊόν μπορεί να ανήκει ακόμα και σε κάποια ενδιάμεση κατηγορία, κι όχι απαραίτητα σε terminal.

Θα παρατηρήσεις ότι αυτό αφήνει ένα παράδοξο να συμβεί: Ένα προϊόν μπορεί να ανήκει σε μία κατηγορία αλλά και σε κάποιον ancestor της. Αυτό δεν είναι κατ' ανάγκη λάθος, εκτός του ότι θα σου "τρώει" κάποιες έξτρα εγγραφές στη βάση, αλλά μπορεί να δημιουργήσει προβλήματα στην παραγωγή συγκεντρωτικών. Κανονικά, αυτό θα λυνόταν με ένα CTE, που όμως η MySQL δεν υποστηρίζει. Ο καλύτερος τρόπος προσομοίωσης είναι τα mirror tables, αλλά έχουν κι αυτά το κόστος τους...

Αν θέλεις κάθε προϊόν να ανήκει μόνο σε terminal κατηγορίες, θα χρειαστείς άλλους δύο IS-A tables και μερικές αλλαγές στα fks.

Όλα τα παραπάνω αφορούν τη δημιουργία του σχήματος με γνώμονα το integrity. Για την απόδοση τώρα, το πρώτο και κυριότερο είναι τα indices. Για να δεις τι χρειάζεσαι, θα πρέπει να μαζέψεις τις περιπτώσεις σου, να δεις που κανεις join, group by, order by και να αποφασίσεις σε ποια πεδία αξίζει τον κόπο να βάλεις index, χωρίς να επηρεάσεις πολύ την απόδοση σε άλλα σημεία.

Εκτός από τα indices των pk/fk που ούτως ή άλλως δημιουργούνται και θα χρησιμοποιηθούν στα joins, έχω προσθέσει και ένα άλλο προφανές, στο sale.sale_date. Αλλά είναι παραπάνω από σίγουρο ότι θα χρειαστείς κάποια στα names (για τις αλφαβητικές λίστες) και πιθανότατα στα sale.price και sale.cost, αν πρόκειται να γκρουπάρεις/ταξινομήσεις ως προς αυτά.

Περαιτέρω, ίσως μία view σαν την παρακάτω θα σου διευκόλυνε λίγο τη ζωή, αλλά οτιδήποτε παραπάνω από αυτό, νομίζω παύει να είναι γενικό:

Κώδικας: Επιλογή όλων

create view ext_sales as
select s.*,p.name,p.brand,p.company,c.category
from sales s
join product p on (s.product=p.id)
join product_category c on (c.product=p.id);

alou
Script Master
Δημοσιεύσεις: 1374
Εγγραφή: 24 Αύγ 2007 19:52
Επικοινωνία:

Συζήτηση για σχεδιασμό βάσης που θα παρέχει στατιστικά στοιχεία πωλήσεων

Δημοσίευση από alou » 15 Ιούλ 2014 12:28

Καλώστονα κι ας άργησε :P

Οι υποθέσεις που κάνεις είναι πολύ σωστές, τα μισά προϊόντα δεν είναι περασμένα σε terminal κατηγορίες και μπορεί να είναι σε 1 ή περισσότερες κατηγορίες είτε στο ίδιο κλαδί είτε (και) σε άλλο του δέντρου, οπότε ισχύει το θέμα περίπτωσης σφάλματος στην παραγωγή συγκεντρωτικών που είναι πολύ σημαντικό (η ουσία της εφαρμογής) και η αλήθεια είναι ότι δεν το είχα ψάξει καθόλου... :oops:

Το CTE που ανέφερες όμως ήταν καλό starting point για αναζήτηση και είδα μια εναλλακτική με stored procedure , που λίγο αργότερα, θα κοιτάξω να δω πως / άν θα μπορούσα να χρησιμοποιήσω... αλλιώς DISTINCT ...?

Κατά τα άλλα, το σχήμα όντως δεν μπορεί να αλλάξει και πάρα πολύ, πέρα ίσως από κάποια βοηθητικά json formatted πεδία που θα διευκολύνουν client side js (γι'αυτό είπα να προχωρήσω εκείνο το κομμάτι περισσότερο πριν καταλήξω οριστικά στο σχήμα).

Thanks ;)

geomagas
Δημοσιεύσεις: 667
Εγγραφή: 06 Απρ 2013 13:36
Τοποθεσία: Ηράκλειο Κρήτης
Επικοινωνία:

Συζήτηση για σχεδιασμό βάσης που θα παρέχει στατιστικά στοιχεία πωλήσεων

Δημοσίευση από geomagas » 15 Ιούλ 2014 13:02

alou έγραψε:Καλώστονα κι ας άργησε :P
Ναι η αλήθεια είναι ότι ήμουν περαστικός, αλλά είδα φως και μπήκα... ;)
alou έγραψε:Το CTE που ανέφερες όμως ήταν καλό starting point για αναζήτηση και είδα μια εναλλακτική με stored procedure , που λίγο αργότερα, θα κοιτάξω να δω πως / άν θα μπορούσα να χρησιμοποιήσω...


Πριν ανακαλύψω τα CTEs στον MSSQL, όλα αυτά τα έκανα κι εγώ με table-valued functions, κι όχι με procedures. Ο λόγος είναι ότι δεν μπορείς να κάνεις select από procedure, μόνο exec (με μία επιφύλαξη στον MSSQL, αν θυμάμαι καλά, αλλά κι αυτό είναι μανούβρα). Οπότε, το αποτέλεσμα της procedure μπορεί να είναι μόνο το τελικό προϊόν που θα πάρει η εφαρμογή σου, κι όχι κάτι που θα μπορείς να χρησιμοποιήσεις πχ σε μία subquery. Και βέβαια, μάλλον δεν θα αποφύγεις την αναδρομή, η οποία όχι ότι απουσιάζει από ένα CTE, απλά το CTE έχει σχεδιαστεί με την αναδρομή κατά νου, και είναι πιο σίγουρο ότι είναι optimized σε χαμηλότερο επίπεδο.

Αυτό που θα μπορούσες να κάνεις είναι να φτιάξεις ένα table με τις στήλες που θα σου παρείχε το CTE. Με αυτόν τον τρόπο, έχεις και το bonus ότι θα κάνεις select από στατικό table και όχι από κάτι υπολογιζόμενο, και άρα αργό.

Το μπέρδεμα είναι στο πως θα το ενημερώνεις. Αν θέλεις να είσαι all-weather, θα πρέπει να βάλεις triggers στον product_category, after insert/update/delete, και να χειρίζεσαι τον πίνακα αναλόγως (εδώ ταιριάζει η procedure, διότι ο trigger είναι ούτως ή άλλως μία τέτοια!). Οπότε, καταλαβαίνεις ότι μεταθέτεις το βάρος των επιδόσεων από το select στα insert/update/delete, που όμως μπορεί να συμφέρει και καλύτερα (πόσο συχνά θα ενημερώνεται ο πίνακας product_category, και πόσο συχνά θα κάνεις select από τον άλλο?)
alou έγραψε:αλλιώς DISTINCT ...?
Δηλαδή;

alou
Script Master
Δημοσιεύσεις: 1374
Εγγραφή: 24 Αύγ 2007 19:52
Επικοινωνία:

Συζήτηση για σχεδιασμό βάσης που θα παρέχει στατιστικά στοιχεία πωλήσεων

Δημοσίευση από alou » 16 Ιούλ 2014 14:28

geomagas έγραψε:
Δηλαδή;
Τίποτα, σκεφτόμουν κάτι που δεν ισχύει ούτως ή άλλως οπότε άκυρο...

Ερώτηση για το παρακάτω:

Κώδικας: Επιλογή όλων

create table product (
  id char(13) primary key,
  ...
  ); 

create table product_category (
  product int not null references product(id),
  ...
  ); 
φαντάζομαι char 13 στην αρχή λόγω barcode εννοούσες και μετά το int στο reference ήταν κατά λάθος ή υπάρχει κάποια δομή που ενοούσες και δεν κατάλαβα?

Το πως θα χειριστώ το barcode με παιδεύει ακόμα, γιατί στην εισαγωγή που θα κάνει ο χρήστης, μπορεί να υπάρχει άλλη κωδικοποίηση για τα προϊόντα + pivot που τη δένει με τα barcode, οπότε ακόμα και ένα pivot με barcode / product_id για τη μόνιμη βάση να υπάρχει, θα χρειάζεται ένα παραπάνω subquery / join ... πιθανότατα είναι μπερδεμένο αυτό που λέω και δεν βγάζει νόημα αν δεν δείξω κάτι πιο συγκεκριμένο :/ οπότε θα επανέλθω ασαπ

geomagas
Δημοσιεύσεις: 667
Εγγραφή: 06 Απρ 2013 13:36
Τοποθεσία: Ηράκλειο Κρήτης
Επικοινωνία:

Συζήτηση για σχεδιασμό βάσης που θα παρέχει στατιστικά στοιχεία πωλήσεων

Δημοσίευση από geomagas » 16 Ιούλ 2014 14:46

alou έγραψε:φαντάζομαι char 13 στην αρχή λόγω barcode εννοούσες

Ακριβώς.
alou έγραψε:και μετά το int στο reference ήταν κατά λάθος...
Ακριβέστατα (my bad!).
alou έγραψε:Το πως θα χειριστώ το barcode με παιδεύει ακόμα, γιατί στην εισαγωγή που θα κάνει ο χρήστης, μπορεί να υπάρχει άλλη κωδικοποίηση για τα προϊόντα + pivot που τη δένει με τα barcode, οπότε ακόμα και ένα pivot με barcode / product_id για τη μόνιμη βάση να υπάρχει, θα χρειάζεται ένα παραπάνω subquery / join ... πιθανότατα είναι μπερδεμένο αυτό που λέω και δεν βγάζει νόημα αν δεν δείξω κάτι πιο συγκεκριμένο :/ οπότε θα επανέλθω ασαπ
Η λογική είναι ότι το barcode είναι ούτως ή άλλως αναγνωριστικό του προϊόντος, και μάλιστα "global". Αυτό το παραδέχεσαι έμμεσα, όταν υλοποιείς τη διαδικασία του import: για να πετύχει, θα πρέπει να υπάρχει αντιστοιχία 1:1 με το id, άρα το barcode να είναι not null και unique. Γιατί λοιπόν να μην το χρησιμοποιήσεις και σαν pk;

Βέβαια αυτά τα λέω επειδή με έχασες λίγο με την ιδιαιτερότητα της εισαγωγής. Να υποθέσω ότι υπάρχει κάποιο SKU-like πεδίο, το οποίο αντιστοιχεί τελικά με ένα global barcode;

Επίσης έχω από την αρχή την απορία, τι εννοείς λέγοντας "pivot"; Επειδή είναι κάτι διαφορετικό από μία M:N συσχέτιση.

alou
Script Master
Δημοσιεύσεις: 1374
Εγγραφή: 24 Αύγ 2007 19:52
Επικοινωνία:

Συζήτηση για σχεδιασμό βάσης που θα παρέχει στατιστικά στοιχεία πωλήσεων

Δημοσίευση από alou » 16 Ιούλ 2014 15:17

geomagas έγραψε: Επίσης έχω από την αρχή την απορία, τι εννοείς λέγοντας "pivot"; Επειδή είναι κάτι διαφορετικό από μία M:N συσχέτιση.
Τα αντίστοιχα tables με αυτό, στο context μιας ΒΔ δεν είναι σωστό?

Κώδικας: Επιλογή όλων

create table product_category
...
geomagas έγραψε: Βέβαια αυτά τα λέω επειδή με έχασες λίγο με την ιδιαιτερότητα της εισαγωγής. Να υποθέσω ότι υπάρχει κάποιο SKU-like πεδίο, το οποίο αντιστοιχεί τελικά με ένα global barcode;
Ναι, κάπως έτσι. Για την ώρα χρησιμοποιώ το barcode σαν id και συμφωνώ με τη λογική που περιέγραψες όμως προσπαθόντας να πάρω δείγματα από διάφορα ERP (export πωλήσεων) βλέπω ότι δε χρησιμοποιούν όλα barcode αλλά κάποιο δικό τους κωδικό, που παντρεύουν με (pivot?) με τα barcode. Οπότε, με όποιο μαγείρεμα γίνει με την εισαγωγή πωλήσεων από το erp, είναι καλύτερο να κρατήσω το barcode ή ένα δικό μου id, αφού έτσι και αλλιώς θα γίνει η αντιστοίχιση κατά την εισαγωγή?

Δεν έχει νόημα η απάντηση για την ώρα καθώς οι λεπτομέρειες της εισαγωγής στοιχείων ακόμα εκκρεμούν + υπάρχουν κάποια μπερδέματα που αρχίζουν να εμφανίζονται, πχ προϊόντα με διπλά barcodes κ.ά. που μπορεί να οδηγήσουν αναγκαστικά και όχι για καλύτερο σε κάποια συγκεκριμένη λύση.

geomagas
Δημοσιεύσεις: 667
Εγγραφή: 06 Απρ 2013 13:36
Τοποθεσία: Ηράκλειο Κρήτης
Επικοινωνία:

Συζήτηση για σχεδιασμό βάσης που θα παρέχει στατιστικά στοιχεία πωλήσεων

Δημοσίευση από geomagas » 16 Ιούλ 2014 18:30

alou έγραψε:
geomagas έγραψε: Επίσης έχω από την αρχή την απορία, τι εννοείς λέγοντας "pivot"; Επειδή είναι κάτι διαφορετικό από μία M:N συσχέτιση.
Τα αντίστοιχα tables με αυτό, στο context μιας ΒΔ δεν είναι σωστό?

Κώδικας: Επιλογή όλων

create table product_category
...
Συνήθως αναφερόμαστε στο pivoting ως έναν μετασχηματισμό του dataset για την παραγωγή συγκεντρωτικών στοιχείων. Στη γενική περίπτωση η διαδικασία περιλαμβάνει τη μετατροπή μίας στήλης σε πολλές, με τις distinct τιμές της να μετατρέπονται σε fields. Πχ δες εδώ, ή εδώ που η υλοποίηση στο fiddle της απάντησης είναι πιο "ψαγμένη" ;).
alou έγραψε:
geomagas έγραψε: Βέβαια αυτά τα λέω επειδή με έχασες λίγο με την ιδιαιτερότητα της εισαγωγής. Να υποθέσω ότι υπάρχει κάποιο SKU-like πεδίο, το οποίο αντιστοιχεί τελικά με ένα global barcode;
Ναι, κάπως έτσι. Για την ώρα χρησιμοποιώ το barcode σαν id και συμφωνώ με τη λογική που περιέγραψες όμως προσπαθόντας να πάρω δείγματα από διάφορα ERP (export πωλήσεων) βλέπω ότι δε χρησιμοποιούν όλα barcode αλλά κάποιο δικό τους κωδικό, που παντρεύουν με (pivot?) με τα barcode. Οπότε, με όποιο μαγείρεμα γίνει με την εισαγωγή πωλήσεων από το erp, είναι καλύτερο να κρατήσω το barcode ή ένα δικό μου id, αφού έτσι και αλλιώς θα γίνει η αντιστοίχιση κατά την εισαγωγή?
Εσύ, σε κάθε περίπτωση, μετά την εισαγωγή έχεις barcode, δεν είναι έτσι;
Το οποίο έχεις ούτως ή άλλως στη βάση σου, αλλιώς δεν μπορείς να κάνεις τίποτα.
Οπότε, το δίλημμα είναι αν θα κρατήσεις το ίδιο το barcode σαν pk ή θα έχεις ένα δικό σου, με αντιστοιχία 1:1 με το barcode. Εγώ θα κρατούσα το barcode.
alou έγραψε:Δεν έχει νόημα η απάντηση για την ώρα καθώς οι λεπτομέρειες της εισαγωγής στοιχείων ακόμα εκκρεμούν + υπάρχουν κάποια μπερδέματα που αρχίζουν να εμφανίζονται, πχ προϊόντα με διπλά barcodes κ.ά. που μπορεί να οδηγήσουν αναγκαστικά και όχι για καλύτερο σε κάποια συγκεκριμένη λύση.
Θέλεις να πεις ότι το ίδιο ακριβώς προϊόν εμφανίζεται με πολλά διαφορετικά barcodes; Γιατί αν είναι έτσι, πάει περίπατο η αντιστοιχία 1:1 που είπαμε παραπάνω. Οπότε:
- είτε κρατάς το barcode σαν pk και αναγκαστικά έχεις πολλά instances για το ίδιο προϊόν
- είτε έχεις ένα δικό σου id στον product αλλά χρειάζεσαι έναν δεύτερο πίνακα (barcode pk, product fk[product.code]) για την αντιστοίχιση.

Απάντηση

Επιστροφή στο “MySQL”

Μέλη σε σύνδεση

Μέλη σε αυτήν τη Δ. Συζήτηση: Δεν υπάρχουν εγγεγραμμένα μέλη και 0 επισκέπτες