Repeat after me: SQL is not assembly

 ( dszakal | 2018. március 7., szerda - 12:17 )


SQL is not assembly.
ORM is not gcc/clang.

Evek alatt tobb projekten is ugy alakult, hogy en feladatomma valt az SQL-hez nyulo kodok optimalizalasa. Utobbi nehany reszben sajat projekten ez mar proaktivan tortenik: en magam seedelem fel millio sorokkal az adatbazist, hogy stresszteszteljem. Havonta egyszer viszont (offline vagy online) nagyarcu fejlesztokbe botlok, akik szerint nekik soha nem is kene SQL kodot irnia. Legutobb epp ket olyan bosszantott fel egymastol fuggetlenul, akikkel halistennek nem dolgozok es nem is fogok sosem egyutt dolgozni.

A legnagyobb tevedes sok fejleszto fejeben: az o kedvenc programozasi nyelveben (PHP, Java, etc.) lehet optimalis SQL kodot generalni. Mert hat erre van kitalalva az o ORM library-je, bitos jol meg van az irva.

WRONG

Se joint, se subquery-t nem lehet ugy generalni, hogy az az optimalisnal csak linearisan legyen lassabb. Minden ORM tud JOIN es/vagy subquery eseten az optimalisnal exponencialisan lassabbat generalni. Pont.

Mar kapasbol: egeszen maskepp irnek JOIN-okat MySQL-en es PostgreSQL-en. Utobbin editalhatod a query plant, elobbinel readonly. Raadasul MySQL-nel 5-6 tabla folott eleg random, hogy optimalis lesz-e a query: annyi mesterseges intelligencia nincs benne, hogy 3 parszazbajtos tablat kitranszformaljon egy switch case-ze. Lett mar MySQL-ben query-m szignifikansan gyorsabb amiatt, hogy 3 ilyen 3-30 soros tabla JOIN-jat kivettem es irtam helyette egy CASE-es SELECT oszlopot (switch SQL-ben). De meg olyannal is talalkoztam, hogy szignifikansan gyorsabb volt 3 query-t futtatni mint 1-et joinokkal. Meg olyat is, hogy a 2. 3. query kigeneralasanal tul hosszu lett a string az SQL szervernek.

"Jo, jo, de akkor te most tenyleg egyesevel megirsz minden INSERT-et/UPDATE-et, meg a switch-et ami ezt eldonti? Jo lassan fejleszthetsz"

JOIN-olni tudtommal csak olvasaskor szoktak.
Mint fentebb allitottam 'Se joint, se subquery-t nem lehet ugy generalni, hogy az az optimalisnal csak linearisan legyen lassabb'.
DE: single table read write-ot igen.
Erre a celra karban is tartom a sajat publikus fuggvenykonyvtaramat.

"Ezzel a fuggvenykonyvtarral osztod az eszt, mikor meg PDO-t meg prepared statementet sem tud?"

Az egyik legnagyobb projekt ami hasznalja egy kioszkokkal foglalkozo business. Ott fontos volt, hogy kigeneraljuk az INSERT query-ket es atadjuk futas nelkul. PDO+Prepared statement paros ezt nem tudja. Ha implementalnam a PDO-t prepared statementekkel, akkor a AutoRecord::generateInsertQuery() nem menne, vagy maskepp viselkedne.

Ettol fuggetlenul nem neveznem "elkeszultnek", elso eset, hogy "promotalni merem" az ez a blogbejegyzes. Meg van hova fejlodnie, de jelen allapotaban stabil. 10 projektrol tudok, ami hasznalja, amibol 5-nel nem talalkoztam a koddal sem. Lassan az olyan fuggvenykonyvtaramat hasznalo fejlesztok szama is eleri a ket szamjegyet, akikkel nem talalkoztam.

"Jo, de ha JOIN vagy subquery kell mit csinalsz?"

Az csak readhez kell: megirom kezzel az SQL-t es van egy rovid (az mar nem publikus, de barki megirja kb 30 sorban) "toolom" (kb egyetlen fuggveny) tobb nyelvhez is, ami az adott nyelv array-aba, hashmapjebe, {}-aba, stb.-jebe beteszi a resultot.

"De akkor SQL kodokat copy paste-elsz, tele van a kodod duplikaciokkal"

Nincs

public static function getStatusSqlColumnString($tableAlias = 'item')
...
public static function getDefaultWhereFilter($tableAlias = 'item')

Es a kedvencem: egyik vitapartneremnek jeleztem, hogy tobb fejleszto arra is keptelen volt, hogy specifikacionak megfeleloen letrehozzon 3 tablat, amik kozul az egyik az egy N to M relation kapcsolotabla lett volna. Valasza:

"Nalunk senki nem ir CREATE TABLE-t, frameworkkel csinalunk class-t es az kigeneralja a manyToMany()-vel egyutt"

WRONG

Itt nekem az aram is kiment az agyambol.

Ha valakinek ujat mondanek: a helyes sorrend uj feature eseten:
1. Megirod az SQL CREATE TABLE-t
2. Review-oljatok az CREATE TABLE-t es felmeritek az azzal kapcsolatos veszelyeket (beleertve azt is hogy deploy time-hoz kepest mikor kell leteznie az uj tablaknak/oszlopoknak/constrainteknek)
3. kigeneralod a review-olt SQL-re a skeleton kodot (a sajat libemhez van erre egy zart toolom, de kb 60 sorbol irsz egyet magadnak is)
4. megirod a kod tobbi reszet

Bonusz trollelemzes:

NoSQL

Hivjuk a NoSQL-eket inkabb nem relacios vagy nem teljes erteku relacios database engine-eknek. A NoSQL teves elnevezes. A Google is rajott: 3 uj "NoSQL" (relacios adatbazis definiciojanak nehany megszoritasat eldobo) technologiajahoz irt egy kozos SQL kompatibilis query language-t. Igen, mindharmon mukodik ugyanaz az SQL query szintaxis.

A problema amit a "NoSQL" megold, nem az "SQL, mint query language levaltasa"
A problema amit a NoSQL megold valojaban:
Teljes erteku relacios adatbazis motorok nehany definicio miatti megszoritasat (akar adatkonzisztenciat is) eldobva jobb lehetoseget nyujt irasi sebessegre, olvasasi sebessegre, skalazodasra, es/vagy valami egyebre.

NoSQL troll:
"Mar reg AkarmiDB-t kene hasznalni"

Ezzel semmi baj nincs. Csak valaszolja meg a kovetkezo kerdest:
"Milyen relacios adatbazisokban talalhato feature-rol mondott le az AakarmiDB, ezen keresztul mit nem lehet benne hasznalni, es cserebe mi az, ami emiatt jobban performol benne? Amit mi hasznalunk abban hol erjuk el a relacios adatbazisok perfromance hatarait, amit AkarmiDB-vel nem ernenk el?"

Ha ezt meg tudja ertelmesen valaszolni: oke, elfogadom, akar uj query language-t is megtanulok az SQL helyett
Ha erre a valasza: "Nem is kene SQL-t NoSQL-hez hasonlitani", vagy valami hasonlo tereles -> kuka

Szomoruan tapasztaltam, hogy nagyon keves NoSQL user/fan tartozik az elobbi kategoriaba :(

Hozzászólás megjelenítési lehetőségek

A választott hozzászólás megjelenítési mód a „Beállítás” gombbal rögzíthető.

A probléma abból adódik, hogy a relációs világ (a SQL nyelvvel együtt) teljesen más, mint az objektumos világ. Az ORM rétegek ezt a különbséget próbálják áthidalni, de valójában más modellt tervezel egy alkalmazáshoz, ha OO oldalról fogod meg, mintha relációs oldalról.

Én nagy ORM fan voltam mindig (elsősorban Hibernate/NHibernate-et ismerem), mert sosem rajongtam az SQL-ért. Kellett nekem is sokszor adatbázis teljesítményre optimalizálni, ami azért nem lehetetlen, ha nem félsz belenyúlni egy kicsit pl. a Hibernate mélyébe. Nekem legutóbb a join-okat kellett optimalizálnom illetve bevezetni group_aggr függvényt a JPA rétegbe, nem megoldhatatlan, és a végén sikerült csúnya hack-ek nélkül, de kellett Hibernate Dialect-et bővítenem.

Amitől az egész relációs-objektumos ORM probléma lesz, az hogy sokszor akkor is ORM-et használnak a fejlesztők, amikor nem kellene. Az oka ennek az, hogy az ORM réteget már ismerik a fejlesztők, nem kell SQL-el foglalkozniuk, bevált sok esetben. Így - mivel van egy jó kalapács - mindent szögnek néznek.

Azt viszont ne felejtsd el, hogy nem ért mindenki mindenhez, illetve nincs mindig idő hatékonyra csinálni. Az ORM rétegek meg igenis jól vannak megírva, ahhoz képest hogy mekkora szakadékot kell áthidaljanak, egészen jól teljesítenek. Csak hát ez nem mindig elég (vannak csavarok is, nem csak szögek...)

Ja igen, van még egy előnye az ilyen ORM és egyéb rétegeknek: az alkalmazás kódját lehet SQL motortól függetlenre készíteni, ami kimondottan kedvező a tesztelés/tesztelhetőség szempontjából. Ezt a saját custom lib-ed is tudja?

Kapasbol be is vezettel 3 fogalmat:
JPA reteg
Hibernate/NHibernate
Hibernate Dialect

Olyan jol ki van talalva az az SQL, miert kell ujrafeltalalni, rosszul?

"Ezt a sajat custom lib-ed is tudja?"

Tudja, a create table-okon kivul kb 3 sort kellett atirni hogy MySQL-es kod menjen Postgres-en miutan megirtam a pgsql backendet.

De egyelore csak MySQL-t es PostgreSQL-t tamogat. Ironikusan lehet hogy pont mssql-re kell nemsokara megcsinalnom (ott is cel helyette vegul masban tarolni).

Ellenben lattam mar ilyen "SQL engine-tol fuggetlen ORM megoldast" lehalni egy enumtol, mert "nem tamogatja minden motor" (le van szarva hogy epp olyat hasznaltam ami tamogatta, Exception es talald meg melyik retegbol)

"JOIN-olni tudtommal csak olvasaskor szoktak."

Velem jött azért már szembe hasonló is:

UPDATE T1
INNER JOIN T2 ON T1.C1 = T2.C1
LEFT JOIN T3 ON T2.C1 = T3.C1
SET T1.C2 = T2.C2
WHERE T3.C1 IS NULL

Evente egyszer velem is, de olyankor nem mertem nemkezzel megirni. DELETE-vel is

Amiert nem jon tul surun:

Altalaban kigyujtom a torlendo id-kat 100-asaval vagy ezresevel iteralva:

SELECT T1.id_t1
... join ...
WHERE T3.c1 IS NULL

Aztan ennek a resultjara update-elek

UPDATE T1 SET col=valami
WHERE id_t1 IN (23,34...867);

Ez utobbi sokkal rovidebb ideig zarolja lockra a tablakat es gyorsabb, mert csak primary key-re filterezik, ami a leggyorsabb

> Altalaban kigyujtom a torlendo id-kat 100-asaval vagy ezresevel iteralva (...) Aztan ennek a resultjara update-elek
Azért itt csuklottam egy kicsit.
Meg valszeg az ACID is.

> Ez utobbi sokkal rovidebb ideig zarolja lockra a tablakat es gyorsabb, mert csak primary key-re filterezik, ami a leggyorsabb
erről valami pontosabb mérést szívesen megnéznék, de eléggé kételkedem.

ja, sorry, elirtam

Meresem nincs publikus, de nempublikusban kijott MySQL-ben, hogy a UNIQUE key es a PRIMARY KEY sokkal gyorsabban WHERE-ezik, mint egy index. Ezenfelul a query plan legtobbszor a PRIMARY KEY filtert rakja elore. Ha nagyon erdekel, felseedelek ra valamit ha lesz idom. PostgreSQL-nel nem tudom mennyire eros a kulonbseg, de MySQL-ben tobb joinos query is volt, amit csak primary key-re filterezve lehetett meggyogyitani. Itt mondjuk pont nincs join sima table update/delete-jenel, de hozzaszoktam hogy query plan atiras helyett PRIMARY KEY-ezes van MySQL-ben.

Egyvalamiben biztos vagyok: lassabb nem lesz a Prmary Key-s filter update/delete-kor es minimalis idore lesz write lock. Ani max kiderulhet az az, hogy "unique key filterrel holtversenyben single table eseten"

> Meresem nincs publikus, de nempublikusban kijott MySQL-ben, hogy a UNIQUE key es a PRIMARY KEY sokkal gyorsabban WHERE-ezik, mint egy index.

Lamer kérdés: Ez nem azért van, mert az egyedi/elsődleges kulcsoknál nincs értelme tovább keresni az első találat után és a LIMIT-től függetlenül megáll, míg sima indexnél meg nem?

Nem lamer kerdes.

Igen, ezert van, vagy ezert IS van.

De még az id > 3000000 egy 4 millio soros tablan is gyorsabb, mint egy index "=" ami igaz parszazezer sorra. Erre ez mar nem magyarazat.

Ja meg az integer index gyorsabb, mint a text index, utobbit ugyanis LIKE, regexp, stb. eseten is hasznalod, igy mar az adatszerkezet is bonyolultabb.

Amiben viszont nem vagyok biztos de sejtem: primary key eseten akar meg a lemezterulet egy resze is excluded lehet az adatok kozul, ha egy bizonyos primary key-nel csak nagyobb elemeket nezel (ez akkor szamithat, ha valami nemindexeltre is keresel)

> De még az id > 3000000 egy 4 millio soros tablan is gyorsabb, mint egy index "=" ami igaz parszazezer sorra. Erre ez mar nem magyarazat.

Ha az előző nem volt az, lehet, hogy ez már lamer kérdés lesz: A táblák feltöltése általában szekvenciálisan történik, ennek megfelelően a rekordok fizikailag többnyire úgy jönnek egymás után, hogy a PKEY sorfolytonos. Tudom, hogy ez nem szükségszerűen van így, "összetördezehet" a sorrend amikor UPDATE vagy DELETE fut, de nincs esetleg valamilyen "mechanizmus" a motorban, ami nyilvántartja ennek a "töredezettségnek" a mértékét és a pontjait? Csak mert egy teljesen sorfolytonos PKEY mezőkkel bíró táblánál elég azt tudni, hogy hol van a 3 milliomodik sor és hol az utolsó és máris nem kell keresgetni semmit, ha meg törések vannak benne, akkor ha azok nyilván vannak tartva, akkor lehet tudni, hogy kell-e még máshova is nyúlni. Ezt totál laikusként kérdezem, nem tudom, hogy működik belülről a PgSQL vagy a MySQL. De szerintem érdemes lenne megnézni egy ebből a szempontból "összetört" tábla tartalmán lefutó PKEY-re szűrést, majd még egyszer, miután lefutott rá egy ALTER TABLE tabla ORDER BY id ASC.

Semmi nem garantálja, hogy az sorfolytonos lenne. Egyrészt ez csak akkor áll fenn, ha szekvenciát használsz PKEY-nek, ami elosztott rendszernél vagy clusternél már helyből szopás, mert vagy particionálod, hogy ki honnan indítja a szekvenciát, vagy, hogy nem egyesével növeled, hanem, mondjuk 10 node esetén 10-esével és az egyik 1-től, a másik 2-től, stb. Vagy szimplán GUID-et használsz. Láttam mind3-ra példát. (Persze, GUID-re nem fogsz nagyobb, mint szűrést végezni.)

Másrészt semmi nem garantálja neked, hogy a lemezre fizikailag is sorbarendezve kerülnek az adatok. Nagyjából az összes RDBMS implementáció lapokban gondolkodik, az a legkisebb mennyiség, amit hajlandó írni vagy olvasni a lemezről. Ráadásul sokszor copy-on-write van update esetén, ami miatt végképp össze-vissza van az adat.

De egyébként ezért van pl. MSSQL-ben is CLUSTERED index, amikor az indexben lévő adatok fizikailag sorba lesznek rendezve, illetve PostgreSQL-ben ott a CLUSTER parancs, amivel egy táblát tudsz fizikailag az indexszel összerendezni.

----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™

A clusterest koszi, maris sikerult valami hasznosat tanulnom a topikbol.

"Egyrészt ez csak akkor áll fenn, ha szekvenciát használsz PKEY-nek, ami elosztott rendszernél vagy clusternél már helyből szopás, mert vagy particionálod, hogy ki honnan indítja a szekvenciát, vagy, hogy nem egyesével növeled, hanem, mondjuk 10 node esetén 10-esével és az egyik 1-től, a másik 2-től, stb. Vagy szimplán GUID-et használsz. Láttam mind3-ra példát. (Persze, GUID-re nem fogsz nagyobb, mint szűrést végezni.)"

Ez meg erdekes. Mi az elsovel jatszottunk mikor kioskok feltoltik a dolgaikat es egyebeiket (termeszetesen direkt nem egyszerre :P ), van egy id_kiosk az id_akarmi melle, meg meg azontul egy masik auto_increment Primary Key a szerveren amit a feltolteskor generalunk.

Amiert meg erdekes szamomra: a lib amit csinaltam es amivel dolgozok limitalva van hogy csak integer primary key-jel tud dolgozni. Ez a GUID viszont bogarat ultetett a fulembe:

KERDESEM:
Tudsz-e olyan legfeljebb kozepesen nehezen elkepzelheto peldat mondani, amikor
- meg mindig egy (O)RDBMS (PostgreSQL, MySQL, etc.) a legjobb valasztas
ES
- biztosan rossz valasztas a szimpla integer oszlop PRIMARY KEY? (pl. jobb helyette a GUID-os)

Olyat tudok, hogy a tul sok write (pl. log, chat) vagy a horizontalis skalazodas miatt lemondasz egy RDBMS-re jellemzo konzisztenciarol, itt jonnek kepbe a "NoSQL"-ek. De olyat, ahol hizhat az RDBMS, de megis rossz valasztas kulon betenni egy nagyjabol novekvo id-ju integer PRIMARY KEY oszlopot egy pici plusz helyert, vagy valami mas okbol, olyat meg nem lattam.

(
Jonak tuno hatareset pelda: n to m relation kapcsolotabla, sokan szeretnek composite primary key-t definialni. Akar 33%-kal nagyobb lehet az auto incrementes / bigserialos PRIMARY KEY miatt a tabla. DE: volt mar olyan joinos query MySQL-ben, ahol tudtam, hogy 10-bol 9x csak bizonyos datum utan kell, azt a legkisebb PRIMARY KEY-t taroltam es onnantol az gyorsabb volt mindennel. Hiaba volt UNIQUE INDEX a kapcsolo tabla masik ket oszlopan meg a created_at oszlopokon, azt nem vette elore a query plan, es lassabb volt, mint az integer PRIMARY KEY-jel meg kulon raszurve egyet "mindjart az elejen". Ez a problema lehet nem erinti a Postgres-t, mert ott meg sosem kellett Primary Key-jel trukkoznom, okosabbnak tunik az amugy is ott legalabb editalhato query plan.
)

Egészen sok, gyakorlatban megélt okokat mondani:

- Üzleti vagy security okokból nem akarod, hogy tudják, hogy hanyadik rekordnál jársz. (ld. German Tank Problem című Wikipedia szócikk)
- Ugyancsak security okokból nem akarod, hogy könnyen végigscannelhető legyen a tartalmad. Egy Id listán seperc alatt végig lehet iterálni.
- Több adatbázis közt merge replication táblákkal. (Testközelben láttam ilyet egy ERP esetén, ahol a cégcsoport egyes tagjai külön adatbázisból futottak, de bizonyos táblák - pl. cikktörzs - közös volt. Ugyan ott úgy lett megoldva, hogy az egyik rendszerben meg lett ugratva a szekvencia mértéke, de gondolom látszik, hogy nem egy idiot proof megoldás.)
- Több, akár fizikailag izolált adatforrásod van, amelyet egy helyre öntesz (pl. mérőműszerek). Persze, lehet plusz kulcsot bevezetni, de lehet, hogy nem célszerű.
- Architekturális okok: pl. az ID nem az adatbázisban jön létre, hanem 3 service layerrel odébb egy eloszottt, skálázódó microservice-s architektúrában.

Egyébként nem mondom, hogy a GUID lenne a single silver bullett - pl. mi is csináltunk olyat, hogy egy microservice business layerébe már csak GUID látszik, de az adatelérési rétegben már megjelenik sequence a GUID mellett helytakarékossági és optimalizációs okokból, de ez már implementációs részlet kategóriába esett és szükség esetén cserélhető.

----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™

"
- Üzleti vagy security okokból nem akarod, hogy tudják, hogy hanyadik rekordnál jársz. (ld. German Tank Problem című Wikipedia szócikk)
- Ugyancsak security okokból nem akarod, hogy könnyen végigscannelhető legyen a tartalmad. Egy Id listán seperc alatt végig lehet iterálni.
"

Ettol meg letezhet integeres PRIMARY KEY, csak sosem teszed ki frontendre, URL-re, arra van kulon UNIQUE key-ed.

"- Több adatbázis közt merge replication táblákkal. (Testközelben láttam ilyet egy ERP esetén, ahol a cégcsoport egyes tagjai külön adatbázisból futottak, de bizonyos táblák - pl. cikktörzs - közös volt. Ugyan ott úgy lett megoldva, hogy az egyik rendszerben meg lett ugratva a szekvencia mértéke, de gondolom látszik, hogy nem egy idiot proof megoldás.)"

Ez jo peldanak tunik, ha lesz idom, lehet erre teszek fel meg egy bonyolultabb kerdest (utana kell neznem a "merge replication"-nek alaposabban elotte)

"- Több, akár fizikailag izolált adatforrásod van, amelyet egy helyre öntesz (pl. mérőműszerek). Persze, lehet plusz kulcsot bevezetni, de lehet, hogy nem célszerű. "

Ahogy irod: "lehet". A kerdesem a "biztosan rosszabb az extra oszlop" reszre vonatkozott.

"- Architekturális okok: pl. az ID nem az adatbázisban jön létre, hanem 3 service layerrel odébb egy eloszottt, skálázódó microservice-s architektúrában."

Ez eleg elcseszett egy rendszernek tunik oszinten. Ahol unique key van mi mindig szamolunk azzal, hogy lehet write failure konkurencia miatt es minimum retry-olni kell, vagy hibauzenetet kuldeni hogy nem sikerult es rollbackelni. Mint irtam, mi mindent ugy kezdunk, hogy megirjuk es review-oljuk a create table-t. Utana gyorsan nyilvanvalova valnak a pontos kovetelmenyek.

"pl. mi is csináltunk olyat, hogy egy microservice business layerébe már csak GUID látszik, de az adatelérési rétegben már megjelenik sequence a GUID mellett helytakarékossági és optimalizációs okokból"

Pontosan, ez nagyon hasonlo az en tapasztalataimhoz.

Summarised: a "merge replication"-os peldat kiveve egyik peldad sem gyozott meg arrol, hogy _biztosan_ rossz dontes bizonyos esetekben az integer primary key. Teny, hogy 1-2 oszloppal es unique index-szel az en megoldasaimban tobb van, kerdes azok overheadjenek szignifikanciaja, de abban ugye hasonlot tapasztaltunk: a sequence nyujtotta optimalizalasi lehetoseg tobbet gyorsitott, mint amennyit az extra oszlop+index elso ranezesre lassit a legtobb esetben.

"Ez eleg elcseszett egy rendszernek tunik oszinten. [...] megirjuk es review-oljuk a create table-t."

Üdv a microservicek világában. :) Az a gond, hogy szerintem te abból a feltételezésből indulsz ki, hogy biztosan van DB. Holott egyáltalán nem biztos, hogy a másik service, amit hívsz, az egyből egy RDBMS-sel fog kommunikálni. Lehet, hogy két-három réteggel odébb fogsz te majd ténylegesen egy adatbázissal találkozni. De az is lehet, hogy valamelyik could provider blobstoragejába hívsz bele.

Másik (szerintem) feltételezésed az, hogy azt feltételezed, hogy egy kliensed van. Holott bőven lehet, hogy 200 instance szórja neked az adatot, mert felskáláztál valami számolós/feldolgozós dolgot és te már csak aggregáltan kapod az adatot az adatbázisba. Viszont te nem fogsz tudni arról, hogy a DB-ben van egy seq pkey (lehet, hogy van, lehet, hogy nincs, lehet, hogy átveszed az user guid-jét, lehet, hogy a DB is meg van clusterezve, emiatt megintcsak szívsz a seq-ekkel, ld. előző eset.) Mondjuk a teljesség kedvéért: annak, hogy két random GUID véletlen megegyezzen viszonylag kicsi az esélye. Arra meg sequence esetén sem alapozhatsz, hogy ott nem lesz ütközés (mert pl. manuálisan be lett importálva egy halom új rekord), innen kezdve meg retry policy kérdése.

De ahogy mondani szokás: a világ nem fekete-fehér, mindig use-case függő, hogy mi a jó megoldás.

----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™

"Üdv a microservicek világában."

Nem az en vilagom, csak ha muszaj. Amig anelkul is boven a hatarido elott kesz vagyunk, addig nekem nem kell. Foleg ha az a data performance es a data consistency eszkozeit kivenne a kezembol. Meg tesztelmi is egy elmeny "neha" a microservice-eket, foleg mikor dev es live maskepp mukodik. A microservice-ek elterjedesenek latom az okat, es az sajnos inkabb gazdasagi oknak tunik, mint muszakinak. :(

"Másik (szerintem) feltételezésed az, hogy azt feltételezed, hogy egy kliensed van. Holott bőven lehet, hogy 200 instance szórja neked az adatot, mert felskáláztál valami számolós/feldolgozós dolgot és te már csak aggregáltan kapod az adatot az adatbázisba."

Tobb, mint 200 kioszkunk irogat a szerver DB-be rovid idokozonkent. Mar az insert into amit general az altalam keszitett custom rendszer is egy query-bol tolt akar 100 sort epp, kelloen gyors, es elfernek benne a plusz oszlopok. Ezenfelul a szerver is igazgatja a kiszkok semajat. Erre mindenfele koztes nemdbzo microservice nelkul megfelelo es safe megoldast irtunk, teljesen konzisztens adatokkal tudunk dolgozni.

"De az is lehet, hogy valamelyik could provider blobstoragejába hívsz bele"

En biztos nem, Isten ments :P Csak ha nem szamit az adatkonzisztencia (pl log), es keves az RDBMS sebessege/skalazhatosaga akkor esetleg atgondolom ujra

"egyáltalán nem biztos, hogy a másik service, amit hívsz, az egyből egy RDBMS-sel fog kommunikálni"

Akkor nem hasznalom, meggyozodok rola, hogy ha hasznalom nem lesz baj az inkonzisztenciabol, vagy ugy szamlazok, hogy irok melle valamit, amivel konzisztens tudok maradni. Volt erre pelda. M megrendelo tolunk kerte a projekt egy reszet es egyutt kellett dolgozni K kivitelezovel egy kozos reszen. Nos, K kivitelezo api-jan latszott, hogy nem egeszen ugy vannak a dolgok, ahogy el van meselve. Aludtam kettot a create table-okre, es vegul konkretan api kulcsonkent es verzio timestampenkent mentettem amit talaltam az endpointjaikon (amiket mint vegul megsejtettem, de elotte letagadtak: nem is egy idoben frissitettek). Vegeredmeny: K kivitelezo megkert, hogy ne csak M megrendelo eseten hasznalhassak mar a rollbackre is alkalmas rendszeremet, hanem B C es D megrendeloik eseten is. Par sort atirtunk a backoffice-ban es kaptak egy ujfajta access-t hozza K-ek.

"Amig anelkul is boven a hatarido elott kesz vagyunk, addig nekem nem kell."

Microservice nem a határidőkről szól alapvetően, hanem, hogy skálázható legyen vagy cserélhető legyen egy-egy komponens. Meg, hogy ne legyenek monolitikus mamutok a stackben. Illetve, hogy az egyes komponensek tesztelhetőbbek legyenek.

Nyilván, hogy ha ez az igény, ehhez kell mérni a határidőt is. (Ilyen szempontból nekem most nagyon szerencsém van, hogy nem projektben bérmunkázok, hanem terméket fejlesztek.)

"Foleg ha az a data performance es a data consistency eszkozeit kivenne a kezembol."

Nézőpont kérdése és az is feladatfüggő, hogy hol, milyen konzisztencia kell. Másrészt mi pl. egy optimalizáló megoldás mögötti adattárt írunk újra jelenleg microservice alapon, zömében pont performance okokból. Régi megoldás pl. tök jól működik, de az architektúrának vannak korlátai leginkább skálázódás terén vagy, hogy sokáig tart egy adattárt felépíteni. (Ezt ne egy sima DB-ként képzeld el, kifele ugyan csak egy Rest API-t látsz, házon belül van, ami DB-ből jön, van ami számított adat, van amit másik 3rd party komponens (szintén service) tud kiszámolni, van, ami másik servicebe van kiszervezve, szóval messze nem sima CRUD jellegű adattárolóról van szó.)

Az, hogy itt-ott van PostgreSQL is az egyes servicek mögött az egy mellékes implementációs kérdés.

Egyébként meg értem, hogy mit mondasz, jelenleg itt cégen belül pont én képviselem a hagyományosabb, konzervatívabb DB-s vonalat, de látom azt is, hogy mik a megoldandó problémák és mit old meg ezekből a microservices architektúra. És nyilván megvannak ennek is a trade-offjai.

----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™

Ez nem feltétlen járható, mivel a SET col=valami egy konstans értékre update-el, de sok esetben egy másik tábla hozzákapcsolható rekordjából kell kivenni az értékeket.

Az az evente egy kiveteles eset :) De azt jobb kezzel irni mint query-t, az a lenyeg.

"SQL is not assembly" ehhez képest pont arról írsz, mennyit kell és lehet benne trükközni, hogy jó legyen a sebesség :)
Amúgy én SQL párti vagyok, lekérdezéseket szoktam írni. Régebben még saját keretrendszert is írtam Java-JDBC alapon, mert nem volt egy rendes lekérdezésgenerátor az akkori ERP-nknek. Nem volt nagy igény arra, hogy optimalizáljak, inkább arra, hogy spóroljon a cég és ne az ERP írónak kelljen egy lekérdezésért egy-két havi fizumat fizetni.
Bele-belefutottam azért teljesítményproblémákba, de gyakrabban döglesztette be egy hivatalos lekérdezés az Oracle-t, mint az enyéim, pedig volt ami sokat szöszmötölt :).
SQL más világ, más logika, mint az OO, de nem olyan bonyolult (ha csak lekérdezés kell) sőt néha más feladatnál is éreztem, előbb kész lennék, ha fellőném adatbázisba és onnan kérdezgetném, mint Java alatt bajlódjak vele, de nem kellett megosztani adatokat, meg offline is kellett futnia, ahhoz meg túlzónak éreztem külön adatbázist.

Ugy ertem lehetsz kiraly C vagy C++ fejleszto ha nem nyulsz assembly-hez, mert a clang/gcc elvegzi a feladatot. De a PHP vagy Java alkalmazasod es az SQL koze az ORM nem olyan amit ugyanezen a szinten kene kezelni, megis sajnos rengeteg fejleszto igy gondolja :( Az SQL-hez erteni _kell_, mert egy bizonyos szint folott semmit nem tudsz hatekonyan folewrappelni. Assembly-re meg mar jobban optimalizal gep, mint ember. Erre ertettem.

Sub.

+1;