SQL Server - Clave primaria - simular autoincremental

   
Vista:

Clave primaria - simular autoincremental

Publicado por Juan Carlos (11 intervenciones) el 16/11/2009 17:34:15
Estimados Foreros:

Necesito saber que pros y contras tiene la solución que se me sugirió para el siguiente problema de gestionar la clave principal de una tabla (en realidad de varias).

Supongamos que tengo la tabla 'TABLA' cuya clave principarl es 'NRO_DE_TABLA', además tengo la tabla 'ULTIMO_NRO_TABLA' con una única columna con el mismo nombre. Lo que se me sugirió es que al insertar en 'TABLA' se lea primero 'ULTIMO_NRO_TABLA', se incremente este valor y al resultado se lo use para insertar la nueva tupla (y actualizando 'ULTIMO_NRO_TABLA'). Todo esto dentro de una transacción.
Otra opción en vez de tener la tabla extra es hacer un select max del campo clave, pero tendría un overhead de procesamiento.

Es esta una buena práctica, o al menos aceptable)

Espero haya podido explicarme, muchas gracias.

Entiendo que se puede usar un campo 'autoincremental', pero se me pidió que no haga uso de esta facilidad :(.
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
información
Otras secciones de LWP con contenido de SQL Server
- Cursos de SQL Server
- Temas de SQL Server
- Chat de SQL Server
información
Cursos y Temas de SQL Server
- Tablas temporales en el SQL Server
- Manual de SQL Server
- Curso de SQL Server 2005
Imágen de perfil de Isaias

RE:Clave primaria - simular autoincremental

Publicado por Isaias (3181 intervenciones) el 17/11/2009 17:28:11
Pues yo haria un MAX() y sumaria 1 en un transaccion.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Clave primaria - simular autoincremental

Publicado por Juan Carlos (11 intervenciones) el 17/11/2009 18:17:22
Muchas gracias Isaias.

Eso lo harías para eliminar las tablas extras? Necesito poder argumentar la decisión que tome :), por eso hago la repregunta. El criterio que usas para este análisis me serviría.

He oído por ahí eso de tener una tabla extra para evitar el select max por una cuestión de performance, quería saber si es una práctica común esto.

Ah! lo olvidaba, el campo clave es de tipo nchar(). (También por decisión externa a mí)

Muchas gracias de nuevo y saludos cordiales.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Isaias

RE:Clave primaria - simular autoincremental

Publicado por Isaias (3181 intervenciones) el 18/11/2009 20:37:46
Habiendo INDICES, no me preocuparia hacer el MAX(CAMPO)
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Clave primaria - simular autoincremental

Publicado por Juan Carlos (11 intervenciones) el 19/11/2009 15:52:42
Muchas gracias por tu ayuda Isaias, la verdad que es muy bueno poder recurrir a gente que se presta a compartir su conocimiento con nosotros que recién empezamos con esto.

Aprovecho para consultar algo que si bien lo he buscado, no lo pude encontrar. El escenario es el siguiente: si alguien hace un SELECT MAX sobre el campo clave dentro de una transacción, le suma uno y usa eso como clave, no se podrían repetir las claves si otro hace un SELECT MAX antes de que el primero inserte la nueva tupla? No se si me he logrado explicar, mi duda es como hago que otros no puedan leer un registro hasta que yo lo actualice.

Muchas gracias por tu atención,
Saludos cordiales.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Clave primaria - simular autoincremental

Publicado por Juan Carlos (11 intervenciones) el 19/11/2009 15:55:03
Me faltaba agregar que he probado leer un campo dentro de una transacción, pero antes de comitear la transacción otro proceso puede leer el mismo campo.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Isaias

RE:Clave primaria - simular autoincremental

Publicado por Isaias (3181 intervenciones) el 19/11/2009 18:11:44
NOP, si tienes serializable tu transaccion, esta se comporta como una FILA DE CINE, mientras en que esta en la taquilla no compre su boleto (commit tran), los de atras, deberan esperar.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Clave primaria - simular autoincremental

Publicado por Juan Carlos (11 intervenciones) el 19/11/2009 19:01:00
No me anduvo :( hice lo siguiente:

Desde una primera consola hice lo siguiente:

USE BD;
GO
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
GO
BEGIN TRANSACTION;
GO
SELECT max(cod_bco)
FROM BANCOS;
GO
/*
COMMIT TRANSACTION;
GO
*/

y desde otra:

USE BD;
GO
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
GO
BEGIN TRANSACTION;
GO
SELECT max(cod_bco)
FROM BANCOS;
GO

COMMIT TRANSACTION;
GO

y la segunda pudo leer los datos de la primera sin que la primera haga el comit.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Isaias

RE:Clave primaria - simular autoincremental

Publicado por Isaias (3181 intervenciones) el 20/11/2009 18:42:40
Antonio

En este mismo foro, me hicieron la misma pregunta, coloque el siguiente procedimiento que fue probado con 500 usuarios al mismo tiempo (es un FOLIADOR, genera un folio por cada usuario que lo solicita) y de 10,000 folios generados, NUNCA, duplico uno solo.

-- Store que sirve como FOLIADOR
CREATE PROCEDURE sPS_ObtieneFolioHost
@iOrigen tinyint = 0,
@iFolioHost int = 0 OUTPUT
AS
BEGIN
SET NOCOUNT ON
BEGIN TRAN MyTran
UPDATE FOLIADOR WITH (ROWLOCK)
SET FOLIO = ISNULL(FOLIO, 0) + 1
SELECT @iFolioHost = FOLIO FROM FOLIADOR ROWLOCK
COMMIT TRAN MyTran
IF @iOrigen = 1
SELECT @iFolioHost
END

Saludos
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Clave primaria - simular autoincremental

Publicado por Juan Carlos (11 intervenciones) el 20/11/2009 19:01:44
Isaias muchas gracias por tu paciencia y generosidad :), realmente no pretendo abusar de ella. Pero de mi respeto a tu conocimiento nace mi voluntad de interpelarte y repreguntarte. Si no creyera que eres un experto no seguiría repreguntando:)

En el código que me presentas hay un UPDATE primero, así que allí inevitablemente el siguiente update se bloquea hasta que el primero commitea. Pero en el caso de lecturas, no funciona así, por ello es que digo que tu select max dentro de la transacción no va a funcionar salvo que se use así:

insert into tabla (pk, nombre) values (select max(pk from tabla), 'pepe')

y lo que bloquea es el insert.

si lo lo leyera, lo incrementara y luego lo escribiera, habría riesgo de claves duplicadas (por supuesto el motor no lo permitiría se pk es clave primaria).

La solución que encontré fué primero updatear el numerador y después leerlo, de esa forma lo logro. (lo leí en el blog de maxi ...)

Mi conclusión es que no pudo bloquear un registro que leo.

saludos y muchas gracias por tu antención y paciencia.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Isaias

RE:Clave primaria - simular autoincremental

Publicado por Isaias (3181 intervenciones) el 20/11/2009 23:08:20
Como te comente, este codigo, esta trabajando en una base de PRODUCCION, con 500 usuarios en linea (call center), NUNCA ha habido un registro duplicado.

Pero bueno, hay muchas formas de matar cucarachas.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Clave primaria - simular autoincremental

Publicado por Juan Carlos (11 intervenciones) el 20/11/2009 23:46:29
Gracias:)
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar