Límites en SQLite

“Límites” en el contexto de este artículo significa tamaños o cantidades que no se pueden exceder. Nos preocupan cosas como el número máximo de bytes en un BLOB o el número máximo de columnas en una tabla.

SQLite fue diseñado originalmente con una política de evitar límites arbitrarios. Por supuesto, cada programa que se ejecuta en una máquina con memoria y espacio en disco finitos tiene algún tipo de límite. Pero en SQLite, esos límites no estaban bien definidos. La política era que si cabía en la memoria y se podía contar con un número entero de 32 bits, debería funcionar.

Desafortunadamente, se ha demostrado que la política sin límites crea problemas. Debido a que los límites superiores no estaban bien definidos, no se probaron y, a menudo, se encontraron errores al llevar SQLite al extremo. Por esta razón, las versiones de SQLite desde aproximadamente la versión 3.5.8 (2008-04-16) tienen límites bien definidos, y esos límites se prueban como parte del conjunto de pruebas.

Este artículo define cuáles son los límites de SQLite y cómo se pueden personalizar para aplicaciones específicas. La configuración predeterminada de los límites suele ser bastante grande y adecuada para casi todas las aplicaciones. Algunas aplicaciones pueden querer aumentar un límite aquí o allá, pero esperamos que tales necesidades sean poco frecuentes. Más comúnmente, una aplicación puede querer recompilar SQLite con límites mucho más bajos para evitar el uso excesivo de recursos en caso de error en los generadores de declaraciones SQL de nivel superior o para ayudar a frustrar a los atacantes que inyectan declaraciones SQL maliciosas.

