saltar al contenido

Cómo Raima Database Manager supera a SQLite

Los 4 principales desafíos con SQLite y cómo Raima Database Manager los evita

Desafío 1: rendimiento escalable

SQLite enfrenta problemas de rendimiento a medida que se agregan más usuarios y / o hardware adicional al sistema debido al diseño de "una escritura a la vez" y de un solo hilo.

RDM no tiene límites

RDM no tiene este problema, ya que su rendimiento mejora a medida que agrega mejor hardware y usuarios. RDM se ha optimizado para escalar y utilizar cualquier hardware adicional agregado al sistema RDM. Los usuarios adicionales también tienen un conjunto de rendimiento muy estable y consistente.  SQLite, por diseño, da prioridad a un usuario aleatorio. Esto hace que el rendimiento de algunos usuarios sea mucho mejor que el de otros.

Desafío 3: vida útil de Flash Media

SQLite no está optimizado para el almacenamiento de medios flash.

Optimizado para Flash Media

RDM optimiza y minimiza el número de escrituras en el medio de almacenamiento, prolongando la vida útil del dispositivo. Esto significa que se necesita menos mantenimiento y menos reemplazos durante la vida útil de la aplicación. Además, RDM funciona mejor en estos dispositivos debido a las optimizaciones que tiene.

Desafío 2: Soporte de plataforma

SQLite no admite tantas plataformas como RDM.

Independencia de la plataforma

RDM es compatible con casi todas las combinaciones de hardware y sistemas operativos. Ha sido optimizado para funcionar en cualquier entorno. RDM puede incluso ejecutarse sin un sistema operativo en una configuración básica.

Desafío 4: Integración del entorno de desarrollo

SQLite no está empaquetado con archivos de proyecto integrados y es compatible con todos los entornos de desarrollo estándar.

Fuera de la caja

El soporte RDM incluye Visual Studio, XCode, Makefiles, CMake, Wind River Workbench, Green Hills MULTI con archivos de proyecto empaquetados e integraciones de entornos de desarrollo.

Cambie de SQLite a RDM para mejorar la escalabilidad y el rendimiento

Raima Database Manager admite casi el mismo nivel de SQL que SQLite. Por lo tanto, el usuario solo necesitaría exportar el contenido delir base de datos a un formato CSV, XML o SQL, ejecuterdm-crearen su archivo de esquema de base de datos, luego ejecuterdm-importaren el archivo de formato CSV, XML o SQL y el usuario tendrá un RDM equivalente a la base de datos SQLite. Desde allí, el usuario Puede que tenga que migrar su aplicación, pero RDM admite la interfaz ODBC SQL, la interfaz JDBC Java y la interfaz ADO.NET C#, por lo que es posible que no tenga que haber cambios sustanciales en el código. Ver guía de migración.

Ejemplo de comparación de rendimiento: Raima Database Manager (RDM) frente a SQLite

La mayoría de los sistemas operativos y hardware actuales admiten subprocesos múltiples. SQLite no aprovecha esta oportunidad por el diseño en SQLite. Cuando hay muchas escrituras simultáneas en una base de datos SQLite, los usuarios de la aplicación experimentan una reducción significativa en la velocidad y es posible que la aplicación no cumpla con las expectativas de rendimiento de los usuarios. Es bien sabido que el acceso de escritura a la base de datos SQLite solo se puede otorgar si no se están atendiendo otras solicitudes. Es el diseño de "una escritura a la vez" dentro de SQLite lo que ralentiza el rendimiento. Por lo tanto, muchos propietarios de aplicaciones se ven obligados a buscar alternativas base de datos incrustada opciones para resolver su cuello de botella de rendimiento.

Raima ha elaborado una prueba que demuestra las diferencias entre la solución de base de datos RDM y SQLite. En esta prueba, demostramos que RDM es una buena alternativa a SQLite.

 

Como hicimos la prueba

En esta comparación de rendimiento, utilizamos un estándarTPC-Bmarco de prueba de www.tpc.org. El TPC-B mide el rendimiento en términos de cuántas transacciones por segundo puede realizar el sistema. La prueba se ha modificado para permitir comparaciones en las que varios clientes realizan trabajos en paralelo.

Usamos el mismo entorno de prueba y marco para SQLite y RDM. En la prueba, RDM demostró ser significativamente más rápido que SQLite. Vea la ilustración a continuación. La plataforma utilizada para la prueba fue la versión 14.1 de RDM que se ejecutaba contra SQLite v3.23 en una máquina con procesador Intel i7 estándar de Windows 10 con 16 GB de RAM y disco duro SATA estándar.

Raima Database Manager tiene un diseño optimizado para incorporado sistemas con un conjunto moderno y eficiente de API, junto con un formato de archivo de almacenamiento de base de datos bien diseñado. RDM permite escrituras y lecturas simultáneas y, por lo tanto, puede hacer muchas más veces la cantidad de trabajo que SQLite puede hacer.

Puntos destacados de la prueba:
Debido al soporte multiproceso de RDM, RDM ejecutará una cantidad sustancialmente mayor de transacciones en comparación con SQLite.

En el siguiente diagrama, RDM multiplica cuatro veces la cantidad de transacciones que SQLite puede realizar dentro del mismo período de tiempo y restricciones de hardware. Si esta prueba se realiza con un en memoria diseño, la diferencia es aún más notable.

 

El desglose de la prueba anterior muestra además el número de transacciones realizadas por segundo en cada cliente de la base de datos.

Conclusión

Como se demuestra en la ilustración anterior, debido al diseño de SQLite, tiene un número variable de transacciones que puede realizar por segundo en cada cliente de la base de datos. RDM ofrece un aumento de hasta cuatro veces en el número de transacciones por segundo por cliente. Si la estabilidad y la consistencia son importantes, RDM encaja perfectamente.

RDM está diseñado para ofrecer transacciones consistentes y confiables por segundo al mismo tiempo que es amigable y eficiente para múltiples usuarios.

Para obtener más puntos de referencia de pruebas de rendimiento haga clic aquí

¿Listo para empezar?

Cómo migrar de SQLite a RDM para mejorar la escalabilidad y el rendimiento

Hgracias a migrar a RDM en orden para probar los beneficios? La respuesta es más sencilla que tú. mayo suponer. RDM admite casi el mismo nivel de SQL que SQLite. Por lo tanto, el usuario solo necesitaría exportar el contenido delir base de datos a un formato CSV, XML o SQL, ejecuterdm-crearen su archivo de esquema de base de datos, luego ejecuterdm-importaren el archivo de formato CSV, XML o SQL y el usuario tendrá un RDM equivalente a la base de datos SQLite. Desde allí, el usuario Puede que tenga que migrar su aplicación, pero RDM admite la interfaz ODBC SQL, la interfaz JDBC Java y la interfaz ADO.NET C#, por lo que es posible que no tenga que haber cambios sustanciales en el código. 

FuncionesSintaxis / Lógica de SQLiteSintaxis / lógica de RaimaNotas
Inicializaciónint sqlite3_config (int, ...) - utilizado para realizar cambios de configuración global en SQLite con el fin de ajustar SQLite a las necesidades específicas de la aplicación.SQLSetConnectAttr () y utilice nuestros atributos definidos por el controlador para establecer opciones de configuración basadas en la conexión.Lista SQLite de opciones de configuración

Raima Lista de opciones
Conexión DB abiertasqlite3_open ("test.db", & db);SQLAllocHandle (), seguido por SQLConnect (). Una vez establecida la conexión, emita el mensaje "USE "comando usando SQLExecute () o SQLExecDirect ().SQLite permite múltiples archivos de base de datos con una sola conexión a través de la declaración ATTACH DATABASE
Bases de datos EN MEMORIAUtilice la opción ": memoria:";
sqlite3_open (": memoria:", & db);
Establezca el atributo de conexión SQL_ATTR_RDM_STORAGE_MEDIA en "INMEMORY_KEEP" llamando SQLSetConnectAttr ().¡SQLite no guardará la base de datos en memoria en el disco!
Raima te da la opción de guardar en disco.
Ejecutar SQL(i) Primero prepare la declaración
int sqlite3_prepare(
sqlite3 * db, / * Identificador de base de datos * /
const char * zSql, / * instrucción SQL, codificado en UTF-8 * /
int nByte, / * Longitud máxima de zSql en bytes. * /
sqlite3_stmt ** ppStmt, / * OUT: identificador de declaración * /
const char ** pzTail / * OUT: puntero a la parte no utilizada de zSql * /
);

(ii) Luego ejecutar utilizando
int sqlite3_step (sqlite3_stmt *)
(i) Ejecutar con SQLExecDirect(SQLHSTMT StatementHandle, SQLCHAR * StatementText, SQLINTEGER TextLength).

(ii) Preparar con SQLPrepare(SQLHSTMT StatementHandle, SQLCHAR * StatementText, SQLINTEGER TextLength) y luego ejecutar con SQLExecute(SQLHSTMT StatementHandle).
Dependiendo de la codificación, SQLite puede usar sqlite3_prepare16 () para codificación UTF-16 e int sqlite3_prepare16_v3 ()
Parámetros de encuadernaciónfamilia sqlite3_bind_ * de funciones se utiliza; p.ej
int sqlite3_bind_double (sqlite3_stmt *, int, doble);
int sqlite3_bind_int (sqlite3_stmt *, int, int);
int sqlite3_bind_null (sqlite3_stmt *, int);
int sqlite3_bind_text (sqlite3_stmt *, int, const char *, int, void (*) (void *));
int sqlite3_bind_pointer (sqlite3_stmt *, int, void *, const char *, void (*) (void *));
int sqlite3_bind_zeroblob (sqlite3_stmt *, int, int n);
SQLBindParameter (
SQLHSTMT StatementHandle,
SQLUSMALLINT ParameterNumber,
Tipo de entrada SQLSMALLINT,
SQLSMALLINT ValueType,
SQLSMALLINT ParameterType,
Precisión de longitud de SQLUINTEGER,
SQLSMALLINT ParameterScale,
SQLPOINTER ParameterValue,
SQLLEN ValueSize,
SQLLEN * StrLen_or_Ind
);
Llamada SQLParamData () y SQLPutData () para procesar los parámetros de blob de datos en ejecución especificados en las declaraciones de inserción y actualización.
Raima usa SQLBindCol () para vincular una variable de aplicación a la columna.

En SQLite, para RESTABLECER una declaración preparada para el uso del estado inicial: sqlite3_reset (sqlite3_stmt * pStmt)
ActasUtiliza comandos BEGIN-TRANSACTION, DEFERRED / INMEDIATE / EXCLUSIVE, END-TRANSACTION o COMMIT, SAVEPOINT y ROLLBACK(i) Utilice los comandos "INICIAR TRANSACCIÓN", "COMPROMISO", "ROLLBACK", "SAVEPOINT" y "ROLLBACK".

(ii) Llamar SQLEndTran () para confirmar o deshacer ".
Obtener conjunto de resultadosEn t sqlite3_step(sqlite3_stmt *)SQLFetch () o SQLFetchScroll () para obtener el siguiente conjunto de filas del conjunto de resultados. Para recuperar datos BLOB en fragmentos, llame SQLGetData ().Ambos DB pueden devolver códigos de error o siguiente FILA (que se detallan a continuación)
Acceder a una columna en una filacolumna_sqlite3 familia de funciones(i) Acceda a los valores de columna recuperados en las variables de aplicación configuradas con SQLBindCol () antes de buscar.

(ii) Llamar SQLGetData () en las columnas deseadas.
SQLite usa funciones basadas en el tipo de columna; doble sqlite3_column_double(sqlite3_stmt *, int iCol) o int sqlite3_column_int(..) o int sqlite3_column_bytes(..)
Cerrar declaraciónsqlite3_finalize(sqlite3_stmt * pStmt) destruye una declaración preparada y libera sus recursosLlamada SQLFreeHandle () en el identificador de instrucciones para liberar todos sus recursos.
Cerrar una conexión / control de base de datosEn t sqlite3_close(sqlite3 *) e int sqlite3_close_v2(sqlite3 *)SQLFreeHandle () para liberar los tiradores de conexión y entorno. Esto libera todos los identificadores de la base de datos asociados con la conexión.En SQLite es mejor usar sqlite3_close_v2 ya que está diseñado para su uso con lenguajes host que se recolectan como basura, y donde el orden en el que se llaman los destructores es arbitrario.
ConfiguraciónLa sqlite3_config () La interfaz se utiliza para realizar cambios de configuración global en SQLite con el fin de ajustar SQLite a las necesidades específicas de la aplicación.Utiliza un script de configuración para establecer variables de entorno.
CifradoEn t sqlite3_key(sqlite3 * db, const void * pKey, int nKey);

En t sqlite3_rekey(sqlite * db,
const void * pKey, int nKey / * La nueva clave * /
);
Llamada rdm_tfsAllocEncrypt(
const char * contraseña,
RDM_ENCRYPT * enc
) para crear un objeto de cifrado.

Pase el objeto de cifrado a SQLSetConnectAttr () utilizando el atributo SQL_ATTR_RDM_ENCRYPT.
SQLite utiliza la Extensión de cifrado SQLite (SEE), que se paga.

Raima usa el cifrado de cifrado AES con soporte para varios tamaños de clave (128, 192 y 256 bits)
AislamientoApoyos "Aislamiento serializable" , Pero en el modo WAL de escritura anticipada, proporciona "Aislamiento de instantáneas".Apoyos "Aislamiento serializable"
FuncionesSintaxis / Lógica de SQLiteSintaxis / lógica de RaimaNotas
Inicializaciónint sqlite3_config (int, ...) - utilizado para realizar cambios de configuración global en SQLite con el fin de ajustar SQLite a las necesidades específicas de la aplicación.SQLSetConnectAttr () y utilice nuestros atributos definidos por el controlador para establecer opciones de configuración basadas en la conexión.Lista SQLite de opciones de configuración

Raima Lista de opciones
Conexión DB abiertasqlite3_open ("test.db", & db);SQLAllocHandle (), seguido por SQLConnect (). Una vez establecida la conexión, emita el mensaje "USE "comando usando SQLExecute () o SQLExecDirect ().SQLite permite múltiples archivos de base de datos con una sola conexión a través de la declaración ATTACH DATABASE
Bases de datos EN MEMORIAUtilice la opción ": memoria:";
sqlite3_open (": memoria:", & db);
Establezca el atributo de conexión SQL_ATTR_RDM_STORAGE_MEDIA en "INMEMORY_KEEP" llamando SQLSetConnectAttr ().¡SQLite no guardará la base de datos en memoria en el disco!
Raima te da la opción de guardar en disco.
Ejecutar SQL(i) Primero prepare la declaración
int sqlite3_prepare(
sqlite3 * db, / * Identificador de base de datos * /
const char * zSql, / * instrucción SQL, codificado en UTF-8 * /
int nByte, / * Longitud máxima de zSql en bytes. * /
sqlite3_stmt ** ppStmt, / * OUT: identificador de declaración * /
const char ** pzTail / * OUT: puntero a la parte no utilizada de zSql * /
);

(ii) Luego ejecutar utilizando
int sqlite3_step (sqlite3_stmt *)
(i) Ejecutar con SQLExecDirect(SQLHSTMT StatementHandle, SQLCHAR * StatementText, SQLINTEGER TextLength).

(ii) Preparar con SQLPrepare(SQLHSTMT StatementHandle, SQLCHAR * StatementText, SQLINTEGER TextLength) y luego ejecutar con SQLExecute(SQLHSTMT StatementHandle).
Dependiendo de la codificación, SQLite puede usar sqlite3_prepare16 () para codificación UTF-16 e int sqlite3_prepare16_v3 ()
Parámetros de encuadernaciónfamilia sqlite3_bind_ * de funciones se utiliza; p.ej
int sqlite3_bind_double (sqlite3_stmt *, int, doble);
int sqlite3_bind_int (sqlite3_stmt *, int, int);
int sqlite3_bind_null (sqlite3_stmt *, int);
int sqlite3_bind_text (sqlite3_stmt *, int, const char *, int, void (*) (void *));
int sqlite3_bind_pointer (sqlite3_stmt *, int, void *, const char *, void (*) (void *));
int sqlite3_bind_zeroblob (sqlite3_stmt *, int, int n);
SQLBindParameter (
SQLHSTMT StatementHandle,
SQLUSMALLINT ParameterNumber,
Tipo de entrada SQLSMALLINT,
SQLSMALLINT ValueType,
SQLSMALLINT ParameterType,
Precisión de longitud de SQLUINTEGER,
SQLSMALLINT ParameterScale,
SQLPOINTER ParameterValue,
SQLLEN ValueSize,
SQLLEN * StrLen_or_Ind
);
Llamada SQLParamData () y SQLPutData () para procesar los parámetros de blob de datos en ejecución especificados en las declaraciones de inserción y actualización.
Raima usa SQLBindCol () para vincular una variable de aplicación a la columna.

En SQLite, para RESTABLECER una declaración preparada para el uso del estado inicial: sqlite3_reset (sqlite3_stmt * pStmt)
ActasUtiliza comandos BEGIN-TRANSACTION, DEFERRED / INMEDIATE / EXCLUSIVE, END-TRANSACTION o COMMIT, SAVEPOINT y ROLLBACK(i) Utilice los comandos "INICIAR TRANSACCIÓN", "COMPROMISO", "ROLLBACK", "SAVEPOINT" y "ROLLBACK".

(ii) Llamar SQLEndTran () para confirmar o deshacer ".
Obtener conjunto de resultadosEn t sqlite3_step(sqlite3_stmt *)SQLFetch () o SQLFetchScroll () para obtener el siguiente conjunto de filas del conjunto de resultados. Para recuperar datos BLOB en fragmentos, llame SQLGetData ().Ambos DB pueden devolver códigos de error o siguiente FILA (que se detallan a continuación)
Acceder a una columna en una filacolumna_sqlite3 familia de funciones(i) Acceda a los valores de columna recuperados en las variables de aplicación configuradas con SQLBindCol () antes de buscar.

(ii) Llamar SQLGetData () en las columnas deseadas.
SQLite usa funciones basadas en el tipo de columna; doble sqlite3_column_double(sqlite3_stmt *, int iCol) o int sqlite3_column_int(..) o int sqlite3_column_bytes(..)
Cerrar declaraciónsqlite3_finalize(sqlite3_stmt * pStmt) destruye una declaración preparada y libera sus recursosLlamada SQLFreeHandle () en el identificador de instrucciones para liberar todos sus recursos.
Cerrar una conexión / control de base de datosEn t sqlite3_close(sqlite3 *) e int sqlite3_close_v2(sqlite3 *)SQLFreeHandle () para liberar los tiradores de conexión y entorno. Esto libera todos los identificadores de la base de datos asociados con la conexión.En SQLite es mejor usar sqlite3_close_v2 ya que está diseñado para su uso con lenguajes host que se recolectan como basura, y donde el orden en el que se llaman los destructores es arbitrario.
ConfiguraciónLa sqlite3_config () La interfaz se utiliza para realizar cambios de configuración global en SQLite con el fin de ajustar SQLite a las necesidades específicas de la aplicación.Utiliza un script de configuración para establecer variables de entorno.
CifradoEn t sqlite3_key(sqlite3 * db, const void * pKey, int nKey);

En t sqlite3_rekey(sqlite * db,
const void * pKey, int nKey / * La nueva clave * /
);
Llamada rdm_tfsAllocEncrypt(
const char * contraseña,
RDM_ENCRYPT * enc
) para crear un objeto de cifrado.

Pase el objeto de cifrado a SQLSetConnectAttr () utilizando el atributo SQL_ATTR_RDM_ENCRYPT.
SQLite utiliza la Extensión de cifrado SQLite (SEE), que se paga.

Raima usa el cifrado de cifrado AES con soporte para varios tamaños de clave (128, 192 y 256 bits)
AislamientoApoyos "Aislamiento serializable" , Pero en el modo WAL de escritura anticipada, proporciona "Aislamiento de instantáneas".Apoyos "Aislamiento serializable"

RDM tiene una arquitectura flexible y un alto rendimiento