Escribiendo mis propios DBMS: almacenamiento de bases de datos -- ++ campo con c++11 campo con file-system campo con database camp codereview Relacionados El problema

Writing my own DBMS: Storing databases


8
vote

problema

Español

He estado interesado en escribir algo significativo en C ++ durante mucho tiempo, pero tuve dificultades para no elegir Java o C # para un nuevo proyecto ... Ahora he encontrado algo para el cual C ++ parece ser el Herramienta adecuada: escribir un sistema de gestión de bases de datos.

Le voy a mostrar el código para el primer paso: almacenar bases de datos.

El código está escrito en Microsoft Visual C ++ 17 y estoy tratando de tener un código que sea lo más moderno posible. Tampoco tenía la intención de construir una biblioteca de serialización, simplemente sucedió. Esta biblioteca exporta sus métodos a través de un DLL.


stdafx.h

  #pragma once  #include "targetver.h"  #define WIN32_LEAN_AND_MEAN             // Exclude rarely-used stuff from Windows headers // Windows Header Files: #include <windows.h>  #include <string> #include <vector> #include <fstream> #include <filesystem> #include <optional>  #ifdef DBMS_EXPORTS #define DBMS_EXPORTS_API __declspec(dllexport) #else #define DBMS_EXPORTS_API __declspec(dllimport) #endif   

titular.h

  #pragma once  // Including SDKDDKVer.h defines the highest available Windows platform.  // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.  #include <SDKDDKVer.h>   

dbms.h

  #pragma once  #include "stdafx.h" #include "Database.h"  namespace DBMS {         class DBMS     {     public:         DBMS_EXPORTS_API DBMS(const std::string file);          DBMS_EXPORTS_API Database& CreateDatabase(const std::string file, const std::string name);          DBMS_EXPORTS_API std::optional<std::reference_wrapper<const Database>> GetDatabaseByFile(const std::string file) const;          DBMS_EXPORTS_API std::optional<std::reference_wrapper<const Database>> GetDatabaseByName(const std::string name) const;          DBMS_EXPORTS_API void DeleteDatabase(const Database& database);      private:         const std::string file;         std::vector<Database> databases;          void SaveToDisk() const;     }; }   

Database.h

  #pragma once  #include "stdafx.h"  namespace DBMS {     class Database     {     public:         DBMS_EXPORTS_API Database(const std::string file, const std::string name);          DBMS_EXPORTS_API std::string GetFile() const;          DBMS_EXPORTS_API std::string GetName() const;          DBMS_EXPORTS_API bool operator==(const Database& other) const;          DBMS_EXPORTS_API bool operator!=(const Database& other) const;      private:         std::string file;         std::string name;     }; }   

serializer.h

  <!doctype html> <html lang="en">     <head>         <title></title>         <style>             .card{                 position: relative;                 float: left;                 width: 350px;                 height: 500px;                 text-align: center;             }              .wonDeck{                 position: absolute;                 bottom: 0;                 width: 75px;                 height: 100px;                 text-align: center;             }              .card{                 margin: 0 5%;             }              .card:first-of-type{                 margin-left: 0;             }              .card:last-of-type{                 margin-right: 0;             }              .card .text{                 position: absolute;                 margin: 0 0 0 -25%;                 left: 35%;                 height: 30%;                 width: 50%;                 font-size: 26px;                 color: rgb(150, 150, 150);             }              .wonDeck .text{                 position: absolute;                 margin: 0 0 0 -25%;                 left: 50%;                 height: 30%;                 width: 50%;                 font-size: 16px;                 color: rgb(150, 150, 150);             }              .warDeck .text{                 position: absolute;                 margin: 0 0 0 -25%;                 left: 50%;                 height: 30%;                 width: 50%;                 font-size: 16px;                 color: rgb(150, 150, 150);             }              .cardHolder{                 position: absolute;                 top: 0;                 left: 0;                 width: 75%;                 height: 350px;                 font-size: 26px;                 color: rgb(0, 0, 0);                 border: 1px dashed black;                 background-color: rgba(0, 0, 0, 0.5);             }              .wonCardsHolder, .warCardsHolder{                 position: absolute;                 top: 0;                 left: 0;                 width: 100%;                 height: 100%;                 font-size: 16px;                 color: rgb(0, 0, 0);                 border: 1px dashed black;                 background-color: rgba(0, 0, 0, 0.5);             }               .warDeck{                 position: relative;                 float: right;                 width: 75px;                 height: 100px;             }              #reshuffle{                 display: none;             }         </style>     </head>     <body>         <div id="player1CurrentCard" class="card">             <div class="warDeck">                 <div class="warCardsHolder"></div>                 <div class="text">                     <p>War Deck</p>                 </div>             </div>             <div class="cardHolder"></div>              <div class="text">                 <p>Player 1 Card</p>             </div>             <div id="player1WonDeck" class="wonDeck">                 <div class="wonCardsHolder"></div>                 <div class="text">                     <p>Won Deck</p>                 </div>             </div>         </div>          <div id="player2CurrentCard" class="card">             <div class="cardHolder"></div>             <div class="warDeck">                 <div class="warCardsHolder"></div>                 <div class="text">                     <p>War Deck</p>                 </div>             </div>             <div class="text">                 <p>Player 2 Card</p>             </div>             <div id="player2WonDeck" class="wonDeck">                 <div class="wonCardsHolder"></div>                 <div class="text">                     <p>Won Deck</p>                 </div>             </div>         </div>         <button id="play">Play</button>         <button id="reshuffle">Reshuffle</button>     </body>     <script src="war.js"></script> </html> 0  

