Apakah postgresql adalah sql atau nosql?

Ini keputusan besar. Ada banyak cerita horor tentang pengembang yang memilih database NoSQL dan kemudian menyesalinya

Tapi sekarang Anda bisa mendapatkan yang terbaik dari kedua dunia dengan JSON di PostgreSQL

Pada artikel ini saya membahas manfaat menggunakan JSON, anti-pola yang harus dihindari, dan contoh cara menggunakan JSON di Postgres

Daftar isi

Kapan Saya Akan Menggunakan Database SQL untuk Data Non-Relasional?

Pertama kita harus membahas secara singkat keuntungan menggunakan SQL vs NoSQL

Perbedaan antara SQL dan NoSQL adalah model datanya. Database SQL menggunakan model data relasional, dan database NoSQL biasanya menggunakan model dokumen. Perbedaan utama adalah bagaimana setiap model data menangani normalisasi data

Apakah postgresql adalah sql atau nosql?
Contoh normalisasi data dalam database sekolah

Normalisasi data adalah proses pemisahan data menjadi “bentuk normal” untuk mengurangi redundansi data. Konsep ini pertama kali diperkenalkan pada tahun 1970-an sebagai cara untuk mengurangi pengeluaran penyimpanan disk yang mahal

Dalam contoh di atas, kami memiliki diagram hubungan entitas yang dinormalisasi untuk database sekolah. Tabel

insert into LunchOrders values(100, '{
	"order_date": "2020-12-11",
	"order_details": {
    	"cost": 4.25,
        "entree": ["pizza"],
    	"sides": ["apple", "fries"],
    	"snacks": ["chips"]}
	}'      
);

insert into LunchOrders values(100, '{
	"order_date": "2020-12-12",
	"order_details": {
    	"cost": 4.89,
        "entree": ["hamburger"],
    	"sides": ["apple", "salad"],
    	"snacks": ["cookie"]}
	}'      
);
4 menyimpan setiap kelas yang telah diambil siswa. Dengan menormalkan data, kami hanya menyimpan satu baris untuk setiap kelas di tabel
insert into LunchOrders values(100, '{
	"order_date": "2020-12-11",
	"order_details": {
    	"cost": 4.25,
        "entree": ["pizza"],
    	"sides": ["apple", "fries"],
    	"snacks": ["chips"]}
	}'      
);

insert into LunchOrders values(100, '{
	"order_date": "2020-12-12",
	"order_details": {
    	"cost": 4.89,
        "entree": ["hamburger"],
    	"sides": ["apple", "salad"],
    	"snacks": ["cookie"]}
	}'      
);
5, alih-alih menduplikasi data kelas untuk setiap siswa di kelas

Tetapi bagaimana jika kita juga ingin melacak setiap pesanan makan siang (hidangan, pendamping, minuman, makanan ringan, dll) untuk mengirimkan ringkasan kepada setiap siswa di akhir setiap minggu?

Dalam hal ini akan lebih masuk akal untuk menyimpan data dalam satu dokumen daripada menormalkannya. Siswa akan selalu diperlihatkan seluruh pesanan makan siang mereka, jadi kami dapat menghindari bergabung yang mahal dengan menyimpan data pesanan makan siang bersama

{
	"student_id": 100,
    "order_date": "2020-12-11",
	"order_details": {
    	"cost": 5.87,
        "entree": ["pizza"],
        "sides": ["apple", "fries"],
        "snacks": ["chips"]
	}
}
Contoh skema pesanan makan siang menggunakan JSON

Alih-alih mempertahankan basis data NoSQL terpisah, kini kami  menyimpan pesanan makan siang sebagai objek JSON di dalam basis data Postgres relasional yang ada

Apa itu JSON?

{
	"student_id": 100,
    "order_date": "2020-12-11",
	"order_details": {
    	"cost": 5.87,
        "entree": ["pizza"],
        "sides": ["apple", "fries"],
        "snacks": ["chips"]
	}
}
JSON Examplestudent_idIntegerorder_dateDateorder_detailsObjectsidesArray

JSON, atau Notasi Objek Javascript, adalah format yang fleksibel untuk meneruskan data antar aplikasi, mirip dengan file csv. Namun, alih-alih baris dan kolom, objek JSON adalah kumpulan pasangan kunci/nilai

Menurut Stack Overflow, JSON sekarang menjadi format pertukaran data paling populer, mengalahkan csv, yaml, dan xml

Pencipta asli JSON, Douglas Crockford, mengaitkan keberhasilan JSON dengan keterbacaannya oleh pengembang dan mesin, mirip dengan mengapa SQL dominan selama hampir 50 tahun.

Format JSON mudah dipahami, tetapi juga cukup fleksibel untuk menangani tipe data primitif dan kompleks

Evolusi JSON di PostgreSQL

Jenis JSON biasa

Pada tahun 2012, PostgreSQL 9. 2 memperkenalkan tipe data

insert into LunchOrders values(100, '{
	"order_date": "2020-12-11",
	"order_details": {
    	"cost": 4.25,
        "entree": ["pizza"],
    	"sides": ["apple", "fries"],
    	"snacks": ["chips"]}
	}'      
);

insert into LunchOrders values(100, '{
	"order_date": "2020-12-12",
	"order_details": {
    	"cost": 4.89,
        "entree": ["hamburger"],
    	"sides": ["apple", "salad"],
    	"snacks": ["cookie"]}
	}'      
);
_6 pertama di Postgres. Itu memiliki validasi sintaks tetapi di bawahnya menyimpan dokumen yang masuk secara langsung sebagai teks dengan spasi putih disertakan. Itu tidak terlalu berguna untuk kueri dunia nyata, pencarian berbasis indeks, dan fungsi lain yang biasanya Anda lakukan dengan dokumen JSON

JSONB

Pada akhir 2014, PostgreSQL 9. 4 memperkenalkan tipe data

insert into LunchOrders values(100, '{
	"order_date": "2020-12-11",
	"order_details": {
    	"cost": 4.25,
        "entree": ["pizza"],
    	"sides": ["apple", "fries"],
    	"snacks": ["chips"]}
	}'      
);

insert into LunchOrders values(100, '{
	"order_date": "2020-12-12",
	"order_details": {
    	"cost": 4.89,
        "entree": ["hamburger"],
    	"sides": ["apple", "salad"],
    	"snacks": ["cookie"]}
	}'      
);
_7 dan yang terpenting meningkatkan efisiensi kueri dengan menambahkan pengindeksan

Tipe data

insert into LunchOrders values(100, '{
	"order_date": "2020-12-11",
	"order_details": {
    	"cost": 4.25,
        "entree": ["pizza"],
    	"sides": ["apple", "fries"],
    	"snacks": ["chips"]}
	}'      
);

insert into LunchOrders values(100, '{
	"order_date": "2020-12-12",
	"order_details": {
    	"cost": 4.89,
        "entree": ["hamburger"],
    	"sides": ["apple", "salad"],
    	"snacks": ["cookie"]}
	}'      
);
7 menyimpan JSON sebagai tipe biner. Ini memperkenalkan overhead dalam pemrosesan karena ada konversi yang terlibat tetapi menawarkan kemampuan untuk mengindeks data menggunakan pengindeksan berbasis GIN/Teks lengkap dan menyertakan operator tambahan untuk kueri yang mudah

JSONPath

Dengan semakin populernya JSON, Standar SQL 2016 menghadirkan bahasa   standar/jalur baru untuk menavigasi data JSON. Ini adalah cara ampuh untuk     menelusuri data JSON yang sangat mirip dengan XPath untuk data XML. PostgreSQL 12 memperkenalkan dukungan untuk standar JSON Path

Kita akan melihat contoh JSON, JSONB, dan JSONPath pada bagian di bawah ini. Hal penting yang perlu diperhatikan adalah bahwa semua fungsionalitas JSON hadir secara native di database. Tidak perlu modul contrib atau paket eksternal untuk diinstal

Contoh JSON di Postgres

Mari buat tabel Postgres untuk menyimpan pesanan makan siang dengan tipe data JSON

create table LunchOrders(student_id int, order json);

Sekarang kita bisa memasukkan data berformat JSON ke dalam tabel kita dengan pernyataan

insert into LunchOrders values(100, '{
	"order_date": "2020-12-11",
	"order_details": {
    	"cost": 4.25,
        "entree": ["pizza"],
    	"sides": ["apple", "fries"],
    	"snacks": ["chips"]}
	}'      
);

insert into LunchOrders values(100, '{
	"order_date": "2020-12-12",
	"order_details": {
    	"cost": 4.89,
        "entree": ["hamburger"],
    	"sides": ["apple", "salad"],
    	"snacks": ["cookie"]}
	}'      
);
9

insert into LunchOrders values(100, '{
	"order_date": "2020-12-11",
	"order_details": {
    	"cost": 4.25,
        "entree": ["pizza"],
    	"sides": ["apple", "fries"],
    	"snacks": ["chips"]}
	}'      
);

insert into LunchOrders values(100, '{
	"order_date": "2020-12-12",
	"order_details": {
    	"cost": 4.89,
        "entree": ["hamburger"],
    	"sides": ["apple", "salad"],
    	"snacks": ["cookie"]}
	}'      
);

Jika Anda melakukan

create table LunchOrders(student_id int, orders jsonb);
_0  dari tabel, Anda akan melihat sesuatu seperti di bawah ini

Apakah postgresql adalah sql atau nosql?
Dapatkan objek JSON. Editor SQL. Jenis busur

Memasukkan data ke kolom

insert into LunchOrders values(100, '{
	"order_date": "2020-12-11",
	"order_details": {
    	"cost": 4.25,
        "entree": ["pizza"],
    	"sides": ["apple", "fries"],
    	"snacks": ["chips"]}
	}'      
);

insert into LunchOrders values(100, '{
	"order_date": "2020-12-12",
	"order_details": {
    	"cost": 4.89,
        "entree": ["hamburger"],
    	"sides": ["apple", "salad"],
    	"snacks": ["cookie"]}
	}'      
);
_7 persis sama, kecuali kami mengubah tipe data menjadi
create table LunchOrders(student_id int, orders jsonb);
2

create table LunchOrders(student_id int, orders jsonb);

Cara Meminta Data JSON di Postgres

Meminta data dari objek JSON menggunakan operator yang sedikit berbeda dari yang kami gunakan untuk tipe data biasa (

create table LunchOrders(student_id int, orders jsonb);
3,
create table LunchOrders(student_id int, orders jsonb);
4 ,
create table LunchOrders(student_id int, orders jsonb);
5, dll)

Berikut adalah beberapa operator JSON yang paling umum

OperatorDescription->Pilih pasangan kunci/nilai->>Filter hasil kueri#>Memilih objek bersarang#>>Filter hasil kueri dalam objek bersarang@>Periksa apakah objek berisi nilai

Daftar lengkap operator JSON

Operator

create table LunchOrders(student_id int, orders jsonb);
_6 dan
create table LunchOrders(student_id int, orders jsonb);
7 bekerja dengan tipe data
insert into LunchOrders values(100, '{
	"order_date": "2020-12-11",
	"order_details": {
    	"cost": 4.25,
        "entree": ["pizza"],
    	"sides": ["apple", "fries"],
    	"snacks": ["chips"]}
	}'      
);

insert into LunchOrders values(100, '{
	"order_date": "2020-12-12",
	"order_details": {
    	"cost": 4.89,
        "entree": ["hamburger"],
    	"sides": ["apple", "salad"],
    	"snacks": ["cookie"]}
	}'      
);
6 dan
insert into LunchOrders values(100, '{
	"order_date": "2020-12-11",
	"order_details": {
    	"cost": 4.25,
        "entree": ["pizza"],
    	"sides": ["apple", "fries"],
    	"snacks": ["chips"]}
	}'      
);

insert into LunchOrders values(100, '{
	"order_date": "2020-12-12",
	"order_details": {
    	"cost": 4.89,
        "entree": ["hamburger"],
    	"sides": ["apple", "salad"],
    	"snacks": ["cookie"]}
	}'      
);
7. Operator lainnya adalah operator pencarian teks lengkap dan hanya bekerja dengan tipe data
insert into LunchOrders values(100, '{
	"order_date": "2020-12-11",
	"order_details": {
    	"cost": 4.25,
        "entree": ["pizza"],
    	"sides": ["apple", "fries"],
    	"snacks": ["chips"]}
	}'      
);

insert into LunchOrders values(100, '{
	"order_date": "2020-12-12",
	"order_details": {
    	"cost": 4.89,
        "entree": ["hamburger"],
    	"sides": ["apple", "salad"],
    	"snacks": ["cookie"]}
	}'      
);
7

Mari kita lihat beberapa contoh cara menggunakan setiap operator untuk mengkueri data di tabel

select orders -> 'order_date'
from lunchorders
where student_id = 100;
1 kita

Mendapatkan nilai dari objek JSON

Kita dapat menggunakan operasi

create table LunchOrders(student_id int, orders jsonb);
_6 untuk menemukan setiap hari bahwa siswa tertentu membeli makan siang sekolah

select orders -> 'order_date'
from lunchorders
where student_id = 100;
Apakah postgresql adalah sql atau nosql?
Pilih data JSON. Editor SQL. Jenis Arktik

Memfilter data JSON menggunakan klausa ________22______3

Kami dapat menggunakan operator

create table LunchOrders(student_id int, orders jsonb);
_7 untuk memfilter pesanan makan siang saja pada tanggal tertentu

select orders
from lunchorders
where orders ->> 'order_date' = '2020-12-11';
Apakah postgresql adalah sql atau nosql?
Filter JSON menurut tanggal. Editor SQL. Jenis Arktik

Kueri ini mirip dengan operator

create table LunchOrders(student_id int, orders jsonb);
_3 yang biasanya kita gunakan, kecuali kita harus terlebih dahulu menambahkan operator
create table LunchOrders(student_id int, orders jsonb);
7 untuk memberi tahu Postgres bahwa bidang
select orders -> 'order_date'
from lunchorders
where student_id = 100;
7 ada di kolom
select orders -> 'order_date'
from lunchorders
where student_id = 100;
8

Mendapatkan data dari array di objek JSON

Katakanlah kita ingin menemukan setiap lauk yang dipesan oleh siswa tertentu

Bidang

select orders -> 'order_date'
from lunchorders
where student_id = 100;
_9 bersarang di dalam objek
select orders
from lunchorders
where orders ->> 'order_date' = '2020-12-11';
0, tetapi kita dapat mengaksesnya dengan menggabungkan dua operator
create table LunchOrders(student_id int, orders jsonb);
6 bersama-sama

select
  orders -> 'order_date',
  orders -> 'order_details' -> 'sides'
from
  lunchorders
where
  student_id = 100;
Apakah postgresql adalah sql atau nosql?
Mendapatkan nilai bersarang dari objek JSON. Editor SQL. Jenis Arktik

Hebat sekarang kami memiliki susunan sisi yang dipesan 100 siswa setiap hari. Bagaimana jika kita hanya menginginkan sisi pertama dalam array?

Apakah postgresql adalah sql atau nosql?
Mendapatkan nilai array pada indeks tertentu. Editor SQL. Jenis busur

Mengambil nilai bersarang dari objek JSON

Alih-alih menggabungkan beberapa operator

create table LunchOrders(student_id int, orders jsonb);
_6, kita juga dapat menggunakan operator
select orders
from lunchorders
where orders ->> 'order_date' = '2020-12-11';
4 untuk menentukan jalur untuk mengambil nilai bersarang

select orders #> '{order_details, sides}'
from lunchorders;
      ?column?      
--------------------
 ["apple", "fries"]
 ["apple", "salad"]
(2 rows)

Memeriksa apakah objek JSON berisi nilai

Katakanlah kami ingin melihat setiap pesanan yang dibuat oleh siswa yang memiliki salad pendamping. Kami tidak dapat menggunakan

create table LunchOrders(student_id int, orders jsonb);
_7 sebelumnya untuk memfilter karena
select orders -> 'order_date'
from lunchorders
where student_id = 100;
9 adalah larik nilai

Untuk memeriksa apakah array atau objek berisi nilai tertentu, kita dapat menggunakan operator

select orders
from lunchorders
where orders ->> 'order_date' = '2020-12-11';
7

{
	"student_id": 100,
    "order_date": "2020-12-11",
	"order_details": {
    	"cost": 5.87,
        "entree": ["pizza"],
        "sides": ["apple", "fries"],
        "snacks": ["chips"]
	}
}
0
{
	"student_id": 100,
    "order_date": "2020-12-11",
	"order_details": {
    	"cost": 5.87,
        "entree": ["pizza"],
        "sides": ["apple", "fries"],
        "snacks": ["chips"]
	}
}
1

JSONPath. Bos Terakhir

JSON Path adalah alat yang ampuh untuk mencari dan memanipulasi objek JSON dalam SQL menggunakan

  • Dot (. ) digunakan untuk akses anggota
  • Tanda kurung siku ("[]") digunakan untuk akses array
  • Array SQL/JSON diindeks 0, tidak seperti array SQL biasa yang dimulai dari 1

Fungsi bawaan

JSONPath juga menyertakan fungsi bawaan yang kuat seperti

select orders
from lunchorders
where orders ->> 'order_date' = '2020-12-11';
8 untuk menemukan panjang array

Mari gunakan fungsi JSONPath

select orders
from lunchorders
where orders ->> 'order_date' = '2020-12-11';
8 untuk mendapatkan setiap pesanan yang memiliki >= 1 camilan

{
	"student_id": 100,
    "order_date": "2020-12-11",
	"order_details": {
    	"cost": 5.87,
        "entree": ["pizza"],
        "sides": ["apple", "fries"],
        "snacks": ["chips"]
	}
}
2
Apakah postgresql adalah sql atau nosql?
Contoh fungsi bawaan JSONPath. Editor SQL. Jenis Arktik

Perbandingan tanpa pengecoran tipe

JSONPath juga memungkinkan perbandingan tanpa pengecoran tipe eksplisit

{
	"student_id": 100,
    "order_date": "2020-12-11",
	"order_details": {
    	"cost": 5.87,
        "entree": ["pizza"],
        "sides": ["apple", "fries"],
        "snacks": ["chips"]
	}
}
_3

Seperti inilah tampilan kueri yang sama dengan perbandingan JSON reguler kami

{
	"student_id": 100,
    "order_date": "2020-12-11",
	"order_details": {
    	"cost": 5.87,
        "entree": ["pizza"],
        "sides": ["apple", "fries"],
        "snacks": ["chips"]
	}
}
_4

Ringkasan operator JSON

Pada bagian ini kita membahas dasar-dasar bekerja dengan data JSON di Postgres termasuk

  • Memilih data menggunakan
    create table LunchOrders(student_id int, orders jsonb);
    
    6
  • Memfilter kueri menggunakan
    create table LunchOrders(student_id int, orders jsonb);
    
    _7
  • Memilih nilai bersarang menggunakan
    select orders
    from lunchorders
    where orders ->> 'order_date' = '2020-12-11';
    4
  • Memeriksa apakah array berisi nilai menggunakan
    select orders
    from lunchorders
    where orders ->> 'order_date' = '2020-12-11';
    7
  • Menggunakan JSONPath untuk bekerja dengan objek JSON

Kami telah melihat bahwa bekerja dengan data JSON bisa jadi rumit. Arctype adalah editor SQL modern dan gratis yang memudahkan bekerja dengan basis data

Apakah postgresql adalah sql atau nosql?
Contoh fungsi Build-in JSONPath. Editor SQL. Jenis busur

Jadi seberapa efisien operasi JSON ini?

Dengan tidak adanya indeks, mesin basis data harus memindai seluruh tabel untuk menemukan catatan yang disebut pemindaian berurutan

Apakah postgresql adalah sql atau nosql?
Menganalisis performa kueri JSON. Editor SQL. Jenis busur

Ini dengan cepat menjadi tidak realistis ketika data menjadi sangat besar dan waktu kueri menjadi sangat lambat

Pengindeksan JSON di Postgres

Untuk meningkatkan kinerja kueri, Postgres 9. 4 termasuk dukungan untuk indeks database. Indeks adalah struktur data tambahan untuk menyusun data sehingga lebih mudah untuk kueri

Saya telah membuat tabel sampel dengan 700 ribu baris untuk mendemonstrasikan bagaimana indeks basis data dapat meningkatkan kinerja kueri sebesar 350X untuk data JSON

PostgreSQL menawarkan dua jenis indeks untuk bekerja dengan data JSON

  • indeks B-Tree
  • Indeks GIN/indeks pencarian teks lengkap

Indeks B-Pohon

select
  orders -> 'order_date',
  orders -> 'order_details' -> 'sides'
from
  lunchorders
where
  student_id = 100;
