2012-02-09 1 views
0

У меня есть сценарий, в котором данные должны быть импортированы из файла CSV через приложение .NET в SQL Server 2008 на сервере базы данных (распределено). Файл CSV содержит около 4 миллиона записей ', в то время как таблица назначения может содержать более 100 миллионов записей. Данные, которые импортируются, должны быть проверены на наличие существующих данных для дубликатов до того, как вставка будет выполнена.Высокопроизводительная архитектура для сценария dataimport?

Я попытался создать DataTable в памяти и отправить это как параметр хранимой процедуре, однако это очень плохо.

Что такое хороший подход для этого сценария?

  • данных для импорта (importdata) должен быть отправлен в SQL Server
  • importdata необходимо проверить Agains существующие данные (existing) для дубликатов
  • если только один дубликат найден в existing весь импорт для importdata должна быть прервана

Формат CSV

"Name1", "11111111-1111-1111-1111-111111111111" 
"Name1", "11111111-1111-1111-1111-111111111111" 
"Name1", "11111111-1111-1111-1111-111111111111" 

данных для импорта (DataTable формат схематично):

Table (
    name nvarchar(20), 
    someId uniqueidentifier 
) 

Таблица назначения на SQL Server (схематично):

Table (
    id int primarykey, 
    name nvarchar(20), 
    someId uniqueidentifier 
) 
+1

CsvReader (код-проект), затем SqlBulkCopy (.net BCL) - должен работать нормально –

+0

Вы вообще не видели [SSIS] (http://en.wikipedia.org/wiki/SQL_Server_Integration_Services)? – Oded

+0

@Oded: не вариант из-за распределенной среды – ReFocus

ответ

1

Что бы я сделал. , ,

  1. Использование класса SqlBulkCopy я вставить 4 миллиона строк в базу данных во временную таблицу (или таблицы, Постоянный но используется только для этой цели).
  2. Напишите Proc, который запускает один стол против другого, и только вставляет строк в таблицу назначения соответствующим образом.

Класс SqlBulkCopy - это самый быстрый способ получить данные в MS SQL DB, а затем получить db для обновления, это то, на что это хорошо.

Обновление Это можно сделать в сделке?

Да, но я не хотел бы представлять транзакцию, охватывающую вставку из 4 миллионов строк и обновляющую разные 4 миллиона строк.

Если вы используете действительно временную таблицу (например, #MyTempStrore), то таблица температуры будет сброшен, когда вы закончите эту сессию в базе данных (например, dbConn.Close()).
Если вы используете таблицу permant, вы можете создать уникальный идентификатор сеанса, вставить все строки с этим идентификатором и передать этот идентификатор в сохраненный proc. Затем вы можете очистить эти идентификаторы из таблицы, если хотите (или просто усечь таблицу).

Надеюсь, это поможет.

+0

Может ли это быть заключено в транзакции в сочетании с proc? Мне нужно быть уверенным, что данные, скопированные в временную таблицу, будут удалены впоследствии ... – ReFocus

+0

ReFocus: добавлено больше деталей в ответе –

1

Я хотел бы создать временную таблицу для массового импорта все записи CSV:

BULK 
INSERT CSVTEMP 
FROM 'c:\csvfile.txt' 
WITH 
(
FIELDTERMINATOR = ',', 
ROWTERMINATOR = '\n' 
) 
GO 

Затем создайте хранимую процедуру для вставки из CSVTEMP в пункт назначения, выполнив все проверки.

+0

Это не вариант, так как это распределенная среда, и невозможно получить CSV на сервере базы данных. – ReFocus

0

проверить SQLBulkCopy и SqlBulkCopyOptions.CheckConstraints. Вы можете использовать SQLBulkCopy direct в целевой таблице и разрешить откат всех изменений, если возникает дублирующийся ключ.

 Смежные вопросы

  • Нет связанных вопросов^_^