Мне нужно регулярно импортировать большие (сотни тысяч строк) tsv-файлы во множество связанных таблиц SQL Server 2008 R2.Каков самый быстрый способ выполнения больших вставок с отношениями внешнего ключа и предварительной обработки?
Входной файл выглядит примерно так (это на самом деле еще более сложным, и данные другой характер, но то, что я здесь аналогично):
January_1_Lunch.tsv
+-------+----------+-------------+---------+
| Diner | Beverage | Food | Dessert |
+-------+----------+-------------+---------+
| Nancy | coffee | salad_steak | pie |
| Joe | milk | soup_steak | cake |
| Pat | coffee | soup_tofu | pie |
+-------+----------+-------------+---------+
Обратите внимание, что один столбец содержит характера -пределенный список, которому требуется предварительная обработка, чтобы разделить его.
Схема сильно нормализована - каждая запись имеет несколько взаимосвязей между многими и многими внешними ключами. Здесь нет ничего необычного ...
Meals
+----+-----------------+
| id | name |
+----+-----------------+
| 1 | January_1_Lunch |
+----+-----------------+
Beverages
+----+--------+
| id | name |
+----+--------+
| 1 | coffee |
| 2 | milk |
+----+--------+
Food
+----+-------+
| id | name |
+----+-------+
| 1 | salad |
| 2 | soup |
| 3 | steak |
| 4 | tofu |
+----+-------+
Desserts
+----+------+
| id | name |
+----+------+
| 1 | pie |
| 2 | cake |
+----+------+
Каждый столбец ввода в конечном итоге предназначен для отдельной таблицы.
Это может показаться излишне сложной схемой - почему бы просто не иметь единственную таблицу, соответствующую вводу? Но подумайте, что закусочная может прийти в ресторан и заказать только напиток или десерт, и в этом случае будет много нулевых рядов. Учитывая, что эта БД в конечном счете хранит сотни миллионов записей, это похоже на плохое использование хранилища. Я также хочу иметь возможность создавать отчеты только для напитков, десертов и т. Д., И я полагаю, что они будут работать намного лучше с отдельными таблицами.
Заказов отслеживаются в таблицах отношений, как это:
BeverageOrders
+--------+---------+------------+
| mealId | dinerId | beverageId |
+--------+---------+------------+
| 1 | 1 | 1 |
| 1 | 2 | 2 |
| 1 | 3 | 1 |
+--------+---------+------------+
FoodOrders
+--------+---------+--------+
| mealId | dinerId | foodId |
+--------+---------+--------+
| 1 | 1 | 1 |
| 1 | 1 | 3 |
| 1 | 2 | 2 |
| 1 | 2 | 3 |
| 1 | 3 | 2 |
| 1 | 3 | 4 |
+--------+---------+--------+
DessertOrders
+--------+---------+-----------+
| mealId | dinerId | dessertId |
+--------+---------+-----------+
| 1 | 1 | 1 |
| 1 | 2 | 2 |
| 1 | 3 | 1 |
+--------+---------+-----------+
Обратите внимание, что есть несколько записей для пищевых продуктов, так как входные данные содержали ту малоприятную списки, которые были разделены на несколько записей. Это еще одна причина, по которой это помогает иметь отдельные таблицы.
Итак, вопрос в том, что является наиболее эффективным способом получения данных из файла в схему, которую вы видите выше?
подходов Я рассмотрел:
- Разбирает файл TSV линии за линией, выполняя вставки, как я иду. Независимо от того, используете ли ORM или нет, это похоже на множество поездок в базу данных и будет очень медленным.
- Разбирайте файл ЦСУ в структуры данных в памяти или несколько файлов на диске, соответствующих схеме. Затем используйте SqlBulkCopy для импорта каждого из них. В то время как транзакций меньше, это кажется более дорогостоящим, чем просто выполнение множества вставок из-за необходимости либо кэшировать большое количество данных, либо выполнять многие записи на диск.
- За How do I bulk insert two datatables that have an Identity relationship и Best practices for inserting/updating large amount of data in SQL Server 2008 импортируйте файл ЦС в промежуточную таблицу, а затем объединитесь в схему, используя функции БД, чтобы выполнить предварительную обработку. Это похоже на лучший вариант, но я думаю, что проверка и предварительная обработка могут быть более эффективными в C# или действительно что-либо еще.
Есть ли другие возможности там?
Схема все еще находится в разработке, поэтому я могу ее пересмотреть, если это окажется точкой торцевания.
4. Используйте SSIS ................. –
Я бы посоветовал вам пересмотреть разделение между напитками, едой и десертом и подумать о том, чтобы иметь один стол для этих предметов с код, указывающий «тип» или «категория». Зачем? Хорошо рассмотрите изменение бизнеса, которое добавляет «начальные» или «боковые заказы», гораздо проще добавить новую категорию, чем добавить новую новую таблицу. Не беспокойтесь о неэффективности космоса; гораздо важнее получить хорошую модель. – Rikalous
@MitchWheat - У меня было ощущение, что службы интеграции SQL Server могут быть полезны, но очень мало знают об этом. Не могли бы вы быть более конкретными? Мы говорим о ETL здесь? – ibadibam