2012-03-28 15 views
5

Tenemos un sistema en el que a los clientes se les asigna un producto por orden de llegada.Solución óptima para una gran cantidad de solicitudes en una tabla de base de datos

Nuestra tabla de productos contiene una clave principal incremento que se inició a cero, lo que utilizamos para realizar un seguimiento de la cantidad de productos que se han asignado es decir, un usuario se reserva un producto y se asigna 1, junto usuario obtiene 2, etc.

El problema es que potencialmente cientos de miles de usuarios accederán al sistema en cualquier momento. Todos los cuales golpearán esta mesa.

Como debemos asegurarnos de asignar un producto a cada cliente y realizar un seguimiento de la cantidad de productos asignados, utilizamos un bloqueo de fila para cada cliente que accede al sistema para asegurarnos de escribir en la mesa antes del próximo cliente golpea el sistema, es decir, haciendo cumplir la regla del primero llegado primero servido.

Nos preocupa el cuello de botella que es el tiempo de procesamiento de cada solicitud entrando en SQL Server 2008 Enterprise Edition y el bloqueo de fila.

No podemos usar varios servidores ya que necesitamos asegurar la integridad de la clave primaria, por lo que cualquier cosa que requiera replicación no funcionará.

¿Alguien sabe de alguna buena solución que sea particularmente eficiente en el manejo de un gran número de solicitudes en una tabla de base de datos?

Un poco más de información: La tabla en cuestión contiene esencialmente dos campos solamente: ID e ID de cliente. La solución es un regalo gratis de un millón de productos; de ahí la expectativa de una gran demanda y por qué el uso de la tecla principal creciente como clave tiene sentido para nosotros: una vez que la clave llega a un millón, no pueden registrarse más clientes. Además, los productos son todos diferentes, por lo que la asignación de la clave correcta es importante, p. los primeros 100 clientes ingresados ​​reciben un producto de mayor valor que los siguientes 100, etc.

Gracias por cualquier ayuda.

+1

¿Puede volver a etiquetar, incluya [sqlserver] y me puede decir la versión y edición, si edita su pregunta y nos dice que tiene 'SQL2008 Enterprise Edition', por ejemplo, podríamos ofrecer soluciones a medida, por ejemplo Table Partitioning está disponible en SQL 2008 EE –

+0

Gracias Jeremy. Se agregó la información adicional. –

+0

Obvia primera pregunta; ¿Has despojado a todo lo demás de la transacción que obtiene la clave? P.ej. ¿Sabes antes de tratar de obtener la clave de todo lo que necesitas saber, ir a la mesa, obtener la llave y desbloquear antes de hacer otras cosas? – Karl

Respuesta

5

Primero, para eliminar el problema de la generación de claves, las generaría todas por adelantado. Solo tiene 1m de filas y significa que no tiene que preocuparse por la administración del proceso de generación de claves. También significa que no tiene que preocuparse por generar demasiadas filas accidentalmente, porque una vez que tenga la tabla llena, solo realizará ACTUALIZACIONES, no INSERTAR.

Una pregunta importante aquí es, ¿son idénticos o no todos los elementos de 1 m? Si lo son, no importa en qué orden estén las claves (o incluso si tienen un pedido), para que los clientes envíen solicitudes, simplemente 'intenta' ACTUALIZAR la tabla aproximadamente así:

UPDATE TOP(1) dbo.Giveaway -- you can use OUTPUT to return the key value here 
SET CustomerID = @CurrentCustomerID 
WHERE CustomerID IS NULL 

IF @@ROWCOUNT = 0 -- no free items left 
PRINT 'Bad luck' 
ELSE 
PRINT 'Winner' 

Si, por otro lado, los elementos de 1 m son diferentes, entonces necesita otra solución, por ejemplo el ítem 1 es X, los ítems 2-10 son Y, 11-50 son Z, etc. En este caso, es importante asignar clientes a las claves en el orden en que se envían las solicitudes, por lo que probablemente deba buscar algún tipo de sistema de colas, quizás usando Service Broker. Cada cliente agrega una solicitud a la cola, luego un procedimiento almacenado los procesa de uno en uno y les asigna la tecla libre MAX, luego devuelve los detalles de lo que ganaron.

+0

'SET ROWCOUNT' está en desuso en SQL 2008. Use' UPDATE TOP (1) 'en su lugar? http://msdn.microsoft.com/en-us/library/ms188774%28v=sql.100%29.aspx –

+0

@EdHarper Sí, ese es un buen punto y he actualizado mi ejemplo. Aunque el mensaje clave para el OP es, por supuesto, que no importa qué fila actualice siempre que actualice solo una. – Pondlife

+0

Gracias Pondlife. Los artículos son diferentes, por lo que parece que hacer cola es el camino a seguir y simplemente acepta que habrá un poco de retraso en el procesamiento de cada solicitud en las horas punta. Otra solución en la que estaba pensando era colocar todos los números impares en una base de datos e incluso en otra base de datos tener un equilibrador de carga con un simple interruptor de bit enviar clientes alternativos a una base de datos. ¿Alguna idea de ello como solución? Supongo que probablemente moveré el cuello de botella al equilibrador de carga y que probablemente también necesite una cola. Gracias por su ayuda, muy apreciada. –

Cuestiones relacionadas