E vërteta mbi të gjitha, ose përse sistemi duhet të projektohet duke u bazuar në strukturën e bazës së të dhënave

Përshëndetje, Habr!

Ne pohojme të hetojmë temën Java dhe Spring, përfshirë në nivelin e bazave të të dhënave. Sot ju ofrojmë një lexim mbi arsyen se pse kur projektoni aplikacione të mëdha, struktura e bazës së të dhënave, dhe jo kodi Java, duhet të ketë rëndësi vendimtare, si është e realizueshme kjo dhe cilat janë përjashtimet nga ky rregull.

Në këtë artikull të vonuar, do të shpjegoj arsyen pse mendoj se në praktikisht të gjitha rastet, modeli i të dhënave në aplikacion duhet të projektohet "duke u nisur nga baza e të dhënave", dhe jo "duke u nisur nga mundësitë e Java" (ose ndonjë gjuhe tjetër klienti me të cilën po punoni). Duke zgjedhur qasjen e dytë, ju filloni një rrugë të gjatë vuajtjesh sapo projekti juaj fillon të rritet.

Artikulli është shkruar mbi motivin e një pyetjeje, që u bë në Stack Overflow.

Diskutimet interesante në reddit në seksionet /r/java dhe /r/programming.

Gjenerimi i kodit

Sa shumë u befasova kur zbulova se ekziston një grup aq i vogël përdoruesish, të cilët, pasi u njohën me jOOQ, u shqetësuan nga fakti se në punën me jOOQ mbështetet seriozisht në gjenerimin e kodit. Askush nuk ju pengon të përdorni jOOQ ashtu si e shihni të arsyeshme dhe nuk ju detyron të përdorni gjenerimin e kodit. Por në mënyrë default (ashtu siç përshkruhet në manual), puna me jOOQ ndodh kështu: filloni me (trashëguar) schemën e bazës së të dhënave, kryeni inxhinierinë e saj të prapmë me ndihmën e gjeneratorit të kodit jOOQ, për të marrë një grup klasash që përfaqësojnë tabelat tuaja, dhe më pas shkruani pyetje të sigurta për tipin për këto tabela:

	for (Record2 record : DSL.using(configuration)
//   ^^^^^^^^^^^^^^^^^^^^^^^ Informacioni mbi tipet është nxjerrë në 
//   bazë të kodit të gjeneruar, i cili referohet në kushtin e dhënë
// më poshtë SELECT 

       .select(ACTOR.FIRST_NAME, ACTOR.LAST_NAME)
//           vvvvv ^^^^^^^^^^^^  ^^^^^^^^^^^^^^^ emrat e gjeneruar
       .from(ACTOR)
       .orderBy(1, 2)) {
    // ...
}

Kodi gjenerohet ose manualisht jashtë ndërtimit, ose manualisht çdo herë kur ndodh ndërtimi. Për shembull, një rigjenerim i tillë mund të ndodhë menjëherë pas migros të bazës së të dhënave Flyway, e cila gjithashtu mund të kryhet manualisht ose automatikisht.

Gjenerimi i kodit burimor

Me kĂ«to qasje ndaj gjenerimit tĂ« kodit – manuale dhe automatike – lidhen filozofi tĂ« ndryshme, avantazhe dhe disavantazhe, tĂ« cilat nuk do t’i diskutoj nĂ« detaje nĂ« kĂ«tĂ« artikull. Por, nĂ« pĂ«rgjithĂ«si, e gjithĂ« thelbi i kodit tĂ« gjeneruar Ă«shtĂ« se ai lejon tĂ« riprodhohet nĂ« Java ajo "e vĂ«rtetĂ«", qĂ« e pranojmĂ« si tĂ« dhĂ«nĂ«, qoftĂ« brenda sistemit tonĂ«, qoftĂ« jashtĂ« tij. NĂ« njĂ«farĂ« mĂ«nyre, tĂ« njĂ«jtĂ«n gjĂ« bĂ«jnĂ« kompilet, tĂ« cilĂ«t gjenerojnĂ« kodin bajt, kodin makinerik ose ndonjĂ« formĂ« tjetĂ«r tĂ« kodit mbi bazĂ«n e burimeve – ne marrim njĂ« pĂ«rfaqĂ«sim tĂ« "e vĂ«rtetĂ«s" tonĂ« nĂ« njĂ« gjuhĂ« tjetĂ«r, pavarĂ«sisht shkakut tĂ« veçantĂ«.

Ekzistojnë shumë të tillë gjenerues kodesh. Për shembull, XJC mund të gjenerojë kod Java mbi baza të skedarëve XSD ose WSDL. Parimi gjithmonë është i njëjtë:

  • Ekziston njĂ« e vĂ«rtetĂ« (brendshme ose jashtme) – pĂ«r shembull, specifikimi, modeli i tĂ« dhĂ«nave, etj.
  • Na nevojitet njĂ« pĂ«rfaqĂ«sim lokal i kĂ«saj tĂ« vĂ«rtete nĂ« gjuhĂ«n tonĂ« programore.

Dhe Ă«shtĂ« gjithmonĂ« e arsyeshme tĂ« gjenerohet njĂ« pĂ«rfaqĂ«sim i tillĂ« – pĂ«r tĂ« evituar qĂ«llimin e tepĂ«rt.

Ofertues të llojeve dhe përpunimi i annotimeve

PĂ«r t'u vĂ«nĂ« nĂ« dukje: njĂ« tjetĂ«r, mĂ« modern dhe specifik qasje ndaj gjenerimit tĂ« kodit pĂ«r jOOQ lidhet me pĂ«rdorimin e ofertuesve tĂ« llojeve, nĂ« formĂ«n siç janĂ« implementuar nĂ« F#. NĂ« kĂ«tĂ« rast, kodi gjenerohet nga kompajleri, pikĂ«risht nĂ« fazĂ«n e kompilimimit. NĂ« formĂ«n e burimeve njĂ« kod i tillĂ« nĂ« parim nuk ekziston. NĂ« Java ekzistojnĂ« mjete tĂ« ngjashme, megjithĂ«se jo aq elegante – kĂ«to janĂ« procesorĂ«t e annotimeve, pĂ«r shembull, Lombok.

Në një farë kuptimi, këtu ndodhin të njëjtat gjëra si në rastin e parë, përveç:

  • Nuk e shihni kodin e gjeneruar (ndoshta kjo situatĂ« disa njerĂ«zve u duket jo aq e frikshme?)
  • Duhet tĂ« garantoni qĂ« llojet mund tĂ« ofrohen, dmth, "e vĂ«rteta" gjithmonĂ« duhet tĂ« jetĂ« e disponueshme. Kjo Ă«shtĂ« e lehtĂ« nĂ« rastin e Lombok, i cili annoton “e vĂ«rtetĂ«n”. MĂ« pak e thjeshtĂ« me modelet e bazave tĂ« tĂ« dhĂ«nave, puna e tĂ« cilave varet nga njĂ« lidhje e drejtpĂ«rdrejtĂ« e vazhdueshme.

Cila është problemi me gjenerimin e kodit?

Përveç një pyetje të hollë rreth mënyrës më të mirë për të filluar gjenerimin e kodit - në mënyrë manuale apo automatikisht, duhet të përmendim gjithashtu se ka njerëz që mendojnë se gjenerimi i kodit nuk është i nevojshëm fare. Justifikimi i një pikëpamjeje të tillë, të cilin e kam hasur shpesh, është se atëherë është e vështirë të konfigurosh cilindrin e ndërtimit. Po, me të vërtetë është e vështirë. Ka shpenzime shtesë infrastrukturore. Nëse sapo po filloni të punoni me një produkt të caktuar (qoftë jOOQ, JAXB, Hibernate, etj.), koha e nevojshme për të konfiguruar mjedisin e punës është një kohë që do të donit ta kalonit duke studiuar vetë API-n, për të nxjerrë më vonë vlerë prej saj.

NĂ«se shpenzimet janĂ« shumĂ« tĂ« mĂ«dha pĂ«r tĂ« kuptuar funksionimin e gjeneratorit – atĂ«herĂ« me tĂ« vĂ«rtetĂ« API-ja nuk ka punuar mirĂ« nĂ« pĂ«rdorshmĂ«rinĂ« e gjeneratorit (dhe mĂ« vonĂ« del se edhe konfigurimi i pĂ«rdoruesit nĂ« tĂ« Ă«shtĂ« i komplikuar). LehtĂ«sia e pĂ«rdorimit duhet tĂ« jetĂ« prioriteti mĂ« i lartĂ« pĂ«r çdo API tĂ« tillĂ«. Por ky Ă«shtĂ« vetĂ«m njĂ« argument kundĂ«r gjenerimit tĂ« kodit. NĂ« tĂ« tjerat, Ă«shtĂ« absolutisht e nevojshme tĂ« shkruhet manualisht prezantimi lokal i sĂ« vĂ«rtetĂ«s sĂ« brendshme ose tĂ« jashtme.

Shumë do të thonë se nuk kanë kohë për të bërë të gjitha këto. Ata kanë afate për produktin e tyre Super. Diku më vonë do ta rregullojmë cilindrin e ndërtimit, do të kemi kohë. Unë iu përgjigjem atyre:

E vërteta mbi të gjitha, ose përse sistemi duhet të projektohet duke u bazuar në strukturën e bazës së të dhënave
Originali, Alan O’Rourke, Audience Stack

Por në Hibernate / JPA është kaq e lehtë të shkruash kod "nën Java".

Në të vërtetë. Për Hibernate dhe përdoruesit e tij, kjo është njëherësh një bekim dhe një mallkim. Në Hibernate mund të shkruash thjesht disa entitete, kështu:

	@Entity
class Book {
  @Id
  int id;
  String title;
}

Dhe pothuajse çdo gjë është gati. Tani detyra e Hibernate është të gjenerojë "detajet" komplekse të asaj se si do të përcaktohet me të vërtetë kjo entitet në DDL-në e "dialektit" tuaj SQL:

	CREATE TABLE book (
  id INTEGER PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
  title VARCHAR(50),
 
  CONSTRAINT pk_book PRIMARY KEY (id)
);
 
CREATE INDEX i_book_title ON book (title);

... dhe fillojmë të përshkojmë aplikacionin. Vërtet një mundësi e shkëlqyer, për të filluar shpejt dhe për të provuar gjëra të ndryshme.

Megjithatë, ndaluni një çast. Kam gënjyer.

  • Por a do ta aplikojĂ« Hibernate definicionin e kĂ«tij çelĂ«si primar tĂ« emĂ«ruar?
  • A do tĂ« krijojĂ« Hibernate indeksin nĂ« TITLE? – unĂ« e di saktĂ«sisht se do na nevojitet.
  • A do ta bĂ«jĂ« Hibernate kĂ«tĂ« çelĂ«s identifikues nĂ« Specifikimin e Identitetit?

Ndoshta jo. Nëse po e zhvilloni projektin tuaj nga e para, gjithmonë është e dobishme të hiqni bazën e të dhënave të vjetër dhe të krijoni një të re, sa herë që të shtoni anotacionet e nevojshme. Kështu, entiteti Book në fund do të duket si:

	@Entity
@Table(name = "book", indexes = {
  @Index(name = "i_book_title", columnList = "title")
})
class Book {
  @Id
  @GeneratedValue(strategy = IDENTITY)
  int id;
  String title;
}

Super. Rinisni nga fillimi. Edhe kësaj here, në një rast të tillë, do të jetë shumë e lehtë në fillim.

Por më vonë do t'ju duhet të paguani për këtë.

Për ose më vonë do të duhet të kaloni në prodhim. Pikërisht atëherë ky model do të ndalojë së funksionuari. Sepse:

Në prodhim nuk do të jetë e mundur, sipas nevojës, të hiqni bazën e të dhënave të vjetër dhe të filloni gjithçka nga e para. Baza juaj e të dhënave do të bëhet hereditar.

Që nga tani e tutje do t'ju duhet të shkruani skriptet e migracionit DDL, për shembull, duke përdorur Flyway.. Por çfarë do të ndodhë në këtë rast me entitetet tuaja? Ju mund të adaptoni ato manualisht (dhe kështu do të dyfishoni punën tuaj), ose mund të kërkoni nga Hibernate t'i gjenerojë përsëri për ju (sa të mëdha janë shanset që ato të jenë siç e prisni?) Në çdo rast, ju humbni.

Pra, sa herë që kaloni në prodhim, ju nevojiten patches të nxehta. Dhe ato duhet të dalin në prodhim shumë shpejt. Sepse ju nuk u përgatitët dhe nuk organizuat një konvej për migrimet tuaja, ju gjithçka do ta patçoni. Dhe pastaj nuk do të keni kohë ta bëni gjithçka siç duhet. Dhe e akuzoni Hibernate, sepse gjithmonë është faji i dikujt tjetër, jo ju...

Në vend të kësaj, që nga fillimi mund të bëni gjithçka krejt ndryshe. Për shembull, ndoshta të vendosni rrota të rrumbullakëta në biçikletë.

Së pari baza e të dhënave.

E vĂ«rteta e vĂ«rtetĂ« nĂ« skemĂ«n e bazĂ«s tuaj tĂ« tĂ« dhĂ«nave dhe "sovraniteti" mbi tĂ« qĂ«ndron brenda bazĂ«s sĂ« tĂ« dhĂ«nave. Skema pĂ«rcaktohet vetĂ«m brenda vetĂ« bazĂ«s sĂ« tĂ« dhĂ«nave dhe askund tjetĂ«r, dhe çdo klient ka njĂ« kopje tĂ« kĂ«saj skeme, kĂ«shtu qĂ« Ă«shtĂ« krejt e arsyeshme tĂ« impononi ruajtjen e skemĂ«s dhe integritetit tĂ« saj, duke bĂ«rĂ« kĂ«tĂ« direkt nĂ« bazĂ«n e tĂ« dhĂ«nave – aty ku ruhet informacioni.
Kjo Ă«shtĂ« njĂ« urtĂ«si e vjetĂ«r, madje e vjetĂ«r. ÇelĂ«sat e parĂ« dhe unikĂ« janĂ« tĂ« mirĂ«. ÇelĂ«sat e jashtĂ«m – janĂ« tĂ« mirĂ«. Verifikimi i kufizimeve – Ă«shtĂ« i mirĂ«. Shprehjet – janĂ« tĂ« mira.

Dhe, kjo nuk është gjithçka. Për shembull, duke përdorur Oracle, ndoshta do të dëshironi të specifikoni:

  • NĂ« cilin hapĂ«sirĂ« tabellash ndodhet tabela juaj
  • Cili Ă«shtĂ« vlerĂ« PCTFREE
  • Cili Ă«shtĂ« madhĂ«sia e caches nĂ« sekuencĂ«n tuaj (pas identifikuesit)

Ndoshta e gjitha kjo nuk ka rĂ«ndĂ«si nĂ« sistemet e vogla, por nuk Ă«shtĂ« e nevojshme tĂ« prisni kalimin nĂ« fushĂ«n e 'tĂ« dhĂ«nave tĂ« mĂ«dha' — mund tĂ« filloni tĂ« pĂ«rfitoni nga optimizimet e ruajtjes sĂ« tĂ« dhĂ«nave qĂ« ofrohen nga ofruesi, si ato tĂ« pĂ«rmendura mĂ« sipĂ«r, edhe mĂ« herĂ«t. AsnjĂ« prej ORM-ve qĂ« kam parĂ« (pĂ«rfshirĂ« jOOQ) nuk ofron qasje nĂ« tĂ« gjithĂ« grupin e mundĂ«sive DDL qĂ« mund tĂ« dĂ«shironi tĂ« pĂ«rdorni nĂ« bazĂ«n tuaj tĂ« tĂ« dhĂ«nave. ORM-tĂ« ofrojnĂ« disa mjete qĂ« ndihmojnĂ« nĂ« shkrimin e DDL.

Por, nĂ« fund tĂ« fundit, njĂ« skemĂ« e mirĂ«projektuar shkruhet manualisht nĂ« DDL. Çdo DDL e gjeneruar Ă«shtĂ« vetĂ«m njĂ« aproximim i saj.

ÇfarĂ« ndodh me modelin e klientit?

Siç u përmend më parë, në klient do t'ju duhet një kopje e skemës së bazës suaj të të dhënave, një pamje e klientit. E tepërt për të përmendur se kjo pamje e klientit duhet të jetë e sinkronizuar me modelin e vërtetë. Si t'ia arrini më së miri kësaj? Me ndihmën e një gjeneratori kodi.

Të gjitha bazat e të dhënave ofrojnë metainformacionin e tyre përmes SQL. Ja si të merrni të gjitha tabelat nga baza juaj e të dhënave në dialekte të ndryshme SQL:

	-- H2, HSQLDB, MySQL, PostgreSQL, SQL Server
SELECT table_schema, table_name
FROM information_schema.tables
 
-- DB2
SELECT tabschema, tabname
FROM syscat.tables
 
-- Oracle
SELECT owner, table_name
FROM all_tables
 
-- SQLite
SELECT name
FROM sqlite_master
 
-- Teradata
SELECT databasename, tablename
FROM dbc.tables

Këto kërkesa (apo të ngjashme me to, në varësi të faktit nëse duhet të merrni parasysh gjithashtu pamjet, pamjet e materializuara, funksionet me vlerë tabellash) ekzekutohen gjithashtu përmes thirrjes DatabaseMetaData.getTables() nga JDBC, ose përmes modulit meta jOOQ.

Nga rezultatet e këtyre kërkesave është relativisht e lehtë të gjenerosh çdo pamje klienti të modelit të bazës së të dhënave, pa zakoni se çfarë teknologjie përdorni në klientin tuaj.

  • NĂ«se pĂ«rdorni JDBC ose Spring, mund tĂ« krijoni njĂ« grup konstantash string
  • NĂ«se pĂ«rdorni JPA, mund tĂ« gjeneroni vetĂ« entitetet
  • NĂ«se pĂ«rdorni jOOQ, mund tĂ« gjeneroni modelin meta tĂ« jOOQ

Në varësi të asaj që ofrohet nga API juaj për klientët (p.sh. jOOQ ose JPA), meta-modeli i gjeneruar mund të jetë me të vërtetë i pasur dhe i plotë. Le të marrim, për shembull, mundësinë e bashkimeve të implicit, që u shfaq në jOOQ 3.11, e cila mbështetet në metainformacionin e gjeneruar mbi marrëdhëniet e çelësave të jashtëm, që veprojnë midis tabelave tuaja.

Tani çdo rritje e bazës së të dhënave do të çojë automatikisht në përditësimin e kodit të klientit. Imagjinoni, për shembull:

ALTER TABLE book RENAME COLUMN title TO book_title;

A do të donit të bënit këtë punë dy herë? Asnjëherë. Thjesht regjistroni DDL-në, kaloni atë përmes konvejerit tuaj të ndërtimit dhe merrni entitetin e përditësuar:

@Entity
@Table(name = "book", indexes = {
 
  // A e keni menduar këtë?
  @Index(name = "i_book_title", columnList = "book_title")
})
class Book {
  @Id
  @GeneratedValue(strategy = IDENTITY)
  int id;
 
  @Column("book_title")
  String bookTitle;
}

Ose klasa e përditësuar jOOQ. Shumica e ndryshimeve DDL reflektohen gjithashtu në semantike, dhe jo vetëm në sintaksë. Prandaj, ndonjëherë është e dobishme të shihni në kodin e kompiluar se cili kod do të preket (apo mund të preket) nga rritja e bazës suaj të të dhënave.

E vërteta e vetme

PavarĂ«sisht se çfarĂ« teknologjie pĂ«rdorni, gjithmonĂ« ka njĂ« model qĂ« Ă«shtĂ« burimi i vetĂ«m i vĂ«rtetĂ«s pĂ«r njĂ« nĂ«nsisistem tĂ« caktuar – ose, tĂ« paktĂ«n, duhet tĂ« strimcahemi pĂ«r kĂ«tĂ« dhe tĂ« shmangim njĂ« konfuzion tĂ« tillĂ« enterprise ku "e vĂ«rteta" Ă«shtĂ« menjĂ«herĂ« kudo dhe asnjĂ«herĂ«. Gjithçka mund tĂ« jetĂ« shumĂ« mĂ« e thjeshtĂ«. NĂ«se thjesht shkĂ«mbeni skedarĂ« XML me ndonjĂ« sistem tjetĂ«r, thjesht pĂ«rdorni XSD. Shikoni nĂ« meta-modelin INFORMATION_SCHEMA nga jOOQ nĂ« formatin XML:
https://www.jooq.org/xsd/jooq-meta-3.10.0.xsd

  • XSD Ă«shtĂ« e kuptueshme mirĂ«
  • XSD markon mjaft mirĂ« pĂ«rmbajtjen e XML dhe lejon validimin nĂ« tĂ« gjitha gjuhĂ«t e klientĂ«ve
  • XSD ka njĂ« versionim tĂ« mirĂ« dhe ofron njĂ« pĂ«rputhshmĂ«ri tĂ« avancuar mbrapa
  • XSD mund tĂ« transformohet nĂ« kod Java pĂ«rmes XJC

Pika e fundit është e rëndësishme. Kur komunikojmë me një sistem të jashtëm përmes mesazhesh XML, duam të jemi të sigurt për vlefshmërinë e mesazheve tona. Kjo është shumë e lehtë të arrihet përmes JAXB, XJC dhe XSD. Do të ishte çmenduri të mendojmë se, duke iu qasur projektimit "Java e parë", ku ne i bëjmë mesazhet tona si objekte Java, ato mund të projektohen në XML dhe të dërgohen për konsum në një sistem tjetër. XML i gjeneruar kështu do të ishte me cilësi shumë të dobët, pa dokumentim, dhe do të ishte i vështirë për t'u zhvilluar. Nëse për një ndërfaqe të tillë ekzistonte një marrëveshje për nivelin e shërbimit (SLA), do ta kishim dështuar menjëherë.

Sinqerisht, kjo është pikërisht ajo që ndodh vazhdimisht me API-të në JSON, por kjo është një histori tjetër, herën tjetër do të ankohem...

Baza të dhënash: është e njëjta gjë.

Kur punoni me baza tĂ« dhĂ«nash, kuptoni se tĂ« gjitha janĂ«, nĂ« thelb, tĂ« ngjashme. NjĂ« bazĂ« zotĂ«ron tĂ« dhĂ«nat e saj dhe duhet tĂ« udhĂ«heqĂ« skemĂ«n. Çdo modifikim qĂ« bĂ«het nĂ« skemĂ« duhet tĂ« implementohet drejtpĂ«rdrejt nĂ« DDL, nĂ« mĂ«nyrĂ« qĂ« burimi i vetĂ«m i sĂ« vĂ«rtetĂ«s tĂ« azhurnohet.

Kur burimi i azhurnohet, të gjithë klientët gjithashtu duhet të azhurnojnë kopjet e tyre të modelit. Disa klientë mund të jenë shkruar në Java duke përdorur jOOQ dhe Hibernate ose JDBC (apo të gjitha njëherësh). Klientë të tjerë mund të jenë shkruar në Perl (u uroj fat), të tjerët - në C#. Nuk ka rëndësi. Modeli kryesor është në bazën e të dhënave. Modelet e gjeneruara përmes ORM zakonisht janë të dobëta, me dokumentim të dobët dhe të vështira për t'u zhvilluar.

Prandaj mos bĂ«ni gabime. Prej fillimit mos bĂ«ni gabime. Punoni nga baza e tĂ« dhĂ«nave. NdĂ«rtoni njĂ« pipeline shpĂ«rndarjeje qĂ« mund tĂ« automatizohet. PĂ«rfshini gjeneruesit e kodit pĂ«r ta bĂ«rĂ« tĂ« lehtĂ« kopjimin e modelit tĂ« bazĂ«s tuaj tĂ« dhĂ«nash dhe shpĂ«rndarjen e tij te klientĂ«t. Dhe ndaloni sĂ« shqetĂ«suari pĂ«r gjeneruesit e kodit. Ata janĂ« tĂ« mirĂ«. Me ta do tĂ« bĂ«heni mĂ« produktivĂ«. VetĂ«m duhet tĂ« shpenzoni pak kohĂ« nĂ« fillim pĂ«r t'i pĂ«rshtatur ato – dhe mĂ« pas ju presin vite produktiviteti tĂ« pĂ«rmirĂ«suar, nga tĂ« cilat do tĂ« formohet historia e projektit tuaj.

Mos e falëndero tani, më vonë.

Shpjegimi

PĂ«r qartĂ«si: Ky artikull nĂ« asnjĂ« mĂ«nyrĂ« nuk propagandon qĂ« modeli i bazĂ«s suaj tĂ« tĂ« dhĂ«nave duhet tĂ« pĂ«rshtatet me gjithĂ« sistemin (pra, fushĂ«n e subjektit, logjikĂ«n e biznesit, etj.). NĂ« kĂ«tĂ« artikull, po flas pĂ«r faktin se kodi i klientit qĂ« interakton me bazĂ«n e tĂ« dhĂ«nave duhet tĂ« veprojĂ« duke u bazuar nĂ« modelin e bazĂ«s sĂ« tĂ« dhĂ«nave, nĂ« mĂ«nyrĂ« qĂ« nĂ« vetvete tĂ« mos riprodhohet modeli i bazĂ«s sĂ« tĂ« dhĂ«nave si njĂ« “klasĂ« e parĂ«â€. Kjo logjikĂ« zakonisht vendoset nĂ« nivelin e qasjes sĂ« tĂ« dhĂ«nave tek ju nĂ« klient.

NĂ« arkitekturĂ«n me dy nivele, e cila ende ekziston nĂ« disa vende, njĂ« model i tillĂ« i sistemit mund tĂ« jetĂ« i vetmi i mundshĂ«m. MegjithatĂ«, nĂ« shumicĂ«n e sistemeve, niveli i qasjes sĂ« tĂ« dhĂ«nave mĂ« duket si njĂ« “nĂ«n sistem”, qĂ« inkapsulon modelin e bazĂ«s sĂ« tĂ« dhĂ«nave.

Përjashtimet

Nga çdo rregull ka përjashtime, dhe unë kam thënë tashmë se qasja me rëndësinë e bazës së të dhënave dhe gjenerimin e kodit burimor ndonjëherë mund të jetë e papërshtatshme. Këtu janë dy përjashtime të tilla (pranoni se do të ketë edhe të tjera):

  • Kur skema Ă«shtĂ« e panjohur dhe duhet tĂ« hapet. PĂ«r shembull, ju jeni ofrues i njĂ« instrumenti qĂ« ndihmon pĂ«rdoruesit tĂ« orientohen nĂ« çdo skemĂ«. Uff. KĂ«tu pa gjenerim kode. Por pĂ«rsĂ«ri – baza e tĂ« dhĂ«nave Ă«shtĂ« mbi tĂ« gjitha.
  • Kur skema duhet tĂ« gjenerohet nĂ« fluks pĂ«r tĂ« zgjidhur njĂ« detyrĂ« tĂ« caktuar. Ky shembull duket si njĂ« version paksa i zbukuruar i modelit tĂ« atributit tĂ« entitetit, domethĂ«nĂ«, ju me tĂ« vĂ«rtetĂ« nuk keni njĂ« skemĂ« tĂ« qartĂ« tĂ« pĂ«rcaktuar. NĂ« kĂ«tĂ« rast, shpesh nuk mund tĂ« jeni tĂ« sigurt se ju pĂ«rshtatet njĂ« RDBMS.

Përjashtimet për natyrën e tyre janë të veçanta. Në shumicën e rasteve, që lidhen me përdorimin e RDBMS, skema është e njohur paraprakisht, ajo ndodhet brenda RDBMS dhe është burimi i vetëm i "të vërtetës", dhe të gjithë klientët duhet të krijojnë kopje të saj, të derivuara prej saj. Në ide, në këtë rast, duhet të angazhohet një gjenerator kodi.

Burimi: habr.com

Blini hosting tĂ« besueshĂ«m pĂ«r faqe interneti me mbrojtje nga DDoS, serverĂ« VPS VDS đŸ”„ Blini hosting tĂ« besueshĂ«m pĂ«r faqe interneti me mbrojtje nga DDoS, serverĂ« VPS VDS | ProHoster