dbms.cpp

  <!doctype html> <html lang="en">     <head>         <title></title>         <style>             .card{                 position: relative;                 float: left;                 width: 350px;                 height: 500px;                 text-align: center;             }              .wonDeck{                 position: absolute;                 bottom: 0;                 width: 75px;                 height: 100px;                 text-align: center;             }              .card{                 margin: 0 5%;             }              .card:first-of-type{                 margin-left: 0;             }              .card:last-of-type{                 margin-right: 0;             }              .card .text{                 position: absolute;                 margin: 0 0 0 -25%;                 left: 35%;                 height: 30%;                 width: 50%;                 font-size: 26px;                 color: rgb(150, 150, 150);             }              .wonDeck .text{                 position: absolute;                 margin: 0 0 0 -25%;                 left: 50%;                 height: 30%;                 width: 50%;                 font-size: 16px;                 color: rgb(150, 150, 150);             }              .warDeck .text{                 position: absolute;                 margin: 0 0 0 -25%;                 left: 50%;                 height: 30%;                 width: 50%;                 font-size: 16px;                 color: rgb(150, 150, 150);             }              .cardHolder{                 position: absolute;                 top: 0;                 left: 0;                 width: 75%;                 height: 350px;                 font-size: 26px;                 color: rgb(0, 0, 0);                 border: 1px dashed black;                 background-color: rgba(0, 0, 0, 0.5);             }              .wonCardsHolder, .warCardsHolder{                 position: absolute;                 top: 0;                 left: 0;                 width: 100%;                 height: 100%;                 font-size: 16px;                 color: rgb(0, 0, 0);                 border: 1px dashed black;                 background-color: rgba(0, 0, 0, 0.5);             }               .warDeck{                 position: relative;                 float: right;                 width: 75px;                 height: 100px;             }              #reshuffle{                 display: none;             }         </style>     </head>     <body>         <div id="player1CurrentCard" class="card">             <div class="warDeck">                 <div class="warCardsHolder"></div>                 <div class="text">                     <p>War Deck</p>                 </div>             </div>             <div class="cardHolder"></div>              <div class="text">                 <p>Player 1 Card</p>             </div>             <div id="player1WonDeck" class="wonDeck">                 <div class="wonCardsHolder"></div>                 <div class="text">                     <p>Won Deck</p>                 </div>             </div>         </div>          <div id="player2CurrentCard" class="card">             <div class="cardHolder"></div>             <div class="warDeck">                 <div class="warCardsHolder"></div>                 <div class="text">                     <p>War Deck</p>                 </div>             </div>             <div class="text">                 <p>Player 2 Card</p>             </div>             <div id="player2WonDeck" class="wonDeck">                 <div class="wonCardsHolder"></div>                 <div class="text">                     <p>Won Deck</p>                 </div>             </div>         </div>         <button id="play">Play</button>         <button id="reshuffle">Reshuffle</button>     </body>     <script src="war.js"></script> </html> 1  

Database.cpp

  <!doctype html> <html lang="en">     <head>         <title></title>         <style>             .card{                 position: relative;                 float: left;                 width: 350px;                 height: 500px;                 text-align: center;             }              .wonDeck{                 position: absolute;                 bottom: 0;                 width: 75px;                 height: 100px;                 text-align: center;             }              .card{                 margin: 0 5%;             }              .card:first-of-type{                 margin-left: 0;             }              .card:last-of-type{                 margin-right: 0;             }              .card .text{                 position: absolute;                 margin: 0 0 0 -25%;                 left: 35%;                 height: 30%;                 width: 50%;                 font-size: 26px;                 color: rgb(150, 150, 150);             }              .wonDeck .text{                 position: absolute;                 margin: 0 0 0 -25%;                 left: 50%;                 height: 30%;                 width: 50%;                 font-size: 16px;                 color: rgb(150, 150, 150);             }              .warDeck .text{                 position: absolute;                 margin: 0 0 0 -25%;                 left: 50%;                 height: 30%;                 width: 50%;                 font-size: 16px;                 color: rgb(150, 150, 150);             }              .cardHolder{                 position: absolute;                 top: 0;                 left: 0;                 width: 75%;                 height: 350px;                 font-size: 26px;                 color: rgb(0, 0, 0);                 border: 1px dashed black;                 background-color: rgba(0, 0, 0, 0.5);             }              .wonCardsHolder, .warCardsHolder{                 position: absolute;                 top: 0;                 left: 0;                 width: 100%;                 height: 100%;                 font-size: 16px;                 color: rgb(0, 0, 0);                 border: 1px dashed black;                 background-color: rgba(0, 0, 0, 0.5);             }               .warDeck{                 position: relative;                 float: right;                 width: 75px;                 height: 100px;             }              #reshuffle{                 display: none;             }         </style>     </head>     <body>         <div id="player1CurrentCard" class="card">             <div class="warDeck">                 <div class="warCardsHolder"></div>                 <div class="text">                     <p>War Deck</p>                 </div>             </div>             <div class="cardHolder"></div>              <div class="text">                 <p>Player 1 Card</p>             </div>             <div id="player1WonDeck" class="wonDeck">                 <div class="wonCardsHolder"></div>                 <div class="text">                     <p>Won Deck</p>                 </div>             </div>         </div>          <div id="player2CurrentCard" class="card">             <div class="cardHolder"></div>             <div class="warDeck">                 <div class="warCardsHolder"></div>                 <div class="text">                     <p>War Deck</p>                 </div>             </div>             <div class="text">                 <p>Player 2 Card</p>             </div>             <div id="player2WonDeck" class="wonDeck">                 <div class="wonCardsHolder"></div>                 <div class="text">                     <p>Won Deck</p>                 </div>             </div>         </div>         <button id="play">Play</button>         <button id="reshuffle">Reshuffle</button>     </body>     <script src="war.js"></script> </html> 2  
Original en ingles

I've been interested in writing something meaningful in C++ for a long time, yet I had a hard time not picking Java or C# for a new project... Now I've found something for which C++ seems to be the right tool: Writing a Database Management System.

I'm going to show you the code for the first step: Storing databases.

The code is written in Microsoft Visual C++ 17 and I'm trying to have code that is as modern as possible. I also didn't intend to build a serialization library, it just happened. This library exports its methods through a DLL.


stdafx.h

#pragma once  #include "targetver.h"  #define WIN32_LEAN_AND_MEAN             // Exclude rarely-used stuff from Windows headers // Windows Header Files: #include <windows.h>  #include <string> #include <vector> #include <fstream> #include <filesystem> #include <optional>  #ifdef DBMS_EXPORTS #define DBMS_EXPORTS_API __declspec(dllexport) #else #define DBMS_EXPORTS_API __declspec(dllimport) #endif 

targetver.h

#pragma once  // Including SDKDDKVer.h defines the highest available Windows platform.  // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.  #include <SDKDDKVer.h> 

DBMS.h

#pragma once  #include "stdafx.h" #include "Database.h"  namespace DBMS {         class DBMS     {     public:         DBMS_EXPORTS_API DBMS(const std::string file);          DBMS_EXPORTS_API Database& CreateDatabase(const std::string file, const std::string name);          DBMS_EXPORTS_API std::optional<std::reference_wrapper<const Database>> GetDatabaseByFile(const std::string file) const;          DBMS_EXPORTS_API std::optional<std::reference_wrapper<const Database>> GetDatabaseByName(const std::string name) const;          DBMS_EXPORTS_API void DeleteDatabase(const Database& database);      private:         const std::string file;         std::vector<Database> databases;          void SaveToDisk() const;     }; } 

