我需要定期将大型(数十万行)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 |
+--------+---------+-----------+
请注意,Food有更多记录,因为输入包含那些被分成多个记录的讨厌的小列表。这是帮助建立单独表格的另一个原因。
所以问题是,从文件中获取数据的最有效方法是什么?
我考虑过的方法:
那里还有其他可能吗?
架构仍在开发中,所以如果最终成为关键点,我可以修改它。
答案 0 :(得分:1)
您可以在以下结构的表格中导入您的文件: Diner , Beverage , Food , Dessert , ID (身份,主键 NOT CLUSTERED - 用于性能问题)。
在此之后,只需添加以下列:Dinner_ID
,Beverage_ID
,Dessert_ID
并根据您的单独表填充它们(将每个列分组并添加缺失很简单数据以Beverages
,Desserts
,Meals
的形式查找表格,之后,使用现有和新添加记录的ID修复导入的表格。“
Food
表的情况更复杂,因为能够combine
食物,但可以使用相同的技巧:你也可以将数据添加到查找表中,其中,将食物组合存储在附加温度表(具有唯一ID)和单个菜肴上的分离。
当完成分区时,您将有3个临时表:
从上面的表中,您可以根据需要将解析后的值插入到任一结构中。
在这种情况下,代码端只对DB执行一次插入(批量)操作。所有其他数据操作将在DB中执行。