¿Qué obtienen las bases de datos relacionales al establecer un tipo de datos predefinido para cada columna?

44

Estoy trabajando con una base de datos SQL en este momento, y esto siempre me ha hecho sentir curiosidad, pero las búsquedas en Google no muestran mucho: ¿Por qué los tipos de datos estrictos?

Entiendo por qué tendría unos tipos de datos diferentes, por ejemplo cómo la diferenciación entre datos binarios y de texto sin formato es importante . En lugar de almacenar el 1 y el 0 de los datos binarios como texto simple, ahora entiendo que es más eficiente almacenar los datos binarios en su propio formato.

Pero lo que no entiendo es el beneficio de tener tantos tipos de datos diferentes:

  • ¿Por qué mediumtext , longtext y text ?
  • ¿Por qué decimal , float y int ?
  • etc.

¿Cuál es el beneficio de decirle a la base de datos "Sólo habrá 256 bytes de datos de texto sin formato en las entradas de esta columna". o "Esta columna puede tener entradas de texto de hasta 16,777,215 bytes"?

¿Es un beneficio de rendimiento? Si es así, ¿por qué saber el tamaño de la entrada antes de la mano ayuda al rendimiento? O mejor dicho, ¿es algo completamente distinto?

    
pregunta john doe 26.05.2017 - 20:13

9 respuestas

50

SQL es un lenguaje estático . Esto significa que debe saber qué tipo de variable es una variable (o campo, en este caso) antes de poder usarla. Esto es lo contrario de los lenguajes de tipo dinámico, donde no es necesariamente el caso.

En su núcleo, SQL está diseñado para definir datos ( DDL ) y datos de acceso ( DML ) en un motor de base de datos relacional . La tipificación estática presenta varios beneficios sobre la tipificación dinámica en este tipo de sistema.

  • Índices , utilizados para acceder rápidamente a registros específicos, funcionan realmente bien cuando el tamaño es fijo. Considere una consulta que utilice un índice, posiblemente con múltiples campos: si los tipos y tamaños de datos se conocen de antemano, puedo comparar rápidamente mi predicado (cláusula WHERE o criterios ÚNETE) con los valores en el índice y encontrar los registros deseados más rápido .

  • Considere dos valores de entero . En un sistema de tipo dinámico, pueden ser de tamaño variable (piense en Java BigInteger , o en enteros de precisión arbitraria incorporados de Python). Si quiero comparar los enteros, primero necesito saber la longitud de sus bits. Este es un aspecto de la comparación de enteros que está en gran parte oculto por los lenguajes modernos, pero es muy real en el nivel de CPU. Si los tamaños son fijos y conocidos de antemano, se elimina un paso completo del proceso. Nuevamente, se supone que las bases de datos pueden procesar millones de transacciones lo más rápido posible. La velocidad es el rey.

  • SQL fue diseñado en la década de 1970. En los primeros días de microcomputación, la memoria era una prima. La limitación de datos ayudó a mantener los requisitos de almacenamiento bajo control. Si un entero nunca crece más allá de un byte, ¿por qué asignarle más almacenamiento? Eso es un desperdicio de espacio en la era de la memoria limitada. Incluso en los tiempos modernos, esos bytes extra desperdiciados pueden sumarse y matar el rendimiento de la memoria caché de una CPU. Recuerde, estos son motores de base de datos que pueden atender cientos de transacciones por segundo, no solo su pequeño entorno de desarrollo.

  • A lo largo de las líneas de almacenamiento limitado, es útil poder ajustar un solo registro en una sola página en la memoria. Una vez que pasa por una página, hay más faltas de página y más acceso lento a la memoria. Los motores más nuevos tienen optimizaciones para hacer que esto sea un problema menor, pero aún está ahí. Al dimensionar adecuadamente los datos, puede mitigar este riesgo.

  • En tiempos modernos, SQL se usa para conectarse a otros lenguajes a través de ORM o < a href="https://en.wikipedia.org/wiki/Open_Database_Connectivity"> ODBC o alguna otra capa. Algunos de estos lenguajes tienen reglas sobre la exigencia de tipos fuertes y estáticos. Es mejor cumplir con los requisitos más estrictos, ya que los lenguajes de tipo dinámico pueden manejar los tipos estáticos más fácilmente que al revés.

  • SQL admite la escritura estática porque los motores de base de datos lo necesitan para el rendimiento, como se muestra arriba.

Es interesante notar que hay implementaciones de SQL que no están fuertemente tipadas. SQLite es probablemente el ejemplo más popular de este motor de base de datos relacional. Nuevamente, está diseñado para uso de un solo hilo en un solo sistema, por lo que los problemas de rendimiento pueden no ser tan pronunciados como en los ej. una base de datos Oracle empresarial que atiende a millones de solicitudes por minuto.

    
respondido por el user22815 26.05.2017 - 20:48
24

Primero: el texto sin formato es binario (ni siquiera son los caracteres UTF8 o ASCII "0" y "1", sino los bits de activación / desactivación reales)

Dicho esto, algunas de las razones son:

  • Restricciones de negocios / diseño: permitir el número 7626355112 en la columna ALTURA de la tabla PERSONA sería incorrecto. Permitir "Howya" en la columna FECHA de una FACTURA sería incorrecto.
  • Código menos propenso a errores: no tiene que escribir código para asegurarse de que los datos recuperados de una columna de fecha sean realmente una fecha. Si los tipos de columna fueran dinámicos, tendría que realizar muchas verificaciones de tipo al leerlos.
  • Eficacia informática: si una columna es de tipo INTEGER y la SUMA (), el RDBMS no tiene que aplicar aritmética de punto flotante.
  • Eficiencia de almacenamiento: que indica que una columna es VARCHAR (10) le permite a RDBMS asignar el espacio con mayor precisión.
  • Integridad y unicidad referenciales: PK (o FK) de una tabla no debería permitir flotantes, ya que la igualdad de punto flotante es difícil, por lo que debe declararlos en un tipo no flotante, como caracteres o entero.
  • Existen RDBMS con tipos de columna dinámicos (no estrictos) (SQLite) . Utiliza el concepto de "afinidad de tipo" al mismo tiempo que le permite insertar prácticamente cualquier cosa en cualquier columna sin quejarse. Hay compensaciones que no serán discutidas aquí. Consulte esta pregunta .
respondido por el Tulains Córdova 26.05.2017 - 20:41
8

Es para que el código subyacente en el que se escribe la base de datos pueda asignar y usar registros de tamaño fijo, si sabe que un campo específico puede contener de 0 a 256 caracteres de texto, entonces puede asignar un bloque de 256 bytes para almacenar en.

Esto hace que las cosas sean mucho más rápidas, por ejemplo. no tiene que asignar almacenamiento adicional a medida que los tipos de usuarios, ya que un campo dado siempre inicia x bytes en el registro que una búsqueda o selección en ese campo sabe que siempre debe marcar x bytes en cada registro, etc.

    
respondido por el Steve Barnes 26.05.2017 - 20:42
6

Cuando las columnas de una base de datos reciben tipos definidos, los tipos generalmente se definen ellos mismos para tener un cierto tamaño en bits. Como resultado:

1) cuando el motor de la base de datos recorre las filas en una tabla, no tiene que realizar ningún análisis sofisticado para determinar dónde termina cada registro, solo puede saber que cada fila consta de, por ejemplo, 32 bytes, y así para obtener el siguiente registro es suficiente agregar 32 bytes a la ubicación de los registros actuales.

2) al buscar un campo dentro de una fila, es posible conocer un desplazamiento exacto para ese campo nuevamente sin analizar nada, por lo que las búsquedas de columnas son una operación aritmética simple en lugar de un procesamiento de datos potencialmente costoso.

    
respondido por el UserNotFound 26.05.2017 - 20:40
3

Usted preguntó por qué los DBMS tienen tipos de datos estáticos.

  1. Velocidad de búsqueda. El objetivo principal de un DBMS es almacenar muchos más datos de los que podría cargar en un programa. Piense "todos los resbalones de tarjetas de crédito generados en el mundo en los últimos diez años". Para buscar estos datos de manera eficiente, los tipos de datos de longitud fija son útiles. Esto es especialmente cierto para datos estructurados como sellos de fecha y números de cuenta. Si sabe con qué está lidiando con anticipación, es más fácil cargar en índices eficientes.

  2. Integridad y restricciones. Es más fácil mantener los datos limpios si tiene tipos de datos fijos.

  3. Historia. Los RDBMS comenzaron cuando las computadoras tenían solo unos pocos megabytes de RAM, y el almacenamiento a escala de terabytes era enormemente costoso. Guardar una docena de bytes en cada fila de una tabla podría ahorrar miles de dólares y horas de tiempo en esas circunstancias.

  4. La maldición de la base de clientes. Los RDBMS de hoy son paquetes de software muy complejos y altamente optimizados, y han estado en uso durante décadas acumulando datos. Son maduros Trabajan. Un fallo de RDBMS que resulta en la pérdida de datos a gran escala es muy raro en estos días. Cambiar a algo con un sistema de escritura de datos más flexible no vale el costo ni el riesgo para la mayoría de las organizaciones.

Analogía: puede ser obvio que los sistemas de metro urbano funcionarían mejor (más silenciosos, más rápidos, más eficientes en cuanto a energía) en un ancho de vía más estrecho. Pero, ¿cómo cambiará todos los rieles en el sistema de metro de la ciudad de Nueva York para realizar esas mejoras? No lo eres, así que optimizas lo que tienes.

    
respondido por el O. Jones 28.05.2017 - 13:11
3

En general, cuanto más detalles le diga a la base de datos acerca de lo que está almacenando, más puede intentar optimizar varias métricas de rendimiento relacionadas con esos datos, como la cantidad de espacio para asignar disco o la cantidad de memoria para asignar al recuperarlo.

  

¿Por qué texto intermedio, texto largo y texto?

No estoy seguro de qué base de datos está usando , por lo que tendré que adivinar: supongo que dos de estos tipos de datos tienen límites superiores, uno de ellos no. El uso de tipos de datos para texto con límites superiores le indica a la base de datos cuánto espacio de almacenamiento necesitará para cada registro. También es posible que algunas bases de datos tengan diferentes formas de almacenar texto grande (posiblemente ilimitado) en comparación con texto pequeño de longitud fija (esto puede variar según la base de datos; consulte el manual para ver el suyo).

  

¿Por qué decimal, float e int?

Los diferentes niveles de precisión requieren diferentes cantidades de almacenamiento, y no todos los usos requieren los más altos grados de precisión. Por ejemplo, vea aquí: enlace

Oracle tiene una gran cantidad de tipos numéricos diferentes con diferentes requisitos de almacenamiento y diferentes capacidades en términos de nivel de precisión y tamaño de número que se puede representar.

    
respondido por el FrustratedWithFormsDesigner 26.05.2017 - 20:42
2

Hasta cierto punto, es histórico.

Érase una vez, los datos tabulares se almacenaban en archivos compuestos por registros de longitud fija, a su vez compuestos por campos predefinidos, de modo que un campo determinado era siempre del mismo tipo y en el mismo lugar en todos y cada uno de los registros. Esto hizo que el procesamiento fuera eficiente y limitó la complejidad de la codificación.

Agregue algunos índices a dicho archivo y tendrá el comienzo de una base de datos relacional.

A medida que las bases de datos relacionales evolucionaron, comenzaron a introducir más tipos de datos y opciones de almacenamiento, incluyendo texto de longitud variable o campos binarios. Sin embargo, esto introdujo registros de longitud variable y rompió la capacidad de ubicar registros de forma consistente mediante cálculos o campos mediante un desplazamiento fijo. No importa, las máquinas son mucho más poderosas hoy en día de lo que eran antes.

A veces es útil establecer un tamaño específico para un campo para ayudar a aplicar un poco de lógica de negocios, por ejemplo, 10 dígitos para un número de teléfono de América del Norte. La mayor parte del tiempo es solo un poco del legado informático.

    
respondido por el Zenilogix 28.05.2017 - 03:43
1

Si una base de datos utiliza registros de tamaño fijo, cualquier registro de la base de datos continuará ajustándose, en la misma ubicación, incluso si se modifica su contenido. Por el contrario, si una base de datos intenta almacenar registros utilizando exactamente la cantidad de almacenamiento necesario para sus campos, cambiar el nombre de Emma Smith a Emma Johnson puede hacer que su registro sea demasiado grande para que quepa en su ubicación actual. Si el registro se mueve a un lugar con suficiente espacio, cualquier índice que realice un seguimiento de dónde se encuentra debería actualizarse para reflejar la nueva ubicación.

Hay varias formas de reducir el costo asociado con dichas actualizaciones. Por ejemplo, si el sistema mantiene una lista de números de registros y ubicaciones de datos, esa lista será la única cosa que debería actualizarse si se mueve un registro. Desafortunadamente, tales enfoques aún tienen un costo significativo (por ejemplo, mantener un mapeo entre los números de registro y las ubicaciones requeriría que la recuperación del registro requeriría un paso adicional para recuperar los datos asociados con un número de registro determinado). El uso de registros de tamaño fijo puede parecer ineficiente, pero simplifica mucho las cosas.

    
respondido por el supercat 26.05.2017 - 23:49
1

Para mucho de lo que haces como desarrollador web, no hay necesidad de entender lo que está sucediendo "bajo el capó". Sin embargo, hay ocasiones en que ayuda.

  

¿Cuál es el beneficio de decirle a la base de datos "Sólo habrá 256 bytes de datos de texto sin formato en las entradas de esta columna". o "¿Esta columna puede tener entradas de texto de hasta 16,777,215 bytes"?

Como usted sospecha, la razón tiene que ver con la eficiencia. El escape de abstracciones . Una consulta como SELECT author FROM books puede ejecutarse con bastante rapidez cuando el tamaño de todos los campos en La tabla es conocida.

Como dice Joel,

  

¿Cómo implementa una base de datos relacional SELECT author FROM books ? En una base de datos relacional, cada fila en una tabla (por ejemplo, la tabla de libros) tiene exactamente la misma longitud en bytes, y cada campo está siempre en un desplazamiento fijo desde el principio de la fila. Entonces, por ejemplo, si cada registro en la tabla de libros tiene una longitud de 100 bytes, y el campo del autor está en el desplazamiento 23, entonces hay autores almacenados en los bytes 23, 123, 223, 323, etc. ¿Cuál es el código para mover a ¿El siguiente registro en el resultado de esta consulta? Básicamente, es esto:

     

pointer += 100;

     

Una instrucción de CPU. Faaaaaaaaaast.

La mayoría de las veces, estás trabajando lo suficientemente lejos de los fundamentos esenciales para que no tengas que preocuparte por eso. Como desarrollador web basado en PHP, ¿le importa la cantidad de instrucciones de CPU que usa su código? La mayoría de las veces, no, en realidad no. Pero a veces es útil saberlo, por dos motivos: puede explicar las decisiones tomadas por sus bibliotecas; y, a veces, debe preocuparse por la velocidad en su propio código.

    
respondido por el TRiG 27.05.2017 - 14:25

Lea otras preguntas en las etiquetas