Database.h

#pragma once  #include "stdafx.h"  namespace DBMS {     class Database     {     public:         DBMS_EXPORTS_API Database(const std::string file, const std::string name);          DBMS_EXPORTS_API std::string GetFile() const;          DBMS_EXPORTS_API std::string GetName() const;          DBMS_EXPORTS_API bool operator==(const Database& other) const;          DBMS_EXPORTS_API bool operator!=(const Database& other) const;      private:         std::string file;         std::string name;     }; } 

Serializer.h

#pragma once  #include "stdafx.h" #include "Database.h" #include <iostream>  namespace DBMS {     template <typename T>     class Serializer     {     public:         static void Serialize(std::ofstream& out, const T& elem)         {             static_assert(std::is_trivially_copyable_v<T>, "standard template is only defined for trivially copyable values");             static_assert(!std::is_pointer_v<T>, "standard template is not defined for pointers of trivially copyable values");             static_assert(!std::is_array_v<T>, "standard template is not defined for arrays of trivially copyable values");             out.write(reinterpret_cast<const char*>(&elem), sizeof(T));         }          static T Deserialize(std::ifstream& in)         {             static_assert(std::is_trivially_copyable_v<T>, "standard template is only defined for trivially copyable values");             T elem;             in.read(reinterpret_cast<char*>(&elem), sizeof(T));             return elem;         }     };      template <typename T>     class Serializer<T*>     {     public:         static void Serialize(std::ofstream& out, const T* const& elem, size_t length)         {             static_assert(std::is_trivially_copyable_v<T>, "standard template is only defined for trivially copyable values");             out.write(reinterpret_cast<const char*>(elem), sizeof(T) * length);         }          static T* Deserialize(std::ifstream& in, size_t length)         {             static_assert(std::is_trivially_copyable_v<T>, "standard template is only defined for trivially copyable values");             auto elements = std::make_unique<T[]>(length);             T* raw = elements.get();             in.read(reinterpret_cast<char*>(raw), sizeof(T) * length);             elements.release();             return raw;         }     };      template <typename E>     class Serializer<std::vector<E>>     {     public:         static void Serialize(std::ofstream& out, const std::vector<E>& vector)         {             Serializer<uint32_t>::Serialize(out, vector.size());              for (const E& elem : vector)             {                 Serializer<E>::Serialize(out, elem);             }         }          static std::vector<E> Deserialize(std::ifstream& in)         {             auto size = Serializer<uint32_t>::Deserialize(in);             auto vector = std::vector<E>();             vector.reserve(size);              for (uint32_t i = 0; i < size; i++)             {                 vector.push_back(Serializer<E>::Deserialize(in));             }              return vector;         }     };      template <>     class Serializer<std::string>     {     public:         static void Serialize(std::ofstream& out, const std::string& string)         {             Serializer<uint32_t>::Serialize(out, string.length());             Serializer<const char*>::Serialize(out, string.data(), string.length() + 1);         }          static std::string Deserialize(std::ifstream& in)         {             auto length = Serializer<uint32_t>::Deserialize(in);             auto raw = Serializer<char*>::Deserialize(in, length + 1);             return std::string(raw, length + 1);         }     };      template <>     class Serializer<Database>     {     public:         static void Serialize(std::ofstream& out, const Database& database)         {             Serializer<std::string>::Serialize(out, database.GetFile());             Serializer<std::string>::Serialize(out, database.GetName());         }          static Database Deserialize(std::ifstream& in)         {             auto file = Serializer<std::string>::Deserialize(in);             auto name = Serializer<std::string>::Deserialize(in);             return Database(file, name);         }     }; } 

DBMS.cpp

// DBMS.cpp : Defines the exported functions for the DLL application. //  #include "stdafx.h" #include "Database.h" #include "Serializer.h"  namespace DBMS {     class DBMS     {     public:         DBMS_EXPORTS_API DBMS(const std::string file) : file(file)         {             if (std::experimental::filesystem::exists(file))             {                 std::ifstream fs(file, std::ios::binary);                 if (fs.is_open())                 {                     databases = Serializer<std::vector<Database>>::Deserialize(fs);                 }             }             else             {                 // save empty database to disk                 SaveToDisk();             }         }          DBMS_EXPORTS_API Database& CreateDatabase(const std::string file, const std::string name)         {             Database database(file, name);             databases.push_back(database);             SaveToDisk();             return databases.back();         }          DBMS_EXPORTS_API std::optional<std::reference_wrapper<const Database>> GetDatabaseByFile(const std::string file) const         {             for (auto& database : databases)             {                 if (database.GetFile() == file)                 {                     return database;                 }             }             return std::optional<std::reference_wrapper<const Database>>();         }          DBMS_EXPORTS_API std::optional<std::reference_wrapper<const Database>> GetDatabaseByName(const std::string name) const         {             for (auto& database : databases)             {                 if (database.GetName() == name)                 {                     return database;                 }             }             return std::optional<std::reference_wrapper<const Database>>();         }          DBMS_EXPORTS_API void DeleteDatabase(const Database& database)         {             for (const auto& db : databases)             {                 if (db == database)                 {                     auto it = std::find(databases.begin(), databases.end(), database);                     if (it != databases.end())                     {                         databases.erase(it);                     }                 }             }             SaveToDisk();         }      private:         const std::string file;         std::vector<Database> databases;          void SaveToDisk() const         {             std::ofstream fs(file, std::ios::binary, std::ios::trunc);   // trunc is a dirty hack to not have to be smart             if (fs.is_open())             {                 Serializer<std::vector<Database>>::Serialize(fs, databases);             }         }     }; } 

Database.cpp

#include "stdafx.h"  namespace DBMS {     class Database     {     public:         DBMS_EXPORTS_API Database(const std::string file, const std::string name) : file(file), name(name)         {          }          DBMS_EXPORTS_API std::string GetFile() const         {             return file;         }          DBMS_EXPORTS_API std::string GetName() const         {             return name;         }          DBMS_EXPORTS_API bool operator==(const Database& other) const         {             return (file == other.file && name == other.name);         }          DBMS_EXPORTS_API bool operator!=(const Database& other) const         {             return !(*this == other);         }      private:         std::string file;         std::string name;     }; } 
           
         
         

Lista de respuestas

2
 
vote

Su código aparece técnicamente funcional, pero en realidad no parece ser muy útil para almacenar los datos.

  • parece tener un sistema de identificación de archivos de base de datos adecuado
  • parece tener una capa de serialización
  • no parece tener ningún tipo de trozo de capas de consulta
  • no parece tener un código de capas de diseño de archivos
  • no parece tener una consistencia de archivos / reconstruir el stub

Nota que dependiendo de cuál es su objetivo, debe considerar lo siguiente:

  • relacional db = & gt; Muy, muy difícil
  • Datos de longitud variable = & gt; Necesidad de construir índices
  • sql u otra entrada de texto = & gt; Necesita un analizador de idiomas, constructor de consulta y evaluador
  • en el lugar Modificación del archivo de base de datos (evitando toda la lectura completa y escriba fuera de la base de datos) = & gt; Necesidad de poder tener entrelazado, extensible y espacio administrado (para manejar cualquier estructura de datos de eliminación e inserciones).

Usted absolutamente puede aumentar considerablemente el rendimiento / reducir el costo del servidor si tiene un flujo de datos que se puede optimizar; Pero a un costo de estar bloqueado en un mecanismo de almacenamiento de datos inflexible y no probado que tiene que hacer y mantenerse. He realizado el siguiente (código de propiedad) que tuvo un rendimiento mucho mayor que la base de datos de propósito general que reemplazó.

  • anexar a / selección de las tablas solo
  • generación de tabla de pase único
  • archivo único por mesa o índice
  • Datos de tamaño variable utilizando un índice
  • Re-generación de índice a través de las tablas analizables que describen
  • Las tablas contienen alineadas (con el sistema de almacenamiento de almacenamiento de eficiencia del sistema de archivos múltiples) datos enmarcados con cheques CRC para la recuperación de corrupción
  • Índices Chunked con CRC para la recuperación de la corrupción
  • Compromiso eventual con el disco (en la memoria Escrite el punto de vista único del caché de la verdad) con un bloqueo de extensión para el uso simultáneo con escritos de bloques para el rendimiento del rendimiento
  • todas las adjuntas en una tabla son transaccionales y secuenciales
  • las consultas son asíncronas y no están bloqueadas entre sí o adjuntas)
  • Implementación del servidor de la base de datos binaria TCP con la API basada en la clase no de texto
  • Instantánea en vivo para copias de seguridad incrementales con ancho de banda de disco de aceleración
  • escrito en C #
 

