Estratégia de inserção em massa de c # para SQL Server
Em nosso projeto atual, os clientes enviarão uma coleção de mensagens complexas / aninhadas ao nosso sistema. A frequência destas mensagens é de aprox. 1000-2000 msg / por segundo.
Esses objetos complexos contêm os dados da transação (a serem adicionados) e os dados mestre (que serão adicionados se não forem encontrados). Mas, em vez de passar os IDs dos dados mestre, o cliente passa a coluna 'nome'.
O sistema verifica se existem dados mestre para esses nomes. Se encontrado, ele usa os IDs do banco de dados, caso contrário, crie esses dados mestre primeiro e depois use esses IDs.
Depois que os IDs de dados mestre são resolvidos, o sistema insere os dados transacionais em um banco de dados do SQL Server (usando IDs de dados mestre). O número de entidades mestras por mensagem é de 15 a 20.
A seguir estão algumas estratégias que podemos adotar.
Podemos resolver primeiro os IDs mestres a partir do nosso código C # (e inserir dados mestre se não forem encontrados) e armazenar esses IDs no cache C #. Depois que todos os IDs forem resolvidos, podemos inserir em massa os dados transacionais usandoSqlBulkCopy
classe. Podemos acessar o banco de dados 15 vezes para buscar os IDs de diferentes entidades e, em seguida, acessar o banco de dados mais uma vez para inserir os dados finais. Podemos usar a mesma conexão para fechá-la depois de todo esse processamento.
Podemos enviar todas essas mensagens contendo dados mestre e dados transacionais em um único hit para o banco de dados (na forma de TVP múltiplo) e depois dentro do procedimento armazenado, criar os dados mestre primeiro para os que estão faltando e inserir os dados transacionais.
Alguém poderia sugerir a melhor abordagem neste caso de uso?
Devido a algum problema de privacidade, não posso compartilhar a estrutura real do objeto. Mas aqui está a estrutura hipotética de objetos que está muito próxima do nosso objeto de negócios.
Uma dessas mensagens conterá informações sobre um produto (seus dados mestre) e seus detalhes de preço (dados de transação) de diferentes fornecedores:
Dados mestre (que precisam ser adicionados se não forem encontrados)
Nome do produto: ABC, ProductCateory: XYZ, Fabricante: XXX e alguns outros detalhes (o número de propriedades está no intervalo de 15 a 20).
Dados de transação (que sempre serão adicionados)
Nome do fornecedor: A, ListPrice: XXX, Desconto: XXX
Nome do fornecedor: B, ListPrice: XXX, Desconto: XXX
Nome do fornecedor: C, ListPrice: XXX, Desconto: XXX
Nome do fornecedor: D, ListPrice: XXX, Desconto: XXX
A maioria das informações sobre os dados mestre permanecerá a mesma para uma mensagem pertencer a um produto (e será alterada com menos frequência), mas os dados da transação sempre flutuarão. Portanto, o sistema verificará se o produto 'XXX' existe no sistema ou não. Caso contrário, verifique se a 'Categoria' mencionada com este produto existe ou não. Caso contrário, ele inserirá um novo registro para a categoria e depois para o produto. Isso será feito para o fabricante e outros dados mestre.
Vários fornecedores enviarão dados sobre vários produtos (2000-5000) ao mesmo tempo.
Portanto, suponha que tenhamos 1000 fornecedores. Cada fornecedor está enviando dados de 10 a 15 produtos diferentes. Após cada 2-3 segundos, cada fornecedor nos envia as atualizações de preço desses 10 produtos. Ele pode começar a enviar dados sobre novos produtos, mas que não serão muito frequentes.