Claves primarias de personaje vs entero


30

Estoy diseñando una base de datos con múltiples tablas de búsqueda que contienen posibles atributos de las entidades principales. Estoy pensando en usar una clave de 4 o 5 caracteres para identificar estos valores de búsqueda en lugar de un entero de incremento automático para que cuando almacene estos ID de atributo en las tablas principales, vea valores significativos en lugar de solo números aleatorios.

¿Cuáles son las implicaciones de rendimiento del uso de un campo de caracteres como clave principal en lugar de un número entero?

Estoy usando MySQL si eso importa.

[Editar]
Estas tablas de búsqueda tienen nuevos registros agregados con poca frecuencia. Se mantienen manualmente y las claves basadas en caracteres también se crean manualmente. Aquí hay un ejemplo:

      CUISINES
 ID      Description
-----  --------------
CHNSE  Chinese
ITALN  Italian
MXICN  Mexican

Respuestas:


22

Depende de tu motor. La sabiduría común es que las lecturas son baratas, unos pocos bytes aquí y allá no afectarán significativamente el rendimiento de una base de datos de tamaño pequeño a mediano.

Más importante aún, depende de los usos a los que va a poner la clave primaria. Los números de serie enteros tienen la ventaja de ser fáciles de usar e implementar. También, dependiendo de la implementación específica del método de serialización, tienen la ventaja de ser rápidamente derivables, ya que la mayoría de las bases de datos simplemente almacenan el número de serie en una ubicación fija, en lugar de derivarlo Select max(ID)+1 from foosobre la marcha.

La pregunta es: ¿cómo presenta una clave de 5 caracteres un "valor significativo" para usted y para la aplicación? ¿Cómo se crea este valor? ¿Lleva más o menos tiempo encontrar un número de serie incremental? Si bien hay una cantidad trivial de espacio ahorrado en algunos enteros, la gran mayoría de los sistemas ignorará este ahorro de espacio.

No hay implicaciones de rendimiento, salvo que el esquema de caracteres requiere que nunca haya un motor automático, ya que sus "claves" son subestimables. Para su dominio específico, no se moleste con las claves artificiales, y solo use chino, japonés y tailandés como nombres clave. Si bien no puede garantizar la unicidad sobre cualquier aplicación posible, en su ámbito es mucho más razonable usarlas en lugar de abreviaturas horribles y forzadas de 5 caracteres. No hay impactos significativos en el rendimiento hasta que llegue a millones de tuplas.

Alternativamente, si solo realiza un seguimiento por país de origen, y no por cocinas regionales específicas (cantonesa, sichuan, siciliana, umbría, calabresa, yucateca, oaxaqueña, etc.), siempre puede usar los códigos ISO 3166 .

Si tengo 10,000 recetas, ¿no comienza a sumar la diferencia entre una clave de 5 caracteres y una de 20 caracteres?

El espacio es barato . Cuando habla de 10,000,000 de recetas en las que está haciendo operaciones OLAP, entonces, tal vez. Con 10k recetas, estás viendo 150k de espacio.

Pero de nuevo, depende. Si tiene muchos millones de registros, y está haciendo uniones en ellos, entonces tiene sentido desnormalizar la búsqueda de algo tan trivial (en una vista materializada). A todos los efectos prácticos, la eficiencia de unión relativa en una máquina moderna entre una clave de 5 caracteres y una clave de longitud variable es muy similar a ser idéntica. Afortunadamente, vivimos en un mundo de CPU abundante y disco abundante. Los desagradables son demasiadas combinaciones e ineficacia de consulta, en lugar de una comparación carácter por carácter. Dicho esto, siempre prueba .

Las cosas de P&T de este nivel dependen tanto de la base de datos que las generalizaciones son extremadamente difíciles. Cree dos modelos de muestra de la base de datos, complételos con el número estimado de registros y luego vea cuál es más rápido. En mi experiencia, la longitud de los caracteres no hace una gran diferencia en comparación con buenos índices, buenas configuraciones de memoria y otros elementos críticos de ajuste de rendimiento.


@ BrianBallsun-Stanton si tiene datos secuenciales voluminosos que se relacionan con estas tablas de búsqueda, el espacio de almacenamiento no es barato (en términos de velocidad de consulta) porque la velocidad de lectura del disco es el cuello de botella en cualquier RDB que no se puede almacenar en caché por completo en la RAM. Encontré esto al tratar de desarrollar un esquema RDB que pueda competir con los mejores en el negocio de DB de series temporales. Revelación completa, no tengo ninguna relación con Skyspark, excepto que le cobran mucho a mi empleador por el uso de su DB muy eficiente.
Hobs

8

Creo que no hay problema con el rendimiento de la tabla que rara vez cambia. Quizás tenga problemas con el diseño en el futuro. Le sugiero que no use los datos comerciales como clave principal debido a los cambios comerciales. Use cualquier clave primaria adicional para "vincular" tablas en su modelo. Cualquier cambio en el negocio NO afectará las tablas relacionadas con esta.


3

La verdadera pregunta es si el rendimiento de la consulta DB es significativo para su aplicación (tamaño de datos). Si su consulta toma microsegundos, guardar algunos de esos microsegundos usando Intclaves no vale la pena de legibilidad / mantenibilidad. Sin embargo, si su consulta toma minutos, entonces guardar algunos de esos minutos puede valer la pena Int.

A continuación se muestra por qué creo que los enteros pueden ahorrarle tiempo de consulta (como un porcentaje de su tiempo de consulta general), pero los fundadores de SkySpark pueden explicarlo mejor que yo . Divulgación completa, mi empleador le paga a SkySpark mucho dinero para usar su base de datos y estoy tratando de construir algo mejor / más rápido.

Si tiene muchos datos secuenciales (archivos de registro, series de tiempo, análisis, corpus de texto o de voz) que tienen enlaces (relaciones) a cualquiera de sus tablas de búsqueda, encontrará que el espacio de almacenamiento es crítico para la velocidad de consulta, a pesar de @ El correcto análisis de Ballsun-Stanton de lo barato que es el espacio en $. Debido a que la mayor parte del tiempo de consulta (para datos secuenciales) se gasta leyendo el disco, el espacio no es barato en términos de tiempo (como un porcentaje del tiempo total de consulta). Por lo tanto, a menos que su RDB comprima / descomprima de manera automática y eficiente todas las claves foráneas (claves de registros relacionados), querrá que todas sus claves Intsean las más eficientes en términos de espacio en disco (y velocidad de lectura) por unidad de información contenido (entropía). FYI MyISAM en MySql impone restriccionessobre lo que puede hacer con filas de datos comprimidos (solo lectura). En otras palabras, los enteros incrementados automáticamente ya están comprimidos tanto como es teóricamente posible , dada la baja limitación de tamaño mínimo en la mayoría de los campos de enteros DB. Y esa compresión viene sin:

  1. penalización por tiempo de consulta / descompresión
  2. penalización por lectura de disco en tiempo de consulta
  3. solo lectura u otras restricciones de base de datos en registros de datos comprimidos o claves

Hay una razón por la cual los ORM populares y eficientes, como Django, predeterminan enteros de incremento automático para PK y por qué otras preguntas SO han llegado a la misma conclusión.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.