Your code appears technically functional, but doesn't actually appear be very useful in storing any data.

  • It appears to have a suitable database file identification system
  • It appears to have a serialisation layer
  • It does not appear to have any kind of query layer stub
  • It does not appear to have a file layout layer stub
  • It does not appear to have file consistency / rebuilding mechanism stub

Note that depending on what your objective is then you should consider the following:

  • Relational DB => very, very difficult
  • Variable length data => need to build indexes
  • Sql or other text input => need a language parser, query constructor and evaluator
  • In place database file modification (avoiding entire read in and write out of the database) => need to be able to have intertwined, extensible and space managed (to handle any deletions and insertions) data structures.

You absolutely can greatly increase performance / reduce server cost if you happen to have a data flow that can be optimised for; but at the cost of being locked into an inflexible, unproven data storage mechanism that you have to make and maintain yourself. I have made the following (propriety code) which had much higher performance than the general purpose database it replaced.

  • append to /selection from tables only
  • single pass table generation
  • single file per table or index
  • variable sized data using an index
  • index re-generation though self describing parsable tables
  • tables contain aligned (with file system efficient storage block multiple) framed data with CRC checks for corruption recovery
  • chunked indexes with CRC for corruption recovery
  • eventual commitment to disk (in memory write back single point of truth cache) with extent locking for concurrent usage with block writes for throughput performance
  • all appends on a table are transactional and sequenced
  • queries are asynchronous and not blocked by each other or appends)
  • tcp binary database server implementation with non-text class based API
  • live snapshotting for incremental backups with throttling disk bandwidth
  • written in C#
 
 

Relacionados problema

3  Personalizar los tipos de datos en un modelo generado con hibernación  ( Customize data types in a generated model with hibernate ) 
Tengo una aplicación de primavera / hibernación con la siguiente clase de dominio (código irrelevante despojado de brevedad): @Entity @Data public class Pr...

3  Mi primer modelo de prueba en phpunit  ( My first model test in phpunit ) 
Acabo de crear una prueba para crear mi clase de pasarela. He escrito alrededor de 8 pruebas y todos estamos pasando. Espero que cualquiera pueda ofrecer cual...

2  Objeto de búsqueda de la base de datos, o fetchlo usando una API si no está ahí  ( Fetch object from database or fetch it using an api if it isnt there ) 
Para dar algunos antecedentes en este código en particular, hay un controlador que recibe un objeto, las partes de los hashes y se analiza en una base de dato...

4  Dos clases de Python para actualizar una base de datos RRD  ( Two python classes to update an rrd database ) 
La primera clase de Python a continuación se usa en uno de mis proyectos actuales y es un enfoque totalmente diferente para cómo normalmente tomaría las cosas...

10  Insertar un valor de DBNULL en una base de datos  ( Inserting a dbnull value into a database ) 
Tengo código que funciona bastante bien. Solo necesito algunas de sus opiniones sobre cómo escribirlo mejor con menos línea de código. Quiero usar un operador...

5  Sincronización de una conexión ODBC  ( Synchronization of an odbc connection ) 
Dado que estoy aventurándose cada vez más en el multithreading, ahora tengo que pensar en cómo proteger mi precioso 9988776665544331 de romper en tiempos al...

2  Custom C # Dapper Orm Wrapper  ( Custom c dapper orm wrapper ) 
I am IC # .NET Developer por unos años ... Últimos dos meses he empezado a estudiar los patrones de diseño y los principios de la arquitectura de software emp...

2  Sesión nhibernate y implementación de transacciones  ( Nhibernate session and transaction implementation ) 
Para crear una arquitectura de acoplamiento suelto en mis aplicaciones web, he creado mi propia implementación para ORM, en este caso, NHibernate. Quiero qu...

4  Formularios: campos ordenados contra iteraciones dinámicas  ( Forms ordered fields vs dynamic iterations ) 
He hecho aproximadamente 2 formularios que tienen una acción del lado del servidor usando PHP. Para el primero, hice una variable para cada campo de forma y l...

2  Método de filtro DataGrid Muy lento  ( Datagrid filter method very slow ) 
Estoy teniendo muchos problemas en mi programa de base de datos con el intento de implementar un método de filtrado efectivo de DataGrid. Después de tomar con...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos