Κατηγορία: sql

  • Με προσοχή το hydrate σε queries με joins

    Με προσοχή το hydrate σε queries με joins

    Το laravel είναι ωραιότατο! Βάζει μια τάξη στην άναρχη PHP, της δίνει έναν αέρα από ASP.NET με MVC, χωρίς όμως το γνωστό βαρύ περίβλημα. Παραμένουμε δηλαδή στην PHP, γιατί είναι γρήγορη και δυναμική, δομώντας την όμως καθαρά και σωστά άλα laravel. Αυτά όμως τα ξέρετε και δεν είναι επί του παρόντος. Θα ξέρετε ακόμα και ότι το laravel είναι αυτό που είναι χάρη στο eloquent, το συμπαθητικό ORM, της ίδιας ακριβώς ιδιοσυγκρασίας με το laravel. Έχει όμως και τα τερτίπια του. Και ειδικά όταν η ΒΔ μεγαλώνει, τα πράγματα περιπλέκουν, τα queries απαιτούν πολλά join και το eloquent στενάζει. Ή πιο σωστά ο προγραμματιστής στενάζει προσπαθώντας να απεικονίσει με eloquent αυτό που τόσα χρόνια έκανε με τρεις γραμμές sql. Και γιατί όχι λέει ο Τaylor! Γράψτο όπως ξέρεις και ενυδάτωσέ το!

    Λογοπαίγνιο για το hydrate ήταν αυτό, ένα παράδειγμα πάντα βοηθάει:

    $result = \DB::table('users')->take(2)->get();
    $users = \App\User::hydrate($result); 
    

    Και για τα πιο hardcore τυπάκια, χωρίς table, με ξερό select:

    $result = \DB::select('select * from users limit 2 ')->get();
    $users = \App\User::hydrate($result); 
    

    Τι κάναμε; Στην πρώτη γραμμή, με ένα ξερό select, η PHP μας γυρνάει ένα γενικού τύπου collection. Στη δεύτερη, χάρη στο hydrate, το αγνώστου τύπου collection παίρνει σάρκα και οστά και γίνεται collection του model User!

    Και φυσικά, για ένα τόσο απλό παράδειγμα, δεν έχει νόημα!

    Θα μπορούσαμε να πετύχουμε ακριβώς τα ίδια με μια γραμμή eloquent, χωρίς ίχνος sql!

    Tα ωραία κόλπα μας θα αρχίσουν με τα join στους ρόλους, στους people και όπου αλλού λαχταράει η ψυχή σας για join. Ειδικά μάλιστα αν είναι αποφύγουμε τα ιδιάζοντα whereHas, whereIn, wherePivot, whereSomethingNew… και να χρησιμοποιήσουμε κάτι πιο οικείο, αυτό που ξέρουμε από τη δεκαετία του ενενήντα: S.Q.L. χωρίς να σπάσουμε το κεφάλι μας για το πως γίνεται το καθετί.

    Μην ξεχάσετε όμως στο τέλος να ενυδατώσετε το ξερό query.

    $result = \DB::select('select * from users inner join roles on users.role_id = roles.id where roles.type="admin" ')->get();
    $users = \App\User::hydrate($result); 
    

    Πως σας φαίνεται το παραπάνω; Ωραιότατο! Δεν θα ήθελα ούτε καν να σκεφτώ πως πρέπει να το συντάξω με eloquent. Αυτό το παραπάνω querάκι μου βγήκε έτσι, αυθόρμητα, χωρίς πολλά-πολλά, σαν να γράφω τη λίστα με τα ψώνια.

    Προσοχή όμως γιατί κρύβεται κάτι σατανικό – κάτι που μόνο ένα δίωρο debugging θα το αποκαλύψει, ή εγώ ευθύς αμέσως:

    Τι γίνεται αν users και roles έχουν πεδία με ίδια ονόματα – πχ. κλειδάκι με όνομα id; Τι θα κάνει το hydrate σε αυτή την περίπτωση; Θα τα σκατώσει! Και καλά θα κάνει, δεν θα φταίει αυτό! Εμείς φταίμε που δεν ορίσαμε με σαφήνεια τι θα ενυδατωθεί! Ζητήσαμε να ενυδατωθεί το αστεράκι (*) συνεπώς δεν αποκλείεται το hydrate να βάλει στον χρήστη το id του ρόλου!

    Ποια είναι η λύση;

    Η αποσαφήνιση του αστερίσκου. Πολλά λόγια δεν χρειάζονται. Δείτε παρακάτω και θα καταλάβετε:

    $result = \DB::select('select users.* from users inner join roles on users.role_id = roles.id where roles.type="admin" ')->get();
    $users = \App\User::hydrate($result); 
    

    Έτσι αποφεύγουμε τις κακοτοπιές, δηλώνουμε ρητά ότι είναι τα πεδία του πίνακα users που θα γίνουν map με το model User!

  • προγραμματισμένο mysql backup

    προγραμματισμένο mysql backup

    Είδαμε κάτι αντίστοιχο για τον sql server express, αλλά ήρθε και η ώρα του mysql backup. Όταν μιλάμε για mysql, μιλάμε για linux κι όταν μιλάμε για linux, ανοίγουμε την κονσόλα.

    mysql backup, όλα και γρήγορα!

    Ας δούμε κατ’αρχήν πως κάνουμε παίρνουμε στα γρήγορα ένα backup για όλες τις databases:

    mysqldump -u root -p --all-databases > alldb.sql

    Θα σας ζητηθεί ο κωδικός του root.

    Για να μην ζητάει τον κωδικό του root (π.χ. cron), θα πρέπει να κολλήσετε δίπλα στο -p τον κωδικό:

    mysqldump -u root -pSECRET --all-databases > alldb.sql

    …και συμπίεση;

    Προφανώς θα θέλετε να συμπιέσετε το αρχείο, κάτι που χάρη στην κονσόλα και το piping, γίνεται με μιας, κάπως έτσι:

    mysqldump -u root -pSECRET --all-databases | bzip2 -c > alldb.$(date +%Y-%m-%d-%H.%M.%S).sql.bz2

    Παρατηρήστε την απλότητα με την οποία δηλώνουμε την ημερομηνιακή μορφή του συμπιεσμένου:

    $(date +%Y-%m-%d-%H.%M.%S)

    ή μήπως καλύτερα σκριπτάκι;

    Συχνά, είναι προτιμότερο να διατηρούμε αντίγραφο της κάθε database σε χωριστό αρχείο. Ακολουθεί ένα ωραιότατο σκριπτάκι bash, το οποίο διαβάζει τα ονόματα των βάσεων δεδομένων και για κάθε μια από αυτές – πλην των συστημικών του mysql – λαμβάνει αντίγραφο και το ζιπάρει!

    #!/bin/bash
    
    USER="root"
    PASSWORD="SECRET"
    
    databases=`mysql -u $USER -p$PASSWORD -e "SHOW DATABASES;" | tr -d "| " | grep -v Database`
    
    for db in $databases; do
        if [[ "$db" != "information_schema" ]] && [[ "$db" != "performance_schema" ]] && [[ "$db" != "mysql" ]] && [[ "$db" != _* ]] ; then
            echo "Dumping database: $db"
            OUTPUT=`date +%Y%m%d`.$db.sql
            mysqldump -u $USER -p$PASSWORD --databases $db > $OUTPUT
            gzip $OUTPUT
        fi
    done
    

    Ονομάστε το σκριπτάκι backup και μην ξεχάσετε να το κάνετε εκτελέσιμο:

    chmod +x backup

    Τώρα, για να έχετε το κεφάλι σας ήσυχο βάλτε το και σε ένα κρον (crontab -e) και καλή ανάσταση:

    0 7 * * * /root/mysqlbackups/backup

     

  • άλλη μια ώρα χαμένη με τα τερτίπια του sql server

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

    Ας πάρουμε όμως τα πράγματα από την αρχή. Ήταν ένα ηλιόλουστο μεσημέρι και κάναμε debugging σε μια παλιά .net εφαρμογή που παρσάρει κάτι παράξενα αρχεία πάραντοξ (!), κάνει κάτι πράξεις και τέλος τα σπρώχνει σε μια database στον sql server που αναλαμβάνει τα περεταίρω. Κι ενώ όλοι θα στοιχημάτιζαν ότι κάτι θα στράβωνε μεταξύ paradox – bde – access – odbc ή κάποιας άλλης παλαιολιθικής οντότητας, το debugging ανέδειξε σφάλμα στο connectivity με τον sql server.

    Τίποτα προφανές: κανένα δικτυακό πρόβλημα, τα συνθηματικά σωστά, ο server πάνω, τι στο καλό; Wtf; -επί το ελληνικότερο!

    (περισσότερα…)

  • mysql: πρωτομηνιά

    Ένα γρήγορο snippet, για την πρώτη του τρέχοντος μήνα στον mysql:

    DATE_FORMAT(NOW() ,'%Y-%m-01')

    Πιο πλήρες άρθρο είχαμε παλιότερα για τον sql server:

    sql server + ημερομηνίες

  • mysql .net connector: Authentication with old password no longer supported, use 4.1 style passwords.

    mysql .net connector: Authentication with old password no longer supported, use 4.1 style passwords.

    Αν συναντήσετε το exception “Authentication with old password no longer supported, use 4.1 style passwords.”, ίσως έχετε πέσει θύματα της αλλαγής του policy του mysql, ο οποίος απαιτεί ισχυρότερα password κατά τη διασύνδεση μέσω του .net connector. Οι λύσεις στο πρόβλημα είναι 2.

    (περισσότερα…)

  • mysql & linux: προσθήκη χρήστη

    mysql & linux: προσθήκη χρήστη

    Θα δείξουμε πως να προσθέσουμε νέο χρήστη στον mysql χρησιμοποιώντας την κονσόλα. Υποθέτουμε ότι ο mysql τρέχει σε σύστημα linux και ότι ο χρήστης jack που θέλουμε να φτιάξουμε απαιτεί select δικαιώματα στον πίνακα transaction της βάσης δεδομένων accounting.

    (περισσότερα…)

  • sql server, εύρεση του foreign βάσει του primary key

    sql server, εύρεση του foreign βάσει του primary key

    Οκ, αυτό το άρθρο θα είναι σύντομο, καθώς πρόκειται για αντιγραφή από το stackoverflow, αλλά το δίνουμε κι εδώ για reference, χρήσιμο στους χρήστες τους Sql Server που παλεύουν με άγνωστο σχήμα προσπαθώντας να εντοπίσουν τις σχέσεις των πινάκων. Ακολουθεί ένας πολύ κομψός τρόπος.


    SELECT
    o1.name AS FK_table,
    c1.name AS FK_column,
    fk.name AS FK_name,
    o2.name AS PK_table,
    c2.name AS PK_column,
    pk.name AS PK_name,
    fk.delete_referential_action_desc AS Delete_Action,
    fk.update_referential_action_desc AS Update_Action
    FROM sys.objects o1
    INNER JOIN sys.foreign_keys fk
    ON o1.object_id = fk.parent_object_id
    INNER JOIN sys.foreign_key_columns fkc
    ON fk.object_id = fkc.constraint_object_id
    INNER JOIN sys.columns c1
    ON fkc.parent_object_id = c1.object_id
    AND fkc.parent_column_id = c1.column_id
    INNER JOIN sys.columns c2
    ON fkc.referenced_object_id = c2.object_id
    AND fkc.referenced_column_id = c2.column_id
    INNER JOIN sys.objects o2
    ON fk.referenced_object_id = o2.object_id
    INNER JOIN sys.key_constraints pk
    ON fk.referenced_object_id = pk.parent_object_id
    AND fk.key_index_id = pk.unique_index_id
    ORDER BY o1.name, o2.name, fkc.constraint_column_id

  • plug and play json restful api για mysql και όχι μόνο

    plug and play json restful api για mysql και όχι μόνο

    Όσοι γνωρίζετε το https://github.com/alixaxel/ArrestDB δεν χρειάζεται να διαβάσετε παρακάτω.

    Όσοι όμως δεν το έχετε ξανακούσει, αξίζει να διαβάσετε τη συνέχεια και ίσως να το δοκιμάσετε.

    Ας υποθέσουμε ότι έχετε σχεδιάσει μια φανταστική database – σε MySql, PostgreSQL ή SQLite και αναρωτιέστε πως θα τη διασυνδέσετε με τη mobile / web / desktop εφαρμογή σας. Τρόποι υπάρχουν πάμπολλοι, άλλοι πιο δύσκολοι, άλλοι πιο εύκολοι, άλλοι σωστοί και άλλοι προβληματικοί.

    Ένας από αυτούς, εξαιρετικά απλός και γρήγορος, είναι το ArrestDB που υπόσχεται να χτίσει σε μηδέν χρόνο ένα RESTful API γύρω από την database σας με μία γραμμή κώδικα – που αφορά στο connection string της db.

    Το project είναι γραμμένο σε PHP αλλά δεν χρειάζεται να γνωρίζετε τίποτα γι αυτήν, εκτός από το γεγονός ότι θα πρέπει να διαθέτετε την v5.4 – κάπως περιοριστικό αφού η 5.3 εξακολουθεί να μεσουρανεί.

    Για την εγκατάσταση κοπιάρετε στον web server σας το ένα και μοναδικό αρχείο του ArrestDB (index.php), τροποποιείτε καταλλήλως την πρώτη γραμμή του, φτιάχνετε και ένα htaccess για το routing και είστε έτοιμοι να δοκιμάσετε το api. Αν έχετε ξαναπαίξει με άλλο api, δεν θα βρείτε πρακτικά διαφορές, είναι έτσι όπως το φαντάζεστε:

    • Για να δείτε τον πελάτη του πίνακα customer με όνομα Nick:
      GET http://api.example.com/customer/name/Nick/
    • Για να τροποποιήσετε τον πελάτη του πίνακα customer με κωδικό 100:
      PUT http://api.example.com/customer/100/

    Για security, ούτε λόγος, στην καλύτερη, ότι προσφέρει ο apache. Ίσως οι πιο απαιτητικοί από εσάς να μην καλυφθούν, αλλά ο,τιδήποτε πιο advanced απαιτεί σαφώς περισσότερο κόπο, κι έτσι το ArrestDB καθίσταται μοναδικό για testing και για ταχύτατη υλοποίηση.

  • εγκατάσταση του xampp στα windows

    εγκατάσταση του xampp στα windows

    Το xampp συγκεντρώνει όλα όσα χρειάζεστε για να μετατρέψετε το pc σας σε web server που να υποστηρίζει τα συνήθη γουεμπικά προαπαιτούμενα apache, php, mysql των πιο δημοφιλών open source web application. Ακόμα κι αν το τελικό προϊόν σας τρέξει σε επαγγελματικό web host, θα χρειαστείτε το xampp για το development. Ακολούθως, θα δείξουμε την εγκατάσταση του xampp στα windows καθώς και μερικές βασικές ρυθμίσεις.

    (περισσότερα…)

  • προγραμματισμένο backup στον sql server express

    προγραμματισμένο backup στον sql server express

    Στο προηγούμενο μιλήσαμε για τον sql server express, σε αυτό θα δώσουμε μια γρήγορη λύση scheduled backup για τον express που έχει δοκιμαστεί για πολλά χρόνια σε αρκετές εγκαταστάσεις.

    (περισσότερα…)