_4 memiliki 770k baris dan berisi kolom
select
  orders -> 'order_date',
  orders -> 'order_details' -> 'sides'
from
  lunchorders
where
  student_id = 100;
5 yang menyimpan informasi buku dalam objek
insert into LunchOrders values(100, '{
	"order_date": "2020-12-11",
	"order_details": {
    	"cost": 4.25,
        "entree": ["pizza"],
    	"sides": ["apple", "fries"],
    	"snacks": ["chips"]}
	}'      
);

insert into LunchOrders values(100, '{
	"order_date": "2020-12-12",
	"order_details": {
    	"cost": 4.89,
        "entree": ["hamburger"],
    	"sides": ["apple", "salad"],
    	"snacks": ["cookie"]}
	}'      
);
7

{
	"student_id": 100,
    "order_date": "2020-12-11",
	"order_details": {
    	"cost": 5.87,
        "entree": ["pizza"],
        "sides": ["apple", "fries"],
        "snacks": ["chips"]
	}
}
5
{
	"student_id": 100,
    "order_date": "2020-12-11",
	"order_details": {
    	"cost": 5.87,
        "entree": ["pizza"],
        "sides": ["apple", "fries"],
        "snacks": ["chips"]
	}
}
6
{
	"student_id": 100,
    "order_date": "2020-12-11",
	"order_details": {
    	"cost": 5.87,
        "entree": ["pizza"],
        "sides": ["apple", "fries"],
        "snacks": ["chips"]
	}
}
7

Di tabel yang tidak diindeks, dibutuhkan

select
  orders -> 'order_date',
  orders -> 'order_details' -> 'sides'
from
  lunchorders
where
  student_id = 100;
7 untuk menemukan setiap buku yang ditulis oleh
select
  orders -> 'order_date',
  orders -> 'order_details' -> 'sides'
from
  lunchorders
where
  student_id = 100;
8

{
	"student_id": 100,
    "order_date": "2020-12-11",
	"order_details": {
    	"cost": 5.87,
        "entree": ["pizza"],
        "sides": ["apple", "fries"],
        "snacks": ["chips"]
	}
}
8
{
	"student_id": 100,
    "order_date": "2020-12-11",
	"order_details": {
    	"cost": 5.87,
        "entree": ["pizza"],
        "sides": ["apple", "fries"],
        "snacks": ["chips"]
	}
}
9

Sekarang mari buat indeks B-Tree pada kunci

select
  orders -> 'order_date',
  orders -> 'order_details' -> 'sides'
from
  lunchorders
where
  student_id = 100;
9 di objek JSON menggunakan
create table LunchOrders(student_id int, orders jsonb);
7

create table LunchOrders(student_id int, order json);
0

Sekarang kita dapat menguji peningkatan kinerja kueri dari menambahkan indeks

create table LunchOrders(student_id int, order json);
1
create table LunchOrders(student_id int, order json);
2

Waktu eksekusi berkurang dari 128ms ->. 091ms. Hampir 350x lebih cepat

Indeks B-Tree sangat berkinerja, tetapi tidak mendukung pencarian teks lengkap dan memerlukan indeks baru untuk setiap kunci di objek JSON. Mari kita lihat bagaimana kita dapat menggunakan Indeks GIN untuk menyelesaikan ini

Indeks GIN untuk pencarian teks lengkap

Jika kami mencoba memfilter penulis menggunakan operator penahanan,

select orders
from lunchorders
where orders ->> 'order_date' = '2020-12-11';
7, Postgres mengabaikan indeks B-Tree kami dan kembali ke pemindaian berurutan yang tidak efisien

create table LunchOrders(student_id int, order json);
3
create table LunchOrders(student_id int, order json);
4

Operator

select orders #> '{order_details, sides}'
from lunchorders;
_2 tidak menggunakan indeks BTree karena melakukan pencarian teks lengkap. Kami dapat membuat indeks GIN untuk menyelesaikan ini

create table LunchOrders(student_id int, order json);
5

Memecat kueri yang sama lagi menghasilkan percepatan yang signifikan

create table LunchOrders(student_id int, order json);
3
create table LunchOrders(student_id int, order json);
7

Selain pencarian teks lengkap, indeks GIN juga dapat digunakan untuk kunci lain dalam objek JSON yang sama

create table LunchOrders(student_id int, order json);
8
create table LunchOrders(student_id int, order json);
9

Indeks GIN juga mendukung beberapa kueri JSONPath, tetapi bergantung pada polanya, Anda mungkin perlu membuat indeks khusus yang serupa dengan indeks B-Tree

Pengindeksan adalah bagian penting dari setiap alur kerja database, dan ada beberapa pertimbangan tambahan untuk membuat indeks yang efisien

Hal yang Harus Dihindari. Anti-Pola JSON

Seperti halnya segala sesuatu dalam ilmu komputer, JSON bukanlah peluru perak. Ini menambahkan lebih banyak fleksibilitas pada model data relasional, tetapi masih ada beberapa anti-pola JSON yang harus diwaspadai

  • Pemodelan data relasional. JSON bukan pengganti untuk toko baris. JSON masih jauh lebih lambat daripada data berbasis baris biasa karena kurangnya statistik. Ini adalah batasan yang diketahui jika Anda berencana menggunakan JSON untuk kueri analitik karena tidak mungkin membuat statistik untuk arsitektur tanpa skema
  • Mengganti NoSQL. JSONB masih bukan pengganti sistem NoSQL (Dijelaskan secara rinci di bagian berikut)
  • Ukuran. Konten JSONB dan indeks GIN membutuhkan lebih banyak ruang (contoh di bawah) dan sulit untuk mempartisi tabel jika dibandingkan dengan data berbasis baris. Jadi seseorang harus sangat memperhatikan skala data karena PostgreSQL tidak dapat menskalakan secara horizontal seperti sistem database NoSQL lainnya
  • Bergabung. Sulit untuk melakukan normalisasi dengan relasi one-to-many, many-to-many dengan tipe JSON. JSON tidak dimaksudkan untuk data yang dinormalisasi dan melakukan penggabungan adalah anti-pola dan akan menyebabkan masalah kinerja

Tabel

select
  orders -> 'order_date',
  orders -> 'order_details' -> 'sides'
from
  lunchorders
where
  student_id = 100;
_4 menempati 236 MB,

insert into LunchOrders values(100, '{
	"order_date": "2020-12-11",
	"order_details": {
    	"cost": 4.25,
        "entree": ["pizza"],
    	"sides": ["apple", "fries"],
    	"snacks": ["chips"]}
	}'      
);

insert into LunchOrders values(100, '{
	"order_date": "2020-12-12",
	"order_details": {
    	"cost": 4.89,
        "entree": ["hamburger"],
    	"sides": ["apple", "salad"],
    	"snacks": ["cookie"]}
	}'      
);
0
insert into LunchOrders values(100, '{
	"order_date": "2020-12-11",
	"order_details": {
    	"cost": 4.25,
        "entree": ["pizza"],
    	"sides": ["apple", "fries"],
    	"snacks": ["chips"]}
	}'      
);

insert into LunchOrders values(100, '{
	"order_date": "2020-12-12",
	"order_details": {
    	"cost": 4.89,
        "entree": ["hamburger"],
    	"sides": ["apple", "salad"],
    	"snacks": ["cookie"]}
	}'      
);
1

Indeks GIN yang dibuat untuk pencarian teks lengkap lebih besar dari ukuran tabel itu sendiri

insert into LunchOrders values(100, '{
	"order_date": "2020-12-11",
	"order_details": {
    	"cost": 4.25,
        "entree": ["pizza"],
    	"sides": ["apple", "fries"],
    	"snacks": ["chips"]}
	}'      
);

insert into LunchOrders values(100, '{
	"order_date": "2020-12-12",
	"order_details": {
    	"cost": 4.89,
        "entree": ["hamburger"],
    	"sides": ["apple", "salad"],
    	"snacks": ["cookie"]}
	}'      
);
2
insert into LunchOrders values(100, '{
	"order_date": "2020-12-11",
	"order_details": {
    	"cost": 4.25,
        "entree": ["pizza"],
    	"sides": ["apple", "fries"],
    	"snacks": ["chips"]}
	}'      
);

insert into LunchOrders values(100, '{
	"order_date": "2020-12-12",
	"order_details": {
    	"cost": 4.89,
        "entree": ["hamburger"],
    	"sides": ["apple", "salad"],
    	"snacks": ["cookie"]}
	}'      
);
3

Karena harus menyimpan JSON dalam format indeks terbalik, ukurannya jauh lebih besar

Sekarang kita telah membahas keuntungan dan anti-pola dengan JSON di Postgres. Bagaimana cara membandingkannya dengan database NoSQL tradisional?

JSON dalam Database Postgres vs NoSQL

Pertama untuk menghilangkan kebingungan, NoSQL adalah singkatan dari "Not Only SQL" dan itu tidak berarti bahwa SQL tidak digunakan. Faktanya, banyak sistem NoSQL seperti Apache Spark dan Flink memiliki semacam antarmuka untuk SQL. SQL hanyalah standar bahasa kueri untuk mengambil/memanipulasi data

Untuk membandingkan sistem basis data, pertama-tama kita harus membahas beberapa teori basis data dengan teorema CAP

teorema CAP

CAP adalah singkatan dari

  • Konsistensi
  • Ketersediaan
  • Toleransi partisi

Teorema tersebut menyatakan bahwa tidak mungkin penyimpanan data terdistribusi memiliki ketiga sifat tersebut

  • PostgreSQL adalah sistem CA
  • Cassandra adalah sistem AP
  • Mongo DB adalah sistem CA secara default

Database yang berbeda memiliki tujuan yang berbeda. Apa pun tipe data yang ditawarkan PostgreSQL, pada akhirnya akan menjadi database relasional dan akan berada di dalam bagian CA dari teorema CAP

Transaksi

Transaksi ACID biasanya sulit untuk diskalakan di beberapa mesin. Inilah alasan mengapa replikasi di PostgreSQL atau basis data relasional apa pun dilakukan melalui Write Ahead Log atau WAL log

Ini berarti transaksi hanya dikirim melalui kabel setelah ditulis ke log WAL, memastikan bahwa ada konsistensi di seluruh instance database yang berbeda. Ini sangat berbeda dari tingkat konsistensi Cassandra (BASE) yang menskalakan beberapa node dan menggunakan sesuatu yang disebut konsistensi akhirnya

Model Data

  • Mongo DB adalah toko dokumen
  • Cassandra adalah toko keluarga kolom
  • PostgreSQL adalah toko baris DB relasional

Pada akhirnya, PostgreSQL masih merupakan model data relasional dan tidak memiliki semua fitur database NoSQL seperti pipa agregasi.

Saat Anda mencoba memodelkan data di PostgreSQL, praktik terbaiknya adalah tetap default ke model relasional dan hanya menggunakan JSON jika masuk akal

Pada artikel ini kita telah membahas

  • Kapan menggunakan SQL vs NoSQL
  • Sejarah JSON di Postgres
  • Contoh cara bekerja dengan data JSON
  • Performa kueri JSON dengan pengindeksan
  • Anti-pola JSON

Postgres tidak dapat menggantikan database NoSQL, tetapi ini bisa menjadi solusi yang bagus untuk data independen dan menyelamatkan Anda dari membuat database NoSQL terpisah

PostgreSQL telah berkembang begitu banyak sejak hari-hari awal, dan kesenjangan antara sistem database yang berbeda semakin sempit

Data JSON mungkin sulit dikelola dari baris perintah. Unduh Arctype hari ini untuk bekerja dengan JSON dalam editor SQL modern yang gratis

Apakah Postgres adalah database SQL atau NoSQL?

Database relasional open source yang kuat dan andal . supports both SQL (relational) and JSON (non-relational) querying.

Apakah Postgres bukan SQL DB?

PostgreSQL adalah RDBMS tradisional (sistem manajemen database relasional) database SQL , seperti Oracle dan MySQL. PostgreSQL gratis. MongoDB adalah database tanpa skema, noSQL, JSON.

Apa perbedaan antara NoSQL dan PostgreSQL?

MongoDB adalah database non-relasional, sedangkan PostgreSQL adalah database relasional . Sementara database NoSQL bekerja untuk menyimpan data dalam key-value pair sebagai satu record, database relasional menyimpan data pada tabel yang berbeda.

Apakah PostgreSQL SQL atau MySQL?

Baik PostgreSQL dan MySQL mengandalkan SQL (Structured Query Language), bahasa standar untuk interaksi dengan sistem manajemen.