Algunos límites se pueden cambiar en tiempo de ejecución por conexión utilizando la interfaz sqlite3_limit () con una de las categorías de límites definidas para esa interfaz. Los límites de tiempo de ejecución están diseñados para aplicaciones que tienen múltiples bases de datos, algunas de las cuales son solo para uso interno y otras que pueden ser influenciadas o controladas por agentes externos potencialmente hostiles. Por ejemplo, una aplicación de navegador web puede usar una base de datos interna para rastrear las vistas históricas de la página, pero tiene una o más bases de datos separadas que son creadas y controladas por aplicaciones javascript que se descargan de Internet. La interfaz sqlite3_limit () permite que las bases de datos internas administradas por código de confianza no estén restringidas y, al mismo tiempo, impone estrictas limitaciones a las bases de datos creadas o controladas por código externo que no es de confianza para ayudar a prevenir un ataque de denegación de servicio.

  1. Longitud máxima de una cadena o BLOB

    El número máximo de bytes en una cadena o BLOB en SQLite está definido por la macro del preprocesador SQLITE_MAX_LENGTH. El valor predeterminado de esta macro es mil millones (mil millones o 1,000,000,000). Puede aumentar o disminuir este valor en tiempo de compilación usando una opción de línea de comandos como esta:

    -DSQLITE_MAX_LENGTH = 123456789

    La implementación actual solo admitirá una longitud de cadena o BLOB de hasta 231-1 o 2147483647. Y algunas funciones integradas como hex () pueden fallar mucho antes de ese punto. En aplicaciones sensibles a la seguridad, es mejor no intentar aumentar la longitud máxima de cadena y blob. De hecho, podría hacer bien en reducir la longitud máxima de cadena y blob a algo más en el rango de unos pocos millones si eso es posible.

    Durante parte del procesamiento INSERT y SELECT de SQLite, el contenido completo de cada fila en la base de datos se codifica como un solo BLOB. Entonces, el parámetro SQLITE_MAX_LENGTH también determina el número máximo de bytes en una fila.

    La longitud máxima de cadena o BLOB se puede reducir en tiempo de ejecución utilizando la interfaz sqlite3_limit (db, SQLITE_LIMIT_LENGTH, size).

  2. Número máximo de columnas

    El parámetro de tiempo de compilación SQLITE_MAX_COLUMN se usa para establecer un límite superior en:

    • El número de columnas en una tabla.
    • El número de columnas en un índice
    • El número de columnas en una vista.
    • El número de términos en la cláusula SET de una instrucción UPDATE
    • El número de columnas en el conjunto de resultados de una instrucción SELECT.
    • El número de términos en una cláusula GROUP BY o ORDER BY
    • El número de valores en una instrucción INSERT

    La configuración predeterminada para SQLITE_MAX_COLUMN es 2000. Puede cambiarla en tiempo de compilación a valores tan grandes como 32767. Por otro lado, muchos diseñadores de bases de datos experimentados argumentarán que una base de datos bien normalizada nunca necesitará más de 100 columnas en una tabla.

    En la mayoría de las aplicaciones, el número de columnas es pequeño: unas pocas docenas. Hay lugares en el generador de código SQLite que usan algoritmos que son O (N²) donde N es el número de columnas. Entonces, si redefine SQLITE_MAX_COLUMN para que sea un número realmente grande y genera SQL que usa una gran cantidad de columnas, es posible que sqlite3_prepare_v2 () se ejecute lentamente.

    El número máximo de columnas se puede reducir en tiempo de ejecución utilizando la interfaz sqlite3_limit (db, SQLITE_LIMIT_COLUMN, size).

  3. Longitud máxima de una instrucción SQL

    El número máximo de bytes en el texto de una declaración SQL está limitado a SQLITE_MAX_SQL_LENGTH que por defecto es 1,000,000,000.

    Si una declaración SQL está limitada a un millón de bytes de longitud, entonces, obviamente, no podrá insertar cadenas de varios millones de bytes incrustándolas como literales dentro de las declaraciones INSERT. Pero no deberías hacer eso de todos modos. Utilice parámetros de host para sus datos. Prepare declaraciones SQL cortas como esta:

    INSERT INTO tab1 VALUES (?,?,?);

    Luego use las funciones sqlite3_bind_XXXX () para vincular sus valores de cadena grandes a la declaración SQL. El uso de la vinculación evita la necesidad de escapar de los caracteres de comillas en la cadena, lo que reduce el riesgo de ataques de inyección SQL. También se ejecuta más rápido ya que la cadena grande no necesita ser analizada o copiada tanto.

    La longitud máxima de una declaración SQL se puede reducir en tiempo de ejecución utilizando la interfaz sqlite3_limit (db, SQLITE_LIMIT_SQL_LENGTH, size).

  4. Número máximo de tablas en una combinación

    SQLite no admite combinaciones que contengan más de 64 tablas. Este límite surge del hecho de que el generador de código SQLite usa mapas de bits con un bit por tabla de unión en el optimizador de consultas.

    SQLite utiliza un algoritmo de planificación de consultas eficiente, por lo que incluso una combinación grande se puede preparar rápidamente. Por lo tanto, no existe ningún mecanismo para aumentar o disminuir el límite del número de tablas en una combinación.

  5. Profundidad máxima de un árbol de expresión

    SQLite analiza las expresiones en un árbol para su procesamiento. Durante la generación de código, SQLite recorre este árbol de forma recursiva. Por lo tanto, la profundidad de los árboles de expresión es limitada para evitar usar demasiado espacio en la pila.

    El parámetro SQLITE_MAX_EXPR_DEPTH determina la profundidad máxima del árbol de expresión. Si el valor es 0, no se aplica ningún límite. La implementación actual tiene un valor predeterminado de 1000.

    La profundidad máxima de un árbol de expresión se puede reducir en tiempo de ejecución utilizando la interfaz sqlite3_limit (db, SQLITE_LIMIT_EXPR_DEPTH, size) si SQLITE_MAX_EXPR_DEPTH es inicialmente positivo. En otras palabras, la profundidad máxima de expresión se puede reducir en tiempo de ejecución si ya existe un límite de tiempo de compilación en la profundidad de expresión. Si SQLITE_MAX_EXPR_DEPTH se establece en 0 en el momento de la compilación (si la profundidad de las expresiones es ilimitada), entonces sqlite3_limit (db, SQLITE_LIMIT_EXPR_DEPTH, size) no es una operación.

  6. Número máximo de argumentos sobre una función

    El parámetro SQLITE_MAX_FUNCTION_ARG determina el número máximo de parámetros que se pueden pasar a una función SQL. El valor predeterminado de este límite es 100. SQLite debería funcionar con funciones que tengan miles de parámetros. Sin embargo, sospechamos que cualquiera que intente invocar una función con más de unos pocos parámetros realmente está tratando de encontrar vulnerabilidades de seguridad en sistemas que usan SQLite, no realizan un trabajo útil, por lo que hemos establecido este parámetro relativamente bajo.

    El número de argumentos de una función a veces se almacena en un carácter con signo. Entonces, hay un límite superior estricto en SQLITE_MAX_FUNCTION_ARG de 127.

    El número máximo de argumentos en una función se puede reducir en tiempo de ejecución utilizando la interfaz sqlite3_limit (db, SQLITE_LIMIT_FUNCTION_ARG, size).

  7. Número máximo de términos en una declaración SELECT compuesta

    Una sentencia SELECT compuesta son dos o más sentencias SELECT conectadas por operadores UNION, UNION ALL, EXCEPT o INTERSECT. Llamamos a cada declaración SELECT individual dentro de un SELECT compuesto un “término”.

    El generador de código en SQLite procesa declaraciones SELECT compuestas usando un algoritmo recursivo. Para limitar el tamaño de la pila, por lo tanto, limitamos el número de términos en un SELECT compuesto. El número máximo de términos es SQLITE_MAX_COMPOUND_SELECT que por defecto es 500. Creemos que esta es una asignación generosa ya que en la práctica casi nunca vemos que el número de términos en una selección compuesta exceda un solo dígito.

    El número máximo de términos SELECT compuestos se puede reducir en tiempo de ejecución utilizando la interfaz sqlite3_limit (db, SQLITE_LIMIT_COMPOUND_SELECT, size).

  8. Longitud máxima de un patrón LIKE o GLOB

    El algoritmo de coincidencia de patrones utilizado en la implementación predeterminada LIKE y GLOB de SQLite puede exhibir un rendimiento O (N²) (donde N es el número de caracteres en el patrón) para ciertos casos patológicos. Para evitar ataques de denegación de servicio por parte de malhechores que pueden especificar sus propios patrones LIKE o GLOB, la longitud del patrón LIKE o GLOB se limita a SQLITE_MAX_LIKE_PATTERN_LENGTH bytes. El valor predeterminado de este límite es 50000. Una estación de trabajo moderna puede evaluar incluso un patrón patológico LIKE o GLOB de 50000 bytes con relativa rapidez. El problema de la denegación de servicio solo entra en juego cuando la longitud del patrón llega a millones de bytes. Sin embargo, dado que los patrones LIKE o GLOB más útiles tienen como máximo unas pocas docenas de bytes de longitud, los desarrolladores de aplicaciones paranoicos pueden querer reducir este parámetro a algo en el rango de unos pocos cientos si saben que los usuarios externos pueden generar patrones arbitrarios.

    La longitud máxima de un patrón LIKE o GLOB se puede reducir en tiempo de ejecución utilizando la interfaz sqlite3_limit (db, SQLITE_LIMIT_LIKE_PATTERN_LENGTH, size).

  9. Número máximo de parámetros de host en una sola declaración SQL

    Un parámetro de host es un marcador de posición en una declaración SQL que se completa utilizando una de las interfaces sqlite3_bind_XXXX (). Muchos programadores de SQL están familiarizados con el uso de un signo de interrogación (“?”) Como parámetro de host. SQLite también admite parámetros de host con nombre precedidos por “:”, “$” o “@” y parámetros de host numerados de la forma “? 123”.

    A cada parámetro de host en una declaración SQLite se le asigna un número. Los números normalmente comienzan con 1 y aumentan en uno con cada nuevo parámetro. Sin embargo, cuando se utiliza el formulario “? 123”, el número de parámetro de host es el número que sigue al signo de interrogación.

    SQLite asigna espacio para contener todos los parámetros de host entre 1 y el número de parámetro de host más grande utilizado. Por lo tanto, una declaración SQL que contenga un parámetro de host como? 1000000000 requeriría gigabytes de almacenamiento. Esto podría abrumar fácilmente los recursos de la máquina host. Para evitar asignaciones de memoria excesivas, el valor máximo de un número de parámetro de host es SQLITE_MAX_VARIABLE_NUMBER, cuyo valor predeterminado es 999 para versiones de SQLite anteriores a 3.32.0 (2020-05-22) o 32766 para versiones de SQLite posteriores a 3.32.0.

    El número máximo de parámetros de host se puede reducir en tiempo de ejecución utilizando la interfaz sqlite3_limit (db, SQLITE_LIMIT_VARIABLE_NUMBER, size).

  10. Profundidad máxima de recursividad del disparador

    SQLite limita la profundidad de la recursividad de los disparadores para evitar que una declaración que involucre disparadores recursivos utilice una cantidad ilimitada de memoria.

    Antes de SQLite versión 3.6.18 (2009-09-11), los desencadenantes no eran recursivos, por lo que este límite no tenía sentido. A partir de la versión 3.6.18, se admitían activadores recursivos, pero tenían que habilitarse explícitamente mediante la declaración PRAGMA recursive_triggers. Empezando con versión 3.7.0 (2009-09-11), los desencadenadores recursivos están habilitados de forma predeterminada, pero se pueden deshabilitar manualmente mediante PRAGMA recursive_triggers. SQLITE_MAX_TRIGGER_DEPTH solo es significativo si los activadores recursivos están habilitados.

    La profundidad de recursividad de disparo máxima predeterminada es 1000.

  11. Número máximo de bases de datos adjuntas

    La declaración ATTACH es una extensión SQLite que permite asociar dos o más bases de datos a la misma conexión de base de datos y operar como si fueran una sola base de datos. El número de bases de datos adjuntas simultáneamente está limitado a SQLITE_MAX_ATTACHED, que se establece en 10 de forma predeterminada. El número máximo de bases de datos adjuntas no se puede aumentar por encima de 125.

    El número máximo de bases de datos adjuntas se puede reducir en tiempo de ejecución utilizando la interfaz sqlite3_limit (db, SQLITE_LIMIT_ATTACHED, size).

  12. Número máximo de páginas en un archivo de base de datos

    SQLite puede limitar el tamaño de un archivo de base de datos para evitar que el archivo de base de datos crezca demasiado y consuma demasiado espacio en disco. El parámetro SQLITE_MAX_PAGE_COUNT, que normalmente se establece en 1073741823, es el número máximo de páginas permitidas en un solo archivo de base de datos. Un intento de insertar nuevos datos que harían que el archivo de la base de datos crezca más que esto devolverá SQLITE_FULL.

    La configuración más grande posible para SQLITE_MAX_PAGE_COUNT es 4294967294. Cuando se usa con el tamaño máximo de página de 65536, esto da un tamaño máximo de base de datos SQLite de aproximadamente 281 terabytes.

    El max_page_count PRAGMA se puede usar para aumentar o disminuir este límite en tiempo de ejecución.

  13. Número máximo de filas en una tabla

    El número máximo teórico de filas en una tabla es 264 (18446744073709551616 o aproximadamente 1.8e + 19). Este límite es inalcanzable ya que primero se alcanzará el tamaño máximo de la base de datos de 281 terabytes. Una base de datos de 281 terabytes no puede contener más de aproximadamente 2e + 13 filas, y solo si no hay índices y si cada fila contiene muy pocos datos.

  14. Tamaño máximo de la base de datos

    Cada base de datos consta de una o más “páginas”. Dentro de una sola base de datos, cada página tiene el mismo tamaño, pero diferentes bases de datos pueden tener tamaños de página que son potencias de dos entre 512 y 65536, inclusive. El tamaño máximo de un archivo de base de datos es 4294967294 páginas. En el tamaño de página máximo de 65536 bytes, esto se traduce en un tamaño de base de datos máximo de aproximadamente 1.4e + 14 bytes (281 terabytes, o 256 tebibytes, o 281474 gigabytes o 256,000 gibibytes).

    Este límite superior en particular no está probado ya que los desarrolladores no tienen acceso a hardware capaz de alcanzar este límite. Sin embargo, las pruebas verifican que SQLite se comporta de manera correcta y sensata cuando una base de datos alcanza el tamaño máximo de archivo del sistema de archivos subyacente (que generalmente es mucho menor que el tamaño máximo teórico de la base de datos) y cuando una base de datos no puede crecer debido al agotamiento del espacio en disco.

  15. Número máximo de tablas en un esquema

    Cada tabla e índice requiere al menos una página en el archivo de base de datos. Un “índice” en la oración anterior significa un índice creado explícitamente usando una instrucción CREATE INDEX o índices implícitos creados por restricciones UNIQUE y PRIMARY KEY. Dado que el número máximo de páginas en un archivo de base de datos es 2147483646 (un poco más de 2 mil millones), esto también es un límite superior en el número de tablas e índices en un esquema.

    Siempre que se abre una base de datos, se escanea y analiza todo el esquema y se guarda en la memoria un árbol de análisis para el esquema. Eso significa que el tiempo de inicio de la conexión a la base de datos y el uso de memoria inicial es proporcional al tamaño del esquema.