Tentang uuids, kunci utama dan database database

Artikel ini dikhususkan untuk versi alternatif driver Qt untuk bekerja dengan database. Secara umum, tidak ada banyak perbedaan dari driver Qt asli, hanya beberapa: 1) dukungan jenis UUID; 2) Bekerja dengan entitas "Transaksi" sebagai objek independen. Tetapi perbedaan ini menyebabkan revisi signifikan dari implementasi kode dari solusi Qt asli dan mengubah pendekatan penulisan kode kerja.





Kunci Utama: UUID atau Integer?

Saya pertama kali berkenalan dengan ide menggunakan UUID sebagai kunci utama pada tahun 2003, saat bekerja di tim lumba-lumba. Kami telah mengembangkan program untuk otomatisasi proses teknologi dalam produksi. DBMS memainkan peran penting dalam proyek ini. Saat itu FireBird versi 1.5. Ketika proyek tumbuh lebih kompleks, menjadi sulit untuk menggunakan pengidentifikasi bilangan bulat sebagai kunci utama. Saya akan menjelaskan beberapa kesulitan:





  • Masalah arsitektural: dari waktu ke waktu pelanggan mengirimkan data referensi untuk memasukkannya ke dalam versi baru kit distribusi. Terkadang direktori berisi kunci utama yang sudah ada di database kami. Saya harus menghilangkan tabrakan dalam proses agregasi data. Masalahnya tidak berakhir di sana: ketika menggunakan kit distribusi baru, tabrakan terbalik terjadi secara berkala.





  • : SELECT-, ( ). . . , , 2003 , - - .





UUID- , . UUID- , , SELECT- , . FireBird 1.5 UUID-, 32 ( UUID- ). , .





UUID- : 1) ; 2) . , . , , UUID-.





: UUID vs Integer MS SQL " – GUID ?"





FireBird

2012 FireBird. . QtFramework. FireBird 2.5 UUID-. : " Qt- FireBird QUuid?" Qt- UUID-. , , .





""

Qt- FireBird 2018 . . - , , ́ . . FireBird, . PostgreSQL, .





. Qt-FireBird . , Qt-, , : ( ) ( "" Driver). Qt- . , , : ( - ). Oracle, PostgreSQL, MS SQL ODBC. FireBird , API . , Qt-FireBird .





(2-3) , . . . , : , , , , sql- , . , . " - ". sql- .





"", , , . , "" , . , "" , , . , COMMIT ROLLBACK. , . Qt-.





, . (Driver) . , , . .





Qt-, :





- : " ?! ' - ', !" , , , , "" ODBC . , - , .





void function3(int value3)
{
    db::firebird::Driver::Ptr dbcon = fbpool().connect();
    db::firebird::Transaction::Ptr transact3 = dbcon->createTransact();
    QSqlQuery q3 {db::firebird::createResult(transact3)};

    if (!transact3->begin())
        return;
        
    if (!q3.prepare("INSERT INTO TABLE3 (VALUE3) VALUES (:VALUE3)"))
        return;
        
    sql::bindValue(q3, ":VALUE3" , value3);
    
    if (!q3.exec())
         return;

    transact3->commit();
}

void function2(int value2)
{
    db::firebird::Driver::Ptr dbcon = fbpool().connect();
    db::firebird::Transaction::Ptr transact2 = dbcon->createTransact();
    QSqlQuery q2 {db::firebird::createResult(transact2)};

    if (!transact2->begin())
        return;

    if (!q2.prepare("SELECT * FROM TABLE2 WHERE VALUE2 = :VALUE2"))
        return;
        
     sql::bindValue(q2, ":VALUE2 " , value2);
     
     if (!q2.exec())
         return;
         
    while (q2.next())
    {
        qint32 value3;
        sql::assignValue(value3, q2.record(), "VALUE3");
        function3(value3);
    }
}

void function1()
{
    db::firebird::Driver::Ptr dbcon = db::firebird::pool().connect();
    db::firebird::Transaction::Ptr transact1 = dbcon->createTransact();
    QSqlQuery q1 {db::firebird::createResult(transact1)};
    
    if (!transact1->begin())
        return;
        
    if (!sql::exec(q1, "SELECT * FROM TABLE1"))
        return;
        
    while (q1.next())
    {
        QSqlRecord r = q1.record();
        QUuidEx  id;
        qint32   value1;
        qint32   value2;
        sql::assignValue(id     , r, "ID     ");
        sql::assignValue(value1 , r, "VALUE1 ");
        sql::assignValue(value2 , r, "VALUE2 ");
        ...
        function2(value2);
    }
}
      
      



(1-3) . . QSqlQuery. ROLLBACK- SELECT- COMMIT- .





sql-. .





void function3(db::firebird::Transaction::Ptr transact, int value3)
{
    QSqlQuery q3 {db::firebird::createResult(transact)};
    //  - 
}

void function2(db::firebird::Transaction::Ptr transact, int value2)
{
    QSqlQuery q2 {db::firebird::createResult(transact)};
    //  - 
    function3(transact, value3);
}

void function1()
{
    db::firebird::Driver::Ptr dbcon = db::firebird::pool().connect();
    db::firebird::Transaction::Ptr transact = dbcon->createTransact();
    QSqlQuery q1 {db::firebird::createResult(transact)};
    
    if (!transact->begin())
        return;
        
    while (q1.next())
    {
        //  - 
        function2(transact, value2);
    }
    transact->commit();
}
      
      



PostgreSQL

2020 . : PostgreSQL. 18- , . PostgreSQL FireBird. Qt, , . Qt- : PREPARE EXECUTE. , , . , " ", PostgreSQL API. libpqxx , . " ". , . , . , , PostgreSQL . , . . singleConnect()



, . . singleConnect()



FALSE



. , . . , . .





MS SQL

MS SQL. , . MS SQL ODBC. PostgreSQL: - . , OLE DB MS SQL , ODBC . , "" . , NULL-. , .





Driver

Qt-. :





  • beginTransaction();





  • commitTransaction();





  • rollbackTransaction().





"" Qt-.





, , , . :





  • tables();





  • record();





  • primaryIndex();





  • formatValue();





  • escapeIdentifier().





. , , . , , .





, : "Forward Only". , , . , , SqlCachedResult



. - Qt-.





Driver



abortOperation()



, sql-, "" . Result



size2()



, sql-. size2()



, resultSize(const QSqlQuery&)



. .





GPL/LGPL 2.1. SqlCachedResult



, Qt . . PostgreSQL, , ( ). , : LGPL. , .





ALog, SharedTools.





-

. : FireBird, PostgreSQL, MS SQL. , . SharedTools .





QtCreator, QBS. :





  1. db_demo_project.qbs - ( 2-4);





  2. db_demo_firebird.qbs - FireBird ( FireBird-);





  3. db_demo_postgres.qbs - PostgreSQL ( libpq-dev);





  4. db_demo_mssql.qbs - MS SQL.





Linux, . Windows FireBird- (), .





- :





  • /tmp/db-demo-firebird.log





  • /tmp/db-demo-mssql.log





  • /tmp/db-demo-postgres.log





, . , - .





, , , : ", , . ?!" , !





Banyak pekerjaan saya dan pekerjaan rekan kerja telah diinvestasikan dalam penciptaan driver, banyak kehidupan telah dihabiskan. Mengetahui ketidaksukaan programmer untuk dependensi eksternal, saya tidak memiliki ilusi bahwa solusi yang disajikan akan digunakan "sebagaimana adanya". Saya mengakui bahwa seseorang memutuskan untuk "terbakar dengan setrika panas" Alog dan menggantinya dengan sesuatu dari mereka sendiri - saya tidak keberatan (saya melakukan ini sendiri dengan penebang lain;) Bagaimanapun, jika solusi kami menghemat waktu seseorang, atau berfungsi sebagai titik awal untuk ide-ide baru - itu akan bagus!








All Articles