Estoy trabajando con una base de datos SQL en este momento, y esto siempre me ha dado curiosidad, pero las búsquedas de Google no aparecen mucho: ¿por qué los tipos de datos estrictos?
Entiendo por qué tendría algunos tipos de datos diferentes, por ejemplo, cómo es importante diferenciar entre datos binarios y de texto sin formato . En lugar de almacenar los 1 y 0 de los datos binarios como texto sin formato, ahora entiendo que es más eficiente almacenar los datos binarios en su propio formato.
Pero lo que no entiendo es cuál es el beneficio de tener tantos tipos de datos diferentes:
- ¿Por qué
mediumtext
,longtext
ytext
? - ¿Por qué
decimal
,float
yint
? - etc.
¿Cuál es el beneficio de decirle a la base de datos "Solo 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é conocer el tamaño de la entrada de antemano ayuda al rendimiento? ¿O más bien es algo completamente diferente?
fuente
decimal
,float
yint
tipos, ¿qué esperaría1 / 3
hacer? ¿Qué hay de1.0 / 3.0
? ¿Podría estar seguro de que cuando dividecolumnA
porcolumnB
eso obtendrá los resultados que espera?Respuestas:
SQL es un lenguaje de tipo estático . Esto significa que debe saber de qué tipo es una variable (o campo, en este caso) antes de poder usarla. Esto es lo opuesto a los lenguajes de tipo dinámico, donde ese no es necesariamente el caso.
En esencia, SQL está diseñado para definir datos ( DDL ) y datos de acceso ( DML ) en un motor de base de datos relacional . La escritura estática presenta varios beneficios sobre la escritura dinámica para este tipo de sistema.
Los índices , utilizados para acceder rápidamente a registros específicos, funcionan realmente bien cuando el tamaño es fijo. Considere una consulta que utiliza un índice, posiblemente con múltiples campos: si los tipos y tamaños de datos se conocen con anticipación, puedo comparar muy rápidamente mi predicado (cláusula WHERE o criterios JOIN) con los valores en el índice y encontrar los registros deseados más rápido .
Considere dos valores enteros . En un sistema de tipo dinámico, pueden ser de tamaño variable (piense en Java
BigInteger
o en los enteros de precisión arbitraria incorporados de Python). Si quiero comparar los enteros, primero necesito saber su longitud de bits. Este es un aspecto de la comparación de enteros que está oculto en gran medida por los lenguajes modernos, pero es muy real a nivel de CPU. Si los tamaños son fijos y se conocen con anticipación, se elimina un paso completo del proceso. Una vez más, 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 la microcomputación, la memoria era muy importante. La limitación de datos ayudó a mantener los requisitos de almacenamiento bajo control. Si un número entero nunca supera un byte, ¿por qué asignarle más almacenamiento? Ese es el espacio perdido en la era de la memoria limitada. Incluso en los tiempos modernos, esos bytes adicionales desperdiciados pueden sumar y matar el rendimiento del caché de una CPU. Recuerde, estos son motores de base de datos que pueden prestar servicio a cientos de transacciones por segundo, no solo su pequeño entorno de desarrollo.
En la línea de almacenamiento limitado, es útil poder ajustar un solo registro en una sola página en la memoria. Una vez que pasa una página, hay más errores de página y más acceso lento a la memoria. Los motores más nuevos tienen optimizaciones para que esto sea un problema menor, pero todavía está ahí. Al dimensionar los datos de manera adecuada, puede mitigar este riesgo.
Más aún, en los tiempos modernos, SQL se utiliza para conectarse a otros idiomas a través de ORM u ODBC o alguna otra capa. Algunos de estos lenguajes tienen reglas para requerir tipos fuertes y estáticos. Es mejor cumplir con los requisitos más estrictos, ya que los lenguajes de tipo dinámico pueden manejar 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 un motor de base de datos relacional. Por otra parte, está diseñado para uso de un solo subproceso en un solo sistema, por lo que las preocupaciones de rendimiento pueden no ser tan pronunciadas como, por ejemplo, en una base de datos Oracle empresarial que atiende millones de solicitudes por minuto.
fuente
Indexes
, se dice más básicamente: tener un tipo de datos permite que el motor de la base de datos tenga sentido de los datos , hacer comparaciones (números más grandes / más pequeños, fechas anteriores / posteriores, antes / después en el alfabeto), y, por lo tanto, permite ordenar y consultar .Primero: el texto plano es binario (ni siquiera son los caracteres UTF8 o ASCII "0" y "1", sino bits de activación / desactivación reales)
Dicho esto, algunas de las razones son:
fuente
Es para que el código subyacente en el que está escrita 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, puede asignar un bloque de 256 bytes para almacenarlo.
Esto hace que las cosas sean mucho más rápidas, por ejemplo, no tiene que asignar almacenamiento adicional a medida que el usuario escribe, ya que un campo dado siempre inicia x bytes en el registro, una búsqueda o selección en ese campo sabe que siempre debe verificar x bytes en cada registro, etc.
fuente
Cuando las columnas de una base de datos reciben tipos definidos, los tipos generalmente se definen a sí mismos para tener un cierto tamaño en bits. Como resultado:
1) cuando el motor de la base de datos atraviesa las filas de 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, digamos, 32 bytes, y así obtener el El siguiente registro es suficiente para 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 una de procesamiento de datos potencialmente costosa.
fuente
Preguntó por qué los DBMS tienen tipos de datos estáticos.
Velocidad de búsqueda. El objetivo de un DBMS es almacenar muchos más datos de los que podría cargar en un programa. Piense "todos los recibos de tarjetas de crédito generados en el mundo en los últimos diez años". Para buscar dichos 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 anticipación a qué se enfrenta, es más fácil cargar en índices eficientes.
Integridad y limitaciones. Es más fácil mantener los datos limpios si tiene tipos de datos fijos.
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 en esas circunstancias.
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 bloqueo de RDBMS que resulta en una 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 o 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 silencioso, más rápido, más eficiente en el consumo de energía) en un ancho de vía más estrecho. Pero, ¿cómo va a 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.
fuente
En general, cuanto más detalle le diga a la base de datos sobre lo que está almacenando, más puede intentar optimizar varias métricas de rendimiento relacionadas con esos datos, como cuánto espacio asignar en el disco o cuánta memoria asignar al recuperarlo. .
No estoy seguro de qué base de datos está utilizando, así 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 que tienen 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) frente a texto pequeño de longitud fija (esto puede variar según la base de datos, consulte su manual para ver el suyo).
Los diferentes niveles de precisión requieren diferentes cantidades de almacenamiento, y no todo uso requiere los más altos grados de precisión. Por ejemplo, vea aquí: https://docs.oracle.com/cd/B28359_01/server.111/b28286/sql_elements001.htm#SQLRF50950
Oracle tiene una gran cantidad de diferentes tipos numéricos 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.
fuente
Hasta cierto punto, es histórico.
Érase una vez, los datos tabulares se almacenaban en archivos compuestos de registros de longitud fija, a su vez compuestos de campos predefinidos, de modo que un campo determinado siempre era del mismo tipo y en el mismo lugar en todos y cada uno de los registros. Esto hizo que el procesamiento sea 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 evolucionaron las bases de datos relacionales, comenzaron a introducir más tipos de datos y opciones de almacenamiento, incluidos campos binarios o de texto de longitud variable. Pero, esto introdujo registros de longitud variable y rompió la capacidad de ubicar registros consistentemente a través de cálculos o campos a través de un desplazamiento fijo. No importa, las máquinas son mucho más potentes hoy que en aquel entonces.
A veces es útil establecer un tamaño específico para un campo para ayudar a aplicar un poco de lógica comercial, digamos 10 dígitos para un número de teléfono de América del Norte. La mayor parte del tiempo es solo un poco de legado informático.
fuente
Si una base de datos utiliza registros de tamaño fijo, cualquier registro en la base de datos continuará encajando, en la misma ubicación, incluso si se cambia su contenido. Por el contrario, si una base de datos intenta almacenar registros utilizando exactamente la cantidad de almacenamiento necesaria para sus campos, cambiar el nombre de Emma Smith a Emma Johnson puede hacer que su registro sea demasiado grande para caber en su ubicación actual. Si el registro se mueve a un lugar con suficiente espacio, cualquier índice que lleve un registro de dónde está necesitaría actualizarse para reflejar la nueva ubicación.
Hay una variedad de 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á lo único 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 de registros requeriría un paso adicional para recuperar los datos asociados con un número de registro dado). El uso de registros de tamaño fijo puede parecer ineficiente, pero hace las cosas mucho más simples.
fuente
Por mucho de lo que haces como desarrollador web, no hay necesidad de entender lo que está sucediendo "bajo el capó". Hay momentos, sin embargo, cuando ayuda.
Como sospecha, la razón es hacer con eficiencia. Las abstracciones gotean . Una consulta como
SELECT author FROM books
puede ejecutarse bastante rápido cuando se conoce el tamaño de todos los campos de la tabla.Como dice Joel:
La mayoría de las veces, estás trabajando lo suficientemente lejos de las bases fundamentales como para no tener que preocuparte por eso. Como desarrollador web basado en PHP, ¿le importa cuántas instrucciones de CPU usa su código? La mayoría de las veces, no, en realidad no. Pero a veces es útil saberlo por dos razones: puede explicar las decisiones tomadas por sus bibliotecas; y a veces debes preocuparte por la velocidad en tu propio código.
fuente