Hogyan tegyem adatbázis-kezelő függetlenné?
2010-02-05T21:23:18+01:00
2010-02-06T14:59:00+01:00
2022-07-25T06:43:43+02:00
  • Én azért irtam ezt, mert akinek van külön DAL rétege, az valószinüleg fel sem teszi ezt a kérdést (már tuljutott ezen a problémakörön)

    Kissebb projektekre vagy gányolásra meg az én megoldásom sokkal gyorsabb.
    Mutasd a teljes hozzászólást!
  • Azért, mert a lekérdezések szintaktikája sem feltétlenül egyforma. Pl:
    tábla és mező nevek határolói:
    - MySQL: `egy mezo`
    - SQL Server: [egy mezo]
    - Oracle: "egy mezo"

    Eltérhetnek az adott platformon használt mezőtípusok és megoldások. Elméletileg pl. lehet olyan rdbms, amiben külön date és time típus van csak, míg a többiben datetime van. Ekkor a spec rdbms-nél külön mezőben tárolod és php-ban összefűzöf, a többinél meg egy mezőt használsz.
    Aztán ugye van egy csomó rdbms, amihez nincs direkt php modul, így pl. odbc-n kell elérni. Ott meg az egész szintaktika egészen más.
    Mutasd a teljes hozzászólást!
  • de akkor már miért ne az alapfügvényeket klonozza:

    sql_fetch_assoc
    > mysql_fetch_assoc
    > mssql_fetch_assoc
    > stb

    az sql parancsokat meg belehet olvasni külön fileokból.

    És akkor ez a layer tényleg semmi másról nemszólna csak adatbázis függetlenitésről.


    Amugy meg szerintem ez az adatbázis függőség nem annyira vészes dolog. Ha átkell állni egy másik adatbázisra, akkor azt általában hamar meglehet oldani. nagyjából sima find and replace :)
    Mutasd a teljes hozzászólást!
  • Ennél én sokkal egyszerűbbre gondoltam, bár így lehet hogy szebb. Az alapötletem a következő:

    fileszerkezet:
    rootfolder +- index.php +- forum_topics.php +- config.php +- ... +- dal +- mssql +- common.php +- forum.php +- ... +- mysql +- common.php +- forum.php +- ... +- oracle +- common.php +- forum.php +- ... +- ... +- ...

    config.php:
    ... $rdbms = "mysql"; $rdbms_server = "dbserver"; $rdbms_user = "mylogin"; $rdbms_password = "mypassword"; $rdbms_db = "mydatabase"; ...

    index.php:
    include "config.php"; include "$rdbms/common.php" ...

    dal/mysql/common.php:
    include "../../config.php"; function Check_User($email, $password) { $conn = mysql_connect($rdbms_server, $rdbms_user, $rdbms_password); if(!$conn) die("Nem lehet kapcsolódni. Hiba: ".mysql_error()); mysql_select_db($rdbms_db, $conn); $result = mysql_query("SELECT COUNT(*) AS cnt FROM users WHERE email = '$email.' AND password = '$password'"); if(!result) die("Nem lehet lekérdezni. Hiba: ".mysql_error()); $row = mysql_fetch_assoc($result); $result = $row["cnt"]; mysql_free_result($result); return($result); } function Change_Password($email, oldpassword, $newpassword) { ... } function Get_Visitors() { ... }

    dal/mssql/common.php:
    include "../../config.php"; function Check_User($email, $password) { $conn = mssql_connect($rdbms_server, $rdbms_user, $rdbms_password); if(!$conn) die("Nem lehet kapcsolódni. Hiba: ".mssql_error()); mssql_select_db($rdbms_db, $conn); $result = mssql_query("SELECT COUNT(*) AS cnt FROM users WHERE email = '$email.' AND password = '$password'"); if(!result) die("Nem lehet lekérdezni. Hiba: ".mssql_error()); $row = mssql_fetch_assoc($result); $result = $row["cnt"]; mssql_free_result($result); return($result); } function Change_Password($email, oldpassword, $newpassword) { ... } function Get_Visitors() { ... }

    dal/oracle/common.php
    ...

    Így pontosan ugyan azt hívod meg a felületért felelős php állományokból. Pontosan ugyan azt kapod vissza minden esetben és pontosan ugyan azt várod paraméterben is. A felületnek nem kell tudnia milyen rdbms van mögötte.
    Mutasd a teljes hozzászólást!
  • Én ezt úgy oldom meg, hogy van pár kisebb függvény amit egyszerűbb levinni az RDBMS szintjére, illetve sokkal gyorsabb ott. De csak kevés ilyen van, a nagy része a programban van - pont az adatbázisfüggőség csökkentése miatt - illetve azért mert ott egyszerűbb komplex feladatokat megoldani mint egy szutyok tárolt eljárásos nyelvben. Illetve persze lehet .NET CLR eljárásokat is definiálni RDBMS szinten, de az már tényleg adatbázisfüggő lenne.
    Mutasd a teljes hozzászólást!
  • Az a baj hogy annyira nem triviális a probléma mint elsőre gondolná az ember. Ez már tényleg architektúrális kérdés.

    Ha beteszel mindent tárolt eljárásba, akkor gyakorlatilag tök mindegy hogy milyen adatelérési réteget írsz, nem lehet nagy kunszt megírni általánosra (sőt erre egy elterjedtebb ORM is elég lehet) azt, hogy csak tárolt eljárásokat hívogass. A probléma ott kezdődik hogy ekkor MINDENT le kell implementálnod külön, adatbázis specifikusan. Viszont így vért izzadsz a többszörös implementálással, kezelhetetlen lesz egy bizonyos méret utána a szoftver.
    Van aki szerint lassabb, szerintem sokkal megbízhatóbb ha a következő kérdést tesszük fel:
    - hova kerüljön az üzleti logika?
    - ha program szintre akkor a db-hez már csak CRUD művelet kéréseket nyújtasz be.
    - ha db szintre, akkor egyrészt nem érdemes többféle db-re implementálni az egészet mert kezelhetetlen lesz hogy az üzleti logikát több példányban kell implementálni és karbantartani. Ekkor fel sem merülhet szerintem a többféle adatbázis kérdése.
    - keverten (van amit db-ben valósítasz meg, van, amit egy BL rétegben. Ekkor lehet olyat látni hogy még a megjelenítési réteg hátterében is van BL kód. Ez tökönszúrása a csapatmunkának. Főleg ha bejön egy új kolléga...

    Az a legszebb az egészben hogy minél jobban belemerül az ember, annál több kérdésbe botlik.

    Morzel
    Mutasd a teljes hozzászólást!
  • Szvsz a legegyszerubb ha valamilyen ORM libet hasznalsz, pl Doctrine, ennek sajat lekerdezo nyelve van, amibol a hasznalt RDBMS-hez valo queryket generalja.

    Ha megis sajat megoldast akarsz, Martin Fowler Patterns of Enterprise Application Architecture c. konyveben talalsz errol egy csomo okossagot, meg megnezheted a nepszerubb CMS-ek forrasat!
    Mutasd a teljes hozzászólást!
  • :)
    tapasztalt ismerős: az egyetemen ilyenkor meg szoktam kérdezni pár havert, és általában semmivel sem okosabbak mint én:)
    olyat meg nem nagyon ismerek, aki 20 éve ebből él

    szóval azt mondjátok, hogy így kéne:

    class DB { procedure select_forum_entries_limit_x_y(par1, par2) {} } class MySQL_DB : DB { procedure select_forum_entries_limit_x_y(par1, par2) { query="select * from forum Limit par1, par2" .... } } class Oracle_DB : DB { procedure select_forum_entries_limit_x_y(par1, par2) { query="select * from forum " // megamikell .... } }

    és akkor ezt minden lekérdezésre?
    ilyenkor egy sima select count(*) from tábla-t is ide tesz az ember, vagy az ugyis mindengol ugyan az, maradhat benn?

    Vagy tegyek mindent tárolt eljárásba? elvileg az is simán megoldható, nem? és kb ugyan az az eredmény?
    Mutasd a teljes hozzászólást!
  • Egyetértek stl-el.
    A gond ott van hogy általános kódot nem tudsz írni ami mindenhol [jól] működik (ha működik egyáltalán).

    Készítesz egy szép, többrétegű architektúrát ahogy illik és nem felejtesz el két dolgot:
    - lehessen könnyen (mondjuk konfig állományból) állítani hogy milyen adatbázissal dolgozzon a program.
    - nem felejtesz el interfacet készíteni a DAO réteghez hogy könnyebb legyen leimplementálni ha egy újabb db miatt megint neki kell esni és ne legyen teljesen átláthatatlan.

    Megjegyzés: ha ennyire nem vagy még tisztában azzal hogy hogyan érdemes ilyesmit megtervezni, hidd el (saját tapasztalat és másokon is láttam), jobban jársz ha segítséget kérsz ebben egy tapasztaltabb ismerőstől aki elmagyarázza hogy-mit-merre, milyen rétegek kellenek és melyiknek mi a funkciója és hogyan tudod elérni hogy ezek teljesen függetlenek legyenek, sehol se follyanak össze.

    Morzel
    Mutasd a teljes hozzászólást!
  • Szia!

    Szerintem először tisztában kell lenni azzal, hogy milyen célközönségnek írod a programot. Ha tudomásul veszed, hogy mindenki nem tudja ugyanolyan hatékonyan használni ugyanazt a programot, akkor már el lehet indulni. Én az ODBC-t néztem ki erre a feladatra. Korlátok között ugyan, de jelenleg a programjaim futnak Access MDB, MySql, Microsoft SQL Server, DBF és feltételezhetően minden ODBC-felületen műdödő adatbázis kezelővel (akár Excel munkafüzettel is). A korlátokkal megtanultam együtt élni és nem érzem, hogy a fejlesztésekben bármiben hátráltatna. Igaz nem is akarok 1-2 millió rekordnál egyszerre többer kezelni. Ha ilyen eset fordulna elő valószínűleg úgysem ezeket a programokat választaná a megrendelő. Szóval a feladat nem megoldhatatlan, de némi lemondással azért jár. Az az objektum ami pedig ezt biztosítja mindössze 50 kbyte. Szerintem előre :).

    B.T.
    Mutasd a teljes hozzászólást!
  • Csak úgy tudod valóban ab. függetlenné tenni, ha írsz egy adatelérési réteget. Ezt legegyszerűbben úgy teheted meg, ha az adatbázis kezeléssel foglalkozó részeket külön file-ba teszed. Ebbe lesz egy csomó function ami lekérdezi vagy módosítja az adatbázist, és visszatér olyan általános dolgokkal, mint pl. egy tömb.
    Ezt a réteget meg tudod sokszorozni, így meg lehet írni minden rdbms-hez a sajátot. Ha mindegyiket külön folderbe teszed, akkor egy config-ból lehet venni, hogy melyik folder-ből include-olj.

    Ez persze azt is jelenti, hogy egy módosítást annyi helyen kell elvégezned, ahány rdbms kezelő adatréteged van.
    Mutasd a teljes hozzászólást!
  • Az ADOdb sem tetszik?

    "ADOdb is a database abstraction library for PHP. [...] The PHP version currently supports an amazing number of databases, thanks to the wonderful ADOdb community: MySQL, PostgreSQL, Interbase, Firebird, Informix, Oracle, MS SQL, Foxpro, Access, ADO, Sybase, FrontBase, DB2, SAP DB, SQLite, Netezza, LDAP, and generic ODBC, ODBTP."


    Ha már nem akarsz saját megoldást, és így külső lib-en gondolkozol, akkor az ADOdb megoldás lehet a számodra. Bár sok olyan dolog van, amitől elesel, ha ilyen köztes kódot használsz (ezek kimondottan az egyes SQL motorok speciális lehetőségei), de legalább nem kell újra feltalálni a kereket. Fontold meg...
    Mutasd a teljes hozzászólást!
  • MySQL tud XML formátumú adatokat kezelni ki- és bemenetként is, de hogy ezt a funkciót hogy lehet PHP-ből elérni, azt nem találom:

    MySQL XML műveletek

    Az MSSQL is rendelkezik XML támogatással, és szerintem az Oracle adatbázis-kezelőjében is biztos van.
    Mutasd a teljes hozzászólást!
  • Csak egy hirtelen ötlet komolyabb átgondolás nélkül, szóval bocs, ha teljes hülyeséget írok: elég sok adatbázis-kezelő tud XML-ből importálni. Nem lehetne megoldani úgy esetleg, hogy standard XML-t generálsz, aztán azt viszed be az SQL-be?

    <szerk.> Mondjuk hogy exportálni mennyire tudnak XML kódot azt nem tudom, mindjárt utánanézek...
    Mutasd a teljes hozzászólást!
  • Ez az adatbázis függetlenség szerintem értelmetlen.

    A függvények jó részéből kizárod magad vele, mert elég ritka pl. a mysql-ben és az mssql-ben az azonos nevű függvény.

    A top/limit és egyéb variációkat meg már meg se említsem.
    Mutasd a teljes hozzászólást!
  • Sziasztok!

    Egy saját parpill egyszerű, de az idők folyamával talán komplexebbé váló CMS-t írok. A kérdés, hogy hogy hogyan próbáljam adatbázis-kezelő függetlenné tenni?
    Ami eddig felmerült:
    -tárolt eljárások: viszont akkor mindet meg kell írni minden adatbázisra.
    -PEAR::DB (Manual :: DB) de ezt nem fejlesztik... akkor mégsem kéne...
    -PEAR::DB_DataObject: (Manual :: What DB_DataObject can do) ez a DB-vel együtt elanult?
    -PEAR::MDB2: most igy gyorsan néztem.. ez nincs annyira dokumentálva? kevésnek tunik

    Ez a PEAR fenn szokott lenni a szolgáltatóknál? mert olyan megoldás kéne ami mindenütt használható

    -saját megoldás: kb ugyan azt kéne megcsinálni, amit a PEAR tud, csak ahhoz tudni kéne, mit kell megcsinálni:) azaz mik az adatbázis specifikus dolgok
    -más: mi?

    Ti hogyan csinálnátok?

    még sosem használtam, és az is baj, hogy nme tudom, mit lehet ,mit nem. MySQL-t haszánltam mindig, meg egyetemen ORACLE-t, és nem tudom, mit tehetek, mit nem, pl mi van, ha bele írok egy sima query-be limit-et, mert nem tudom, hogy azt az oracle nem eszi meg?
    Mutasd a teljes hozzászólást!
Tetszett amit olvastál? Szeretnél a jövőben is értesülni a hasonló érdekességekről?
abcd