22 Mayıs 2020 Cuma

Sütun Tipleri - jsonb - Binary Formattadır, Whitespace İçermez

Giriş
Açıklaması şöyle. JSONB tipi 2014 yılında PostgreSQL 9.4 ile eklendi
In late 2014, PostgreSQL 9.4 introduced the JSONB datatype and most importantly improved the querying efficiency by adding indexing. 

The JSONB datatype stores JSON as a binary type. This introduced overhead in processing since there was a conversion involved, but it offered the ability to index the data using GIN/Full text-based indexing and included additional operators for easy querying.
Açıklaması şöyle. Binary formatta olduğu için whitespace saklamaz.
In Postgres, JSONB is a special kind of column that can store JSON in a format optimized for reads:
json Sütun Tipi ile Farkı
Açıklaması şöyle
Postgres support two forms of JSON types.
json — storing data as textual form in databases
jsonb — storing data as binary form in databases
Kısa Bir Uyarı
Her şeyi JSONB olarak saklamak iyi bir fikir gibi gelebilir. Ancak dikkatli olmak lazım çünkü daha sonra veriyi değiştirmek zor olabiliyor. Açıklaması şöyle.
PostgreSQL has json support – but you shouldn’t use it for the great majority of what you’re doing. This goes for hstore too, and the new jsonb type. These types are useful tools where they’re needed, but should not be your first choice when modelling your data in PostgreSQL, as it’ll make querying and manipulating it harder.
Constraint
Açıklaması şöyle. JSONB sütuna constraint koyulamaz.
Postgres cannot have primary and foreign key constraints on JSONB properties, but it can extract the properties into separate columns on inserts and updates, and those columns can have the constraints.
Index
JSONB sütuna GIN Index konulabilir.

Örnek
Whitespace saklamadığını görmek için şöyle yaparız.
SELECT '{"c":0,   "a":2,"a":1}'::json, '{"c":0,   "a":2,"a":1}'::jsonb;

          json          |        jsonb 
------------------------+--------------------- 
 {"c":0,   "a":2,"a":1} | {"a": 1, "c": 0} 
(1 row)
Select İşlemi
Açıklaması şöyle
The magical @> operator allows you to easily match a key-value pair or an object inside your JSON. It indeed makes easier to match things in JSON, although there are some things you should keep in mind:

- The operator @> behaves as equals comparisons if we search for an attribute
- The operator @> behaves as contains if we search for an array
Örnek
Attribute select için şöyle yaparız.
SELECT address->'city' FROM users WHERE address @> '{"zipcode": "94537"}'
Örnek
Attribute select için şöyle yaparız. Burada doc tablosundan silinen satırlar, child_table tablosuna ekleniyor.
INSERT INTO child_table SELECT doc FROM (
  DELETE FROM docs WHERE doc @> jsonb_build_object('type', 'doc_type') RETURNING doc
);
Array
Array contains için şöyle yaparız.
SELECT * FROM users WHERE address @> '{"entrances":[{"name": "backyard"}]}'
Insert İşlemi

Örnek
Şöyle yaparız. JSON '{...}' içine alınır. Key ve value değerleri çift tırnak içine alınır.
INSERT INTO users VALUES (1, 'First User', 'user1''{"streetName": "Wayside Lane", "houseNumber": 3104, "zipcode": "94538"}');
Update İşlemi
JSONB_SET() metodu kullanılır. İlk parametresi sütun ismi, ikinci parametre key, üçüncü parametre yeni value değeridir.

-> operator attribute değerini text'e çevirmek için kullanılır.

Örnek
Şöyle yaparız.
UPDATE users SET address = jsonb_set(address, '{state}', '"California"')
  WHERE address->'state' = '"CA"';
JPA İle Kullanım
jsonb - JPA İle Kullanım yazısına taşıdım

5 Mayıs 2020 Salı

Sütun Tipleri - Serial (Otomatik Sayı Üretir) - Kullanmayın

Giriş
Açıklaması şöyle. Yani SERIAL yerine IDENTITY kullanılırsa daha iyi
It is recommended to use IDENTITY instead since SERIAL has some weird behaviors.
Serial iki çeşit. Bunlar
1. SERIAL
2. BIGSERIAL

Bu sütunlara NOT NULL + PRIMARY KEY + UNIQUE gibi özellikler de atanabilir.

Diğer
Eğer serial veya bigserial yerine sequence kullanmak istersek şöyle yaparız
CREATE TABLE public.contacts
(
  contactid integer NOT NULL DEFAULT nextval('contacts_contactid_seq'::regclass),
  ...
);
1. SERIAL Sütun Tipi
Açıklaması şöyle
the keyword serial is PostgreSQL specific and it set up an auto-incrementing value and that is the typical way for the primary-key.
Açıklaması şöyle. 4 byte uzunluğundadır. Yani integer ile aynıdır.
Serial is just syntactic sugaring on top of an int column that takes its value from a sequence.
Açıklaması şöyle. Eğer transaction başarısız olsa bile serial numarası artmaya devam eder.
To avoid blocking concurrent transactions that obtain numbers from the same sequence, a nextval operation is never rolled back; that is, once a value has been fetched it is considered used, even if the transaction that did the nextval later aborts. This means that aborted transactions might leave unused "holes" in the sequence of assigned values.
Örnek
Şöyle yaparız.
create table testtable(
  id serial primary key,
  data integer not null
);
Şöyle yaparız.
insert into testtable ( data ) values ( 4 ), ( 5 ), ( 6 ), ( 7 );
Örnek
Şöyle yaparız
CREATE SCHEMA retail;
CREATE TABLE retail.orders_info (
  orderid SERIAL NOT NULL PRIMARY KEY,
  ...
);
Cache Parametresi
Açıklaması şöyle.
SERIAL columns are implemented using standard SQL sequences, which might generate out-of-order values when used by multiple concurrent sessions if the CACHE parameter is set to something more than 1
Daha detaylı açıklama şöyle.
Although multiple sessions are guaranteed to allocate distinct sequence values, the values might be generated out of sequence when all the sessions are considered. For example, with a cache setting of 10, session A might reserve values 1..10 and return nextval=1, then session B might reserve values 11..20 and return nextval=11 before session A has generated nextval=2. Thus, with a cache setting of one it is safe to assume that nextval values are generated sequentially; with a cache setting greater than one you should only assume that the nextval values are all distinct, not that they are generated purely sequentially.
2. BIGSERIAL Sütun Tipi
Örnek
Şöyle yaparız
CREATE TABLE foo (
  id BIGSERIAL PRIMARY KEY,
  ...
);

CREATE TABLE bar (
  foo_id BIGINT UNIQUE,
  ...
);
Örnek
Şöyle yaparız.
CREATE TABLE category
(
  id bigserial NOT NULL PRIMARY KEY,
  ...
)

23 Mart 2020 Pazartesi

PostGIS ST_MakePoint

Giriş
Açıklaması şöyle.
SRID 4326 is assumed if unspecified. 
GEOGRAPHY tipindeki sütünlara değer atamak içindir.

Örnek
Elimizde şöyle bir tablo olsun
CREATE TABLE foo (geog GEOGRAPHY);
Şöyle yaparız.
INSERT INTO foo (geog) VALUES (ST_MakePoint(12.234,23.22));
Örnek - ST_SetSRID İçinde Kullanımı
Şöyle yaparız.
INSERT INTO foo (geog) 
 VALUES (ST_SetSRID(ST_MakePoint(-122.079513,45.607703), 4326));
Açıklaması şöyle.
ST_SetSRID will set the coordinate reference system of your geometry. This will allow PostGIS commands to understand how your grid will relate to other geometries.

Using ST_SetSRID is not essential, as long as all other geometries you may query against are known to be on the same grid. However, if you query against another table that has a SRID set, even if it is known to be of the same grid, PostGIS will fail with a 'mixed geometries' error, which is only resolved when both tables have the same SRID value.

27 Şubat 2020 Perşembe

PG_CLASS Sistem Tablosu

relkind Sütunu
Örnek
Veri tabanındaki sequence'leri görmek için şöyle yaparız
SELECT c.relname FROM pg_class c WHERE c.relkind = 'S';
relname  Sütunu
Örnek
Veri tabanındaki temporary table'ları görmek için şöyle yaparız
CREATE TEMPORARY TABLE t0 (key0 integer);
SELECT relfilenode FROM pg_class WHERE relname = 't0';
TRUNCATE t0;
SELECT relfilenode FROM pg_class WHERE relname = 't0';

19 Ocak 2020 Pazar

Two Phase Commit (2PC)- Distributed Transaction İçindir

Giriş
Distributed Transaction Management için 7 farklı çözüm var. Bunlar şöyle
1. Two-phase commit/XA
2. SAGA
3. TCC (Try, Confirm, Cancel)
4. Local Messaging
5. Transactional Messaging
6. Best-effort Notification
7. Seata-AT

Local Messaging ve Transactional Messaging
Transaction destekleyen ve persistent olan mesaj kuyruğu (message queue) kullanarak gerçekleştirilir.

XA ve JTA İlişkisi
XA standardın ismi. X/Open organizasyonu tarafından yönetiliyor. Açıklaması şöyle
XA is a specification for distributed transactions proposed by the X/Open organization. The XA specification mainly defines the interface between a (global) Transaction Manager (TM) and a (local) Resource Manager (RM). Local databases such as mysql play the RM role in the XA specification.
JTA ise Java gerçekleştirimi. Açıklaması şöyle
Two-phase commit(2PC) is a blocking protocol used to guarantee that all the transactions are succeeded or failed together in a distributed transaction.

The XA standard is a specification for the 2PC distributed transactions. JTA includes standard API for XA. JTA-compliant application servers support XA out-of-the-box. But all the resources have to be deployed to a single JTA platform to run 2PC. 
XA Bileşenleri
İki tane bileşen var. 
1. Transaction Manager 
2. Resource Manager
3. Application Program - Bu aslında bileşen sayılmayabilir
 Açıklaması şöyle
The XA specification mainly defines the interface between a (global) Transaction Manager (TM) and a (local) Resource Manager (RM). Local databases such as mysql play the RM role in the XA specification.
Two Phase Commit Gerçekleştirimi
İki tane yöntem var.
1. 2PC destekleyen veri tabanı kullanmak
2. Distributed Transaction Manager kullanmak
Açıklaması şöyle. Distributed Transaction Manager olarak Atomikos kullanılabilir
Database Management Systems
Many database management systems, such as Oracle, MySQL, and PostgreSQL, provide support for 2PC out-of-the-box. 

Distributed Transaction Managers
Distributed transaction managers, such as JBoss Transactions, provide support for 2PC and can be used to manage transactions across multiple nodes. When using a distributed transaction manager, you can use 2PC by configuring the transaction manager to use 2PC as the transaction management mechanism.

Hangi Veri Tabanları XA Destekler
 Açıklaması şöyle
At present, almost all mainstream databases support XA transactions, including mysql, oracle, sql-server, postgres
Hangi Durumlarda Kullanılır
Strong Consistency (linearizability) gerekiyorsa kullanılır. 

Özellikle
1. Database Replication Varsa
2. Farklı Sistemler Varsa

Açıklaması şöyle
Other than the above database replication scenario for scalability, 2PC is also used when executing transactions between different types of systems such as database servers and message brokers. However, we generally avoid 2PC because of increased lock contention in distributed participants, which leads to poor performance, and hinders scalability. 
Akış Nasıldır?
Şeklen şöyle

Açıklaması şöyle
- Prepare: The participant is asked to check if its data operation can be performed and provide a promise to the transaction coordinator that later on if required, it can commit the operation or rollback. This is done for all the participants. 

- Commit: If all the participants said okay in the prepare phase, each participant is given a commit operation to commit the earlier mentioned operation. At this point, the participant cannot deny the operation, due to the promise given to the transaction coordinator earlier. If any of the participants earlier denied their local data operation due to any reason, the coordinate will send rollback commands to all the participants. 
Örnek
Şeklen şöyle


Voting Aşaması
Eğer tüm sistemler evet cevabını veriyorsa veri bitmiş olarak kabul edilir. Bu aşamaya voting denilir.

Klasik Coordinator Kullanımı
Açıklaması şöyle.
- The Coordinator service asks all the participants if they are ready to commit the transaction. They can reply with a yes or no. Note that if a single service replies with a no ( or a timeout or any other error), the full transaction is automatically canceled.

- If all the participants have answered yes, the Coordinator sends the Commit command to them and waits for the final ack.
Bu yöntemin dezavantajları şöyle.
- First of all, it comes with an intrinsic performance penalty as we're putting all the actors on hold multiple times waiting for an answer. - Secondly, in some cases, it may be possible that other transactions triggered in between are paused until the whole process completes.
- If the Coordinator fails for some reason at the beginning of Phase 2, all the other services are left hanging in a limbo-state.
Coordinator Olmadan Kullanımı
Örneğin kaynağı burası.

1. Two Phase Commit Kullanılmazsa
Bu yöntemin kullanılmadığı şöyle bir senaryo olsun.

Veri tabanına bir işlem yaptıktan sonra commit'lemeden REST çağrısı yapıp çağrı sonucuna göre rollback veya commit yapalım.

1. Eğer REST çağrısı başarılı ancak sonucu bize gelmezse transaction rollback edilir ve veri tutarsız olur
2. Eğer REST çağrısı başarılı ancak bizim commit işlemi başarısız ise veri tutarsız olur

2. İki Transaction Kullanan Two Phase Commit
Daha basit bir yöntem iki transaction kullanmak. Veri önce kendi veri tabanımıza yazılır ancak bitmiş olarak işaretlenmez. Daha sonra REST çağrısı yapılır. Eğer çağrı başarılı ise verimiz bitmiş olarak işaretlenir. Böylece işlem toplam üç transaction'a bölünür. İki tanesi ayrı veri tabanlarında gerçekleşir. Sonuncusu ise voting kabul edilir ve kendi veri tabanımızda gerçekleşir.

Outbox Pattern - Coordinator Olmadan Kullanımı
Açıklaması şöyle. Bu yöntemde tek transaction var ancak veri 2 tabloya yazılıyor.
This pattern provides an effective solution to publish events reliably. The idea of this approach is to have an “Outbox” table in the service’s database. When receiving a request for enrollment, not only an insert into the Student table is done, but a record representing the event is also inserted into the Outbox table. The two database actions are done as part of the same transaction.

An asynchronous process monitors the Outbox table for new entries and if there are any, it publishes the events to the Event Bus. The pattern merely splits the two transactions over different services, increasing reliability.


13 Ocak 2020 Pazartesi

PostGIS ST_Union

Örnek
Şöyle yaparız.
CREATE OR REPLACE VIEW _06_spildevand_vandloeb.drikkevandsledning_dissolve AS
  SELECT ROW_NUMBER() OVER() AS id, 
         ST_Union(the_geom)::GEOMETRY(MULTILINESTRING,25832) AS geom,  -- alias AS geom
         descr 
  FROM   _06_spildevand_vandloeb.ledninger_vand
  GROUP BY
         descr
;

2 Ocak 2020 Perşembe

GROUP BY - Aggregate Function İle Birlikte Kullanılır

Giriş
Açıklaması şöyle. GROUP BY içine SELECT edilen en az bir sütun ismi verilmeli. İstersek daha fazla da verebiliriz.
Each GROUP BY expression must contain at least one column that is not an outer reference
Aggregation Function
Açıklaması şöyle. Yani GROUP BY bir aggregate metod ile birlikte kullanılır. Bunlar SUM(),COUNT(),AVG() olabilir.
The real importance of GROUP BY can be seen when you use it with aggregate functions like SUM(), COUNT()
Açıklaması şöyle.
In most texts, GROUP BY is defined as a way of aggregating records by the specified columns which allow you to perform aggregation functions on non-grouped columns (such as SUM, COUNT, AVG, etc). In other words, the GROUP BY clause’s purpose is to summarize unique combinations of columns values.
Avg Aggregation Function
Örnek
Şöyle yaparız
SELECT department, AVG(salary) AS avg_salary
FROM employees
GROUP BY department;
Çıktısı şöyle
department | avg_salary
-----------------------
Sales      | 65000
Marketing  | 55000
Engineering| 80000
Count Aggregation Function
Count işlemi gruplamadan sonra 
- Tek tablo içinde yapılabilir.
- LEFT JOIN ile yapılabilir

Örnek - Tek Tablo İçinde Count
Şöyle yaparız. Burada GROUP BY içinde SELECT edilen bir sütun için kullanılıyor. COUNT() metodu aggregate olarak kullanılıyor.
SELECT style,COUNT(name) FROM beers GROUP BY style ORDER BY style
Örnek - Tek Tablo İçinde Count
Şöyle yaparız.  Burada GROUP BY içinde SELECT edilen iki sütun için kullanılıyor. COUNT() metodu aggregate olarak kullanılıyor.
SELECT style,brewery_id,COUNT(Name) FROM beers GROUP BY style,brewery_id ORDER BY style
Örnek - LEFT JOIN ile Count
Şöyle yaparız
SELECT products.*, COUNT(sold_products.id) AS total_sold
FROM products
LEFT JOIN sold_products ON sold_products.product_id = product.id
GROUP BY sold_products.product_id