CodeGym /Kurslar /SQL SELF /JSON-məlumatlarla işləyərkən tipik səhvlər və onların qar...

JSON-məlumatlarla işləyərkən tipik səhvlər və onların qarşısını alma yolları

SQL SELF
Səviyyə , Dərs
Mövcuddur

PostgreSQL-də JSON-məlumatlarla işləmək güclü bir alətdir, amma hər bir alət kimi, diqqətli yanaşma tələb edir. Hətta kiçik səhvlər belə sorğunu başağrısına çevirə bilər. Bu gün yenə də PostgreSQL-də JSON və JSONB ilə işləyərkən yaranan tipik səhvlərə və onların qarşısını alma yollarına fokuslanacağıq.

Problem 1: JSON əvəzinə JSONB istifadə etmək

Çox yeni başlayanlar JSON data tipini səhvən seçirlər, düşünürlər ki, bu, JSON formatında məlumat saxlamaq üçün ən yaxşı seçimdir. Amma PostgreSQL-də JSON məlumatı mətn (text) kimi saxlayır, bu isə axtarış və ya filtrasiya zamanı performansın aşağı düşməsinə səbəb ola bilər.

Səhv nümunəsi:

CREATE TABLE products (
    id SERIAL PRIMARY KEY,
    details JSON
);

INSERT INTO products (details) VALUES ('{"name": "Laptop", "price": 1000}');

INSERT INTO products (details) VALUES ('{"name": "Laptop", "price": 1000}');

Açar (price) üzrə filtrasiya etməyə çalışanda JSONB ilə müqayisədə xeyli yavaş işləyəcək.

Necə düzəltməli: əgər tez-tez filtrasiya və ya məlumatlara müraciət etməyi planlaşdırırsansa, JSONB istifadə et.

CREATE TABLE products (
    id SERIAL PRIMARY KEY,
    details JSONB
);

Problem 2: JSONB üçün indekslərin olmaması

JSONB — həqiqətən güclü bir alətdir, amma indekslər olmadan mürəkkəb sorğularda performansı ciddi şəkildə aşağı düşə bilər.

Səhv nümunəsi: təsəvvür et, details sütununda çoxlu JSON-obyektləri saxladığımız bir cədvəlimiz var:

SELECT * FROM products WHERE details->>'name' = 'Laptop';

Əgər məlumatlar indekslənməyibsə, server bütün qeydləri tam yoxlamalı olacaq (full table scan), bu isə çox vaxt aparacaq.

Necə düzəltməli: açarlar üzrə axtarışı sürətləndirmək üçün GIN indeksi yaradın:

CREATE INDEX idx_details_name ON products USING gin (details jsonb_path_ops);

Problem 3: İç-içə məlumatları çıxararkən səhvlər

İç-içə obyekt və ya massivlərdən məlumat çıxarmaq bəzən çaşqınlıq yarada bilər, xüsusilə də ->->> operatorlarının fərqini bilmirsənsə.

Səhv nümunəsi:

SELECT details->'price' FROM products;

Bu sorğu nəticəni JSON formatında qaytaracaq, yəni sətir yox ("1000" əvəzinə 1000). Əgər sənə məhz dəyər lazımdırsa, ->> istifadə et:

SELECT details->>'price' FROM products;

Problem 4: Operatorların səhv istifadəsi

Bəlkə də @> operatoru ilə rastlaşmısan və düşünmüsən: "Çox cool səslənir, həmişə bunu işlədim!" Amma necə işlədiyini başa düşmürsənsə, gözlənilməz nəticələr ala bilərsən.

Səhv nümunəsi:

SELECT * FROM products WHERE details @> '{"price": 1000}';

Bu sorğu yalnız price JSON-da rəqəm kimi saxlanılıbsa işləyəcək. Əgər dəyər sətir kimi saxlanılıbsa "1000", sorğu heç nə qaytarmayacaq.

Necə düzəltməli: JSON-da data tiplərinə diqqət et:

SELECT * FROM products WHERE details->>'price' = '1000';

Problem 5: Böyük JSON-obyektlər

Böyük JSON-obyektləri optimizasiya etmədən saxlamaq sorğuların işini xeyli ləngidə bilər. Üstəlik, JSONB-də hətta kiçik bir hissəni oxumaq və ya dəyişmək üçün bütün obyekt işlənməlidir.

Necə düzəltməli: əgər bəzi açarlar tez-tez istifadə olunursa, onları ayrıca sütun kimi çıxart. Məsələn:

ALTER TABLE products ADD COLUMN price NUMERIC;
UPDATE products SET price = (details->>'price')::NUMERIC;

İndi JSONB-ni parse etmədən rahat filtrasiya və sort edə bilərsən.

Problem 6: Dəyişiklik zamanı obyektin tam yenidən qurulması

jsonb_set() və ya jsonb_insert() kimi funksiyalardan istifadə edəndə, PostgreSQL tamamilə yeni bir JSONB obyekti yaradır, bu isə performans baxımından baha başa gələ bilər.

Necə düzəltməli: JSONB-də update-lərin sayını minimuma endir. Məsələn, bir obyektə tez-tez update etməkdənsə, bütün dəyişiklikləri bir sorğuda birləşdir:

UPDATE products
SET details = jsonb_set(details, '{price}', '1500'::jsonb);

Problem 7: Massivin strukturunu başa düşməmək

JSONB-də massivlərə də diqqətlə yanaşmaq lazımdır. Tutaq ki, belə bir massiv var:

{
    "tags": ["electronics", "laptop", "sale"]
}

Sən "laptop" tag-ının olub-olmadığını yoxlamaq istəyirsən. Əgər səhvən @> operatorunu işlədib sətir verirsənsə, nəticə ala bilməyəcəksən, çünki operator massiv gözləyir, sətir yox.

Səhv nümunəsi:

SELECT * FROM products WHERE details->'tags' @> '"laptop"';

Necə düzəltməli: @> operatorunda düzgün formatdan istifadə et:

SELECT * FROM products WHERE details->'tags' @> '["laptop"]';

Səhvlərin qarşısını almaq üçün tövsiyələr

JSONB ilə işləyərkən bir çox problemlərdən qaçmaq üçün bu tövsiyələrə əməl et:

Düzgün data tipini seç. Əgər böyük həcmdə məlumatla işləyirsənsə və tez-tez filtrasiya edirsənsə, həmişə JSONB istifadə et, JSON yox.

Məlumatı indekslə. Əgər sorğular tez-tez müəyyən açarlara müraciət edirsə, uyğun indeks yarat (məsələn, GIN).

Daxil etməzdən əvvəl məlumatı yoxla. Məlumat strukturunu yoxlamaq üçün validation funksiyalarından istifadə et:

DO $$
BEGIN
    IF jsonb_typeof('{"price": 1000}'::jsonb->'price') IS DISTINCT FROM 'number' THEN
        RAISE EXCEPTION 'Qiymət rəqəm olmalıdır';
    END IF;
END $$;

Məlumat strukturunu optimallaşdır. Əgər bəzi açarlar digərlərindən daha çox istifadə olunursa, onları ayrıca sütun kimi çıxart.

Operator və funksiyaları öyrən. PostgreSQL-in rəsmi sənədlərini diqqətlə oxu ki, ->, ->>, @>, ?| və digər funksiyaların fərqini yaxşı başa düşəsən.

JSON və JSONB çevik və mürəkkəb məlumatlarla işləməkdə sənin dostun ola bilər. Əsas odur ki, alətləri düzgün seç və tipik səhvlərdən qaç ki, kodun həm effektiv, həm də rahat dəstəklənən olsun.

1
Sorğu/viktorina
, səviyyə, dərs
Əlçatan deyil
JSON-obyektlərdə məlumatların yenilənməsi
JSON-obyektlərdə məlumatların yenilənməsi
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION