none
Correlativo solicitud RRS feed

  • Pregunta

  • Buenas noches,

    Estoy desarrollando una aplicación en C# y ASP.NET. estoy con una disyuntiva en cuanto a mi llave primaria de mi solicitud, el cual es de tipo decimal(9,0), he pensado formar mi correlativo de esta forma="codigoagencia+secuencia". Por lo tanto quedaría compuesto así, por ejemplo= 240000100, en este caso es la agencia 24 y el número de secuencia es el 100, esta secuencia se almacenará en una tabla diferente y cada vez que se haga un insert, la secuencia se actualizaría sumándole 1.

    La pregunta va más enfocada en cuanto al rendimiento, es correcto formar un correlativo de esta forma con el código de la agencia y un número secuencial?

    No afectará al rendimiento que el primary key sea variable la longitud ya que de ser como el ejemplo, si el número de la agencia es de 2 cifras (agencia 24) el correlativo si quedará de 9 posiciones pero si la agencia es de 1 cifra (agencia 1) la longitud del correlativo quedará solo de 8 posiciones.

    240000100(longitud=9) 10000101 (longitud = 8), hay algún problema en que varíen las longitudes en una llave primaria?


    Carlos Márquez

    lunes, 23 de junio de 2014 3:41

Respuestas

  • No, no hay ningún problema en que varíen las longitudes de la clave primaria. Sí hay problema en que la clave primaria sea "larga" o costosa de comparar, por lo que si puedes te recomiendo que no uses un varchar sino un numérico.

    Otra alternativa es usar más de una columna para la clave primaria. Por ejemplo, puedes tener una columna con el CodigoAgencia (tipo int) y otra con la Secuencia (también int) y hacer que la clave primaria esté formada por ambas columnas a la vez.

    • Marcado como respuesta Carlos Márquez miércoles, 25 de junio de 2014 2:43
    lunes, 23 de junio de 2014 5:10
    Moderador
  • >>la pregunta pasaba más por si tener un decimal(13,0) iba a ser poco eficiente en db2.

    como primer comentario diria que al menos con que sea numerico es mejor opcion a una clave alfanumerica

    despues evaluaria sino hay un tipo de dato entero como para soportar la clave definida, veo que mencionas un bigint, porque no podrias usarlo ?

    >>Lo de la llave es un formato propio, una especie de máscara, (idAgencia+secuencial) tengo entendido que es válido y no rompe con ninguna de las formas normales ya que tengo además un atributo IdAgencia en mi tabla

    pero la key de la tabla entonces esel idAgencia? si lo es entonces esa parte esta correcta

    la definicion de dos conceptos en un solo campo esta mal, las formas normales no permiten campos compuestos

    es mas si por ejemplo quieres guardar la factura son 3 campos, la letra, la sucursal, y el secuancial, no se usa un solo campo

    en este caso es lo mismo, define dos campos separados, no los unas

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina

    • Marcado como respuesta Carlos Márquez miércoles, 25 de junio de 2014 2:43
    miércoles, 25 de junio de 2014 1:51

Todas las respuestas

  • No, no hay ningún problema en que varíen las longitudes de la clave primaria. Sí hay problema en que la clave primaria sea "larga" o costosa de comparar, por lo que si puedes te recomiendo que no uses un varchar sino un numérico.

    Otra alternativa es usar más de una columna para la clave primaria. Por ejemplo, puedes tener una columna con el CodigoAgencia (tipo int) y otra con la Secuencia (también int) y hacer que la clave primaria esté formada por ambas columnas a la vez.

    • Marcado como respuesta Carlos Márquez miércoles, 25 de junio de 2014 2:43
    lunes, 23 de junio de 2014 5:10
    Moderador
  • Hola, Alberto.

    El tipo de dato que estoy utilizando es decimal(9,0). Con esto no hay ningún problema, con que la llave primaria sea decimal o pensás que es mejor usar un tipo de dato int?

    En cuanto a la longitud te parece muy larga dejar un correlativo de este tipo por ejemplo: 240000100 ?


    Carlos Márquez

    lunes, 23 de junio de 2014 5:29
  • No, no es demasiado largo. Un Decimal(9,0) ocupa 5 bytes en la base de datos, que es un tamaño bastante pequeño. Y siempre mide lo mismo, da igual que guardes un 0 o que guardes 999999999.

    Pero con un dato de tipo INT solo ocuparías 4 bytes, y además las comparaciones de los INT son más eficientes que las de los DECIMAL, y en el INT te caben de sobra los 9 dígitos. No se me ocurre ninguna razón por la que usar un Decimal pueda ser mejor que usar un Int para esta finalidad.

    lunes, 23 de junio de 2014 14:30
    Moderador
  • Hola, Alberto.

    Si, a simple vista el INT es la mejor opción, sin embargo la longitud que abarca el int es de en promedio 9 dígitos pero que pasa si se llaga a más de un millón de clientes y las agencias llegan a ser (1000) o mas o sea 3 dígitos solo para la agencia, de hecho haciendo todas estas consideraciones me han pedido que la llave sea decimal(13,0) dejando 3 dígitos para la agencias y 10 dígitos para los clientes.

    Ahora siendo la llave primaria de tipo decimal(13,0) te parece demasiado larga y difícil de procesar para el motor de base de datos si fuera así: 240000000000100?


    Carlos Márquez

    lunes, 23 de junio de 2014 15:29
  • Con 13 dígitos, el Decimal ocupa 9 bytes en la base de datos. Sigue siendo un tamaño pequeño, así que desde este punto de vista no hay problema en usarlo como clave.

    Desde el punto de vista de normalización de la base de datos, si las partes de "cliente" y "agencia" son datos reales que tienen sentido por separado, entonces sería preferible usar una clave primaria compuesta por dos campos, uno para el cliente y otro para la agencia, en lugar de concatenarlos. Tipo int para cada uno (suficiente para dos mil millones de clientes en cada agencia), ocupando 8 bytes en total.

    lunes, 23 de junio de 2014 15:59
    Moderador
  • Hola, Alberto.

    Ya para ir finalizando, Un tipo INT entonces definitivamente no soporta 13 dígitos, no?

    Solo por cuestiones de cultura general, de no hacer utilizado un decimal(13,0) aparte de tu otra solución de la llave primaria compuesta por los 2 campos, el BIGINT hubiese sido mejor opción que el decimal(13,0)?

    y por ultimo, al momento de que hayan ya muchos registros en la tabla, crees que por la longitud de decimal(13,0) las consultas vayan a tardar mucho tiempo en realizarse cuando se filtre por este campo?


    Carlos Márquez

    lunes, 23 de junio de 2014 16:27
  • el BIGINT hubiese sido mejor opción que el decimal(13,0)?

    Sí, el Bigint mide 8 bytes (en lugar de 9) y además al ser un tipo entero las comparaciones son más rápidas que las del Decimal. Así que es preferible usar un Bigint.

    Las consultas serán eficientes aunque haya muchos registros siempre que las hagas bien hechas, es decir, esto sería rápido:

    ... where clave = agencia+cliente

    pero esto sería lento (esquemáticamente, habría que hacerlo bien con las conversiones de datos):

    ... where left(clave,3)+right(clave,10) = 240000000000100

    lunes, 23 de junio de 2014 16:33
    Moderador
  • Hola, Alberto.

    Lo que quise preguntar es que si al usar un decimal(13,0) como llave primaria, bajará la eficiencia de mis consultas, será mas lento el proceso de generar la data al usar decimal y no BIGINT? Por cierto el motor de base de datos es DB2.


    Carlos Márquez

    lunes, 23 de junio de 2014 16:46
  • Por cierto el motor de base de datos es DB2.

    Ah, pues entonces no hagas caso de las longitudes de datos que te he mencionado antes; eran para SQL Server.

    Pero en cualquier caso, es prácticamente seguro que cualquier tipo de datos no-entero será más lento de procesar que un tipo entero. Te merecerá la pena usar un BIGINT en lugar de un Decimal (aunque los tiempos dedicados a comparar los valores numéricos serán insignificantes frente a los tiempos necesarios para leer las páginas de datos desde el disco).

    lunes, 23 de junio de 2014 20:21
    Moderador
  • hola

    no voy a analizar temas de longuitudes de campos, ni tampoco afecta que db utilices

    lo que si puedo comentarte es que segun las formas normales, no es recomendable usar campos compuestos

    eso que quieres hacer de unir dos cosas (codigo de agencia  + secuancial) rompe con las formas normales, por lo que no lo aconsejo para nada, si defines un secuancial que sea secuancial, que la agencia este como otro campo, que no sea la clave o a los sumo usa clave doble entre dos campos

    Normalización de bases de datos

    pr o que mi consejo seria que no importa lo del tipo de dato, no definas una clave de una tabla uniendo dos conceptos en ese campo compuesto

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina

    martes, 24 de junio de 2014 2:07
  • Hola, Tuttini.

    Totalmente de acuerdo con la parte de la normalización, tengo que decirte que en mi tabla, aparte del código de la solicitud (codagencia + secuencia), también tengo un atributo código de agencia. la idea de componer el código de solicitud era para tener un formato propio:

    240000000100

    320000000101

    Pero el atributo código de agencia existe en la tabla, está ahí, la pregunta pasaba más por si tener un decimal(13,0) iba a ser poco eficiente en db2.

    Teniendo un código de solicitud con el formato antes descrito y teniendo el atributo código de agencia también dentro de la tabla, te sigue pareciendo incorrecto dejarlo de esta forma?


    Carlos Márquez

    martes, 24 de junio de 2014 2:45
  • Hola, Tuttini.

    Lo de la llave es un formato propio, una especie de máscara, (idAgencia+secuencial) tengo entendido que es válido y no rompe con ninguna de las formas normales ya que tengo además un atributo IdAgencia en mi tabla, o sea consistencia hay, lo único que estoy pensando en hacer antes de formar la llave y concatenar es crear un trigger para que cada vez que haya un insert o un update valide que el IdAgencia y el sencuencial realmente existan para que no se de el caso de idsolicitud=240000000100 agencia = 25, secuencial = 101 eso es lo único que pretendo controlar y con eso verifico que haya consistencia pero el IdAgencia siempre va a quedar como atributo, claro sin ser parte de la llave pero va a estar ahí y de esa forma como dije antes cumple con la normalización.

    La pregunta iba mas enfocada en cuanto a si iba a bajar la eficiencia en las consultas al ser un decimal(13,0) el tipo de dato de la llave primaria.


    Carlos Márquez



    martes, 24 de junio de 2014 4:54
  • >>la pregunta pasaba más por si tener un decimal(13,0) iba a ser poco eficiente en db2.

    como primer comentario diria que al menos con que sea numerico es mejor opcion a una clave alfanumerica

    despues evaluaria sino hay un tipo de dato entero como para soportar la clave definida, veo que mencionas un bigint, porque no podrias usarlo ?

    >>Lo de la llave es un formato propio, una especie de máscara, (idAgencia+secuencial) tengo entendido que es válido y no rompe con ninguna de las formas normales ya que tengo además un atributo IdAgencia en mi tabla

    pero la key de la tabla entonces esel idAgencia? si lo es entonces esa parte esta correcta

    la definicion de dos conceptos en un solo campo esta mal, las formas normales no permiten campos compuestos

    es mas si por ejemplo quieres guardar la factura son 3 campos, la letra, la sucursal, y el secuancial, no se usa un solo campo

    en este caso es lo mismo, define dos campos separados, no los unas

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina

    • Marcado como respuesta Carlos Márquez miércoles, 25 de junio de 2014 2:43
    miércoles, 25 de junio de 2014 1:51