Πώς να ενημερώσετε αντικείμενα μέσα σε συστοιχίες JSONB με PostgreSQL

Πώς να ενημερώσετε μια συγκεκριμένη τιμή σε έναν πίνακα JSONB

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

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

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

Σε αυτό το άρθρο ας δούμε πώς να ενημερώσετε μια συγκεκριμένη τιμή ενός αντικειμένου μέσα σε έναν πίνακα με ένα ερώτημα.

TL; DR : το τελικό ερώτημα βρίσκεται στο τέλος του άρθρου και μπορείτε να δείτε ένα ζωντανό παράδειγμα στο DB Fiddle για αντιγραφή και επικόλληση και αναπαραγωγή.

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

Στη συνέχεια, δημιουργείτε έναν πίνακα πελατών με μια στήλη επαφών JSONB και εισάγετε ορισμένα δεδομένα σε αυτήν:

Πολύ εύκολο, σωστά; Αλλά πώς μπορείτε να ενημερώσετε μια συγκεκριμένη επαφή για έναν συγκεκριμένο πελάτη; Πώς να αλλάξετε το email του Jimi ή του τηλεφώνου της Janis; ;

Ευτυχώς, η PostgreSQL είναι ο φίλος σας και παρέχει τη λειτουργία jsonb_set :

jsonb_set (target jsonb, path path [], new_value jsonb [, create_missing boolean])

Λαμβάνοντας υπόψη μια στήλη jsonb, μπορείτε να ορίσετε μια νέα τιμή στην καθορισμένη διαδρομή:

Οι παραπάνω επιλογές θα επιστρέψουν:

[{“type”: “phone”, “value”: “+1–202–555–0105”}, {“type”: “email”, “value”: “[email protected]”}] [{“type”: “email”, “value”: “[email protected]”}]

Για να αλλάξετε το email του Jimi στη λίστα επαφών, ενημερώνετε τη διαδρομή " 1, τιμή" που σημαίνει το δεύτερο αντικείμενο στον πίνακα (ξεκινώντας από το 0) και την τιμή κλειδιού . Αυτό είναι το μονοπάτι . Το ίδιο ισχύει και για την αλλαγή του email του Janis, αλλά το αντικείμενο του email βρίσκεται στο ευρετήριο 0.

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

Το πρόβλημα με τα μη σχεσιακά δεδομένα είναι ότι είναι δυναμικά. Λοιπόν, αυτός είναι ένας από τους λόγους για τη χρήση του JSONB, αλλά αυτό δημιουργεί ένα πρόβλημα: δείτε ότι το αντικείμενο email του Jimi βρίσκεται στο ευρετήριο 1 και το αντικείμενο email του Janis βρίσκεται στο ευρετήριο 0 στη συστοιχία και ένας άλλος πελάτης θα μπορούσε να έχει μια πολύ διαφορετική συστοιχία με διαφορετικά ευρετήρια . Λοιπόν, πώς μπορείτε να ανακαλύψετε το ευρετήριο κάθε τύπου επαφής; ;

Η απάντηση είναι η παραγγελία των στοιχείων του πίνακα και η λήψη του ευρετηρίου του:

Αυτό το ερώτημα επιστρέφει 1 , το οποίο είναι το ευρετήριο του αντικειμένου email (τύπος email) μέσα στον πίνακα επαφών του πελάτη Jimi.

Τώρα έχουμε όλα τα κομμάτια του παζλ: ξέρουμε πώς να ενημερώσουμε μια τιμή jsonb και πώς να ανακαλύψουμε το ευρετήριο του αντικειμένου που πρέπει να ενημερωθεί.

Το μόνο βήμα που απομένει είναι η ίδια η ενημέρωση. Συγκεντρώνοντας όλα έχουμε:

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

Επιτρέψτε μου να εξηγήσω λίγο για αυτό το μέρος:

(‘’)::text[] as path

Απλώς χτίζει τη διαδρομή ως "{1, value}" , αλλά πρέπει να μετατρέψουμε σε κείμενο [] γιατί αυτός είναι ο αναμενόμενος τύπος στη συνάρτηση jsonb_path .

Τυλίγοντας

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

Σημείωση: αυτή η λύση βγήκε από μια συνεδρία προγραμματισμού ζευγών με τον Lucas Cegatti.

Αναζητάτε μια δημιουργική εταιρεία για να εφαρμόσετε την επόμενη ιδέα σας; Δείτε τα συστήματα LNA και ας μιλήσουμε.