Αναζήτηση σε πεδίο που περιέχει ένα πίνακα στοιχείων

Γενικές συζητήσεις για SQL και SQL Servers (RDBMS)

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

Απάντηση
freds
Δημοσιεύσεις: 320
Εγγραφή: 24 Φεβ 2005 16:11

Αναζήτηση σε πεδίο που περιέχει ένα πίνακα στοιχείων

Δημοσίευση από freds » 22 Σεπ 2008 18:06

Καλησπέρα,

Θα ήθελα να ρωτησω κάτι αν κάποιος γνωρίζει.

Έχω ένα πίνακα σε MySQL ο οποίος περιέχει ένα πεδίο στο οποίο καταχωρώ κάποια νούμερα χωρισμένα με κόμμα. π.χ. (4,45,53,66) ή (1,2,3,4,5,15,23,22,26,44,45)

Θέλω να κάνω μια αναζήτηση με sql στην οποία θέλω πχ να ψάχνω τις εγγραφές εκείνες που περιέχουν το νούμερο 5, και μόνο αυτό και όχι στο 45 ή στο 555.

Αν γράψω κάτι σαν και αυτό

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

SELECT * FROM table WHERE table_field LIKE "%5%";
τότε μου φέρνει και την πρώτη επιλογή του παραδείγματος γιατί φυσιολογικά το 5 υπάρχει και σε αυτήν, πχ στο 45, στο 53

Ποια θα πρέπει να είναι το sql ερώτημα ώστε να φέρνει σωστά τα αποτελέσματα;

Άβαταρ μέλους
cherouvim
Script Master
Δημοσιεύσεις: 3137
Εγγραφή: 13 Ιούλ 2005 22:56
Τοποθεσία: Athens, Greece
Επικοινωνία:

Αναζήτηση σε πεδίο που περιέχει ένα πίνακα στοιχείων

Δημοσίευση από cherouvim » 22 Σεπ 2008 20:22

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

select * from table where field like "%,5,%" or
                          field like "5,%" or
                          field like "%,5";
Αρκετά αργό πάντως.

Ένας άλλος τρόπος είναι να γράφεις τα νούμερα έτσι: [1][2][7][11][100][234]
οπότε το query γίνεται πιο γρήγορο:

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

select * from table where field like "%[5]%";
με κόστος 1 παραπάνω χαρακτήρα ανά νούμερο.

Εναλλακτικά αν μπορείς να εγγυηθείς ότι τα περιεχόμενα είναι σε αυτό το περίεργο format: ,1,2,7,11,100,234,
τότε το query γίνεται:

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

select * from table where field like "%,5,%";

freds
Δημοσιεύσεις: 320
Εγγραφή: 24 Φεβ 2005 16:11

Αναζήτηση σε πεδίο που περιέχει ένα πίνακα στοιχείων

Δημοσίευση από freds » 22 Σεπ 2008 20:45

Thanks για την απάντηση.

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

Η πρώτη γίνεται ακόμα πιο αργή γιατί θα πρέπει να βάλουμε και την επιλογή το 5 να είναι μόνο του χωρίς επιπλέον άλλα ψηφία που σημαίνει ότι θα προστεθεί και το field ="5" που δεν περιέχει κόμματα.


Κάτι άλλο που δεν ξέρω αν υπάρχει.

Γνωρίζω ότι μπορούμε να γράψουμε κάτι σαν και το παρακάτω:

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

select * from table where field IN (5, 15, 2, 33, 45)
Υπάρχει η δυνατότητα να γράψουμε κάτι σαν και αυτό

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

select * from table where "5" IN field 
αν το field έχει την μορφή ενός array;
Τελευταία επεξεργασία από το μέλος freds την 22 Σεπ 2008 21:03, έχει επεξεργασθεί 1 φορά συνολικά.

Άβαταρ μέλους
cherouvim
Script Master
Δημοσιεύσεις: 3137
Εγγραφή: 13 Ιούλ 2005 22:56
Τοποθεσία: Athens, Greece
Επικοινωνία:

Αναζήτηση σε πεδίο που περιέχει ένα πίνακα στοιχείων

Δημοσίευση από cherouvim » 22 Σεπ 2008 20:59

Σωστά.

Γίνεται έτσι λοιπών:

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

select * from table where field like "%,5,%" or
                          field like "5,%" or
                          field like "%,5" or
                          field = "5";
Όπου τα 3 πρώτα είναι σίγουρα full table scan.

Κάνε το τελευταίο.

freds
Δημοσιεύσεις: 320
Εγγραφή: 24 Φεβ 2005 16:11

Αναζήτηση σε πεδίο που περιέχει ένα πίνακα στοιχείων

Δημοσίευση από freds » 22 Σεπ 2008 21:07

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

Καταλαβαίνω ότι μπορεί να είναι χαζομάρα :o η ερώτηση που κάνω σε αυτό αλλά καλό είναι να εξετάζουμε όλες τις περιπτώσεις.

Έτσι κουβέντα να κάνουμε δηλαδή.

Ευχαριστώ πάντως. Το τελευταίο θα κάνω.

Άβαταρ μέλους
cherouvim
Script Master
Δημοσιεύσεις: 3137
Εγγραφή: 13 Ιούλ 2005 22:56
Τοποθεσία: Athens, Greece
Επικοινωνία:

Αναζήτηση σε πεδίο που περιέχει ένα πίνακα στοιχείων

Δημοσίευση από cherouvim » 22 Σεπ 2008 21:13

Δεν έχω ιδέα, και ούτε ξέρω ή έχω χρησιμοποιήσει array datatype στην SQL. Γενικά τέτοια "κόλπα" έρχονται σε αντίθεση με τη φιλοσοφία των σχεσιακών βάσεων δεδομένων. Όπως καταλαβαίνεις το πεδίο για το οποίο μιλάμε κανονικά έπρεπε να είναι ένα άλλο table του τυπου:

parent_id, number

freds
Δημοσιεύσεις: 320
Εγγραφή: 24 Φεβ 2005 16:11

Αναζήτηση σε πεδίο που περιέχει ένα πίνακα στοιχείων

Δημοσίευση από freds » 22 Σεπ 2008 21:27

Τώρα μιλάς σωστά. Έτσι το έχω κάνει.

Πρόσεξε όμως να δεις τι συμβαίνει και θέλω να το αλλάξω.

Βασικά έχω ένα βασικό πίνακα και τρεις επιπλέον με parentid και number.

Τα νούμερα σε κάθε ένα από τους τρεις επιπλέον πίνακες αναφέρονται σε διαφορετικά πράγματα και είναι αναγκαίοι.

Ετσι τώρα δημιουργείται το εξής πρόβλημα.

Έχω μια σελίδα που εμφανίζω τα αποτελέσματα του βασικού πίνακα ανα δέκα (κάνω ένα select δηλαδή). Σε κάθε μία εγγραφή του βασικού πίνακα κάνω τρία ακόμα select για να παρουσιάσω τα αποτελέσματα του κάθε επιπλέον πίνακα με το αντίστοιχο parentid.

Αυτό σημαίνει σύνολο άλλα τριάντα SELECT.

Αυτό θέλω να αποφύγω. Για να απόφύγω τα πολλά queries στην βάση. Έχω ένα θέμα με τα max_questions που συμπληρώνονται πολύ γρήγορα και το site μένει εκτός λειτουργίας για πολύ ώρα κάθε ώρα αιχμής.

Σκέψου ότι αν ανοίξει η σελίδα 100 φορές τότε τα SELECTS γίνονται 31x100 = 3100 ενώ κανονικά θα έπρεπε να είναι 1x100=100

Αυτό που προσπαθούσα να κάνω, είναι μια αναδιοργάνωση του site και αντί να κάνω SELECT για τους επιμέρους πίνακες, απλά να κάνω έναν έλεγχο μετά με κάποιο array.

Άβαταρ μέλους
cherouvim
Script Master
Δημοσιεύσεις: 3137
Εγγραφή: 13 Ιούλ 2005 22:56
Τοποθεσία: Athens, Greece
Επικοινωνία:

Αναζήτηση σε πεδίο που περιέχει ένα πίνακα στοιχείων

Δημοσίευση από cherouvim » 22 Σεπ 2008 21:37

Έχεις πέσει στο κλασικό n+1 selects πρόβλημα (http://www.hibernate.org/118.html#A23)
Αν έπεζες με κάποιο ORM το πρόβλημα θα λυνόταν πιο εύκολα.

Μία ιδέα είναι να ενώσεις τα 3 tables σε ένα, εισάγοντας ένα έξτρα πεδίο για discriminator.
πχ πες το "type".

Τέλος όταν μαζέψεις τα IDs, μην βαρέσεις n queries (στη περίπτωση σου 10), αλλά ένα query της μορφής:

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

select foo, bar, example from articles where id in (1, 2, 5, 10, 13, 16, 21, 22, 25, 30, 23)

freds
Δημοσιεύσεις: 320
Εγγραφή: 24 Φεβ 2005 16:11

Αναζήτηση σε πεδίο που περιέχει ένα πίνακα στοιχείων

Δημοσίευση από freds » 22 Σεπ 2008 21:56

Σε αυτό έχεις πολύ δίκιο.

Αν και το έξτρα πεδίο για discriminator δεν μπορεί να γίνει τώρα πολύ εύκολα.

Δεν το είχα σκεφτεί ότι από πριν μπορώ να μαζέψω όλα των επιπλέων πινάκων που αφορούν τα id των δέκα εμφανιζομένων αποτελεσμάτων και αντίστοιχα να τα μεταφέρω σε κάποιο array του οποίου τα στοιχεία να τα εμφανίζω αντίστοιχα.

Δεν το είχα παρατηρήσει το n+1 πρόβλημα στο παρελθόν.

Thanks a lot.

Τελικά αυτό θα κάνω, και όχι αυτά που αναφέραμε παραπάνω. Από ότι μπορώ να καταλάβω τα SELECTS γίνονται συνολικά 4 και όχι 31. Η διαφορά είναι πολύ μεγάλη.

Να μη σου πω ότι έτσι γλυτώνω όλη αυτή την μετάβαση και την διαφοροποίηση που είχα σκεφτεί να κάνω. Θέλει βέβαια και αυτό την δουλειά του και την ώρα του αλλά φαντάζομαι πολύ λιγότερη.
:D

Απάντηση

Επιστροφή στο “Βάσεις Δεδομένων και SQL - γενικά”

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

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