Как разделить данные плоских файлов и загрузить их в родительские и дочерние таблицы в базе данных? - PullRequest
7 голосов
/ 12 июля 2011

У меня есть денормализованные данные (поступающие из файла), которые необходимо импортировать в таблицы типа «родители-потомки». Исходные данные выглядят примерно так:

Account#    Name        Membership    Email
101         J Burns     Gold          alpha@foo.com
101         J Burns     Gold          bravo@foo.com
101         J Burns     Gold          charlie@yay.com
227         H Gordon    Silver        red@color.com
350         B Clyde     Silver        italian@food.com
350         B Clyde     Silver        mexican@food.com

Какие части, части или тактику служб SSIS я должен использовать, чтобы прочитать первые три столбца в родительскую таблицу, а четвертый столбец (электронная почта) - в дочернюю таблицу? У меня есть несколько вариантов родительского ключа, которые мне разрешено брать:

  • Непосредственно используйте Account # в качестве первичного ключа
  • Использовать суррогатный ключ, сгенерированный SSIS в процессе импорта
  • Настройка первичного ключа идентификации

Я уверен, что перечислил мои первичные ключевые параметры в порядке возрастания сложности. Мне было бы интересно узнать, как сделать первый и последний вариант - я сделаю вывод, как добиться среднего варианта. Еще раз подчеркну: Я заинтересован в решительном решении SSIS; Я ищу ответ, который использует язык SSIS, а не процедурный, нейтральный в технологическом отношении ответ.

Мой вопрос чем-то похож на другой вопрос SO , имеющий ответ на неопределенную жизнеспособность. Я надеюсь, что более подробное руководство может быть дано. Я уже знаю, как решить эту проблему, создав «промежуточный» промежуточный этап, где разделение родитель-потомок фактически обрабатывается прямым SQL. Однако мне любопытно, как это можно сделать без такого промежуточного шага.

Мне кажется, что такого рода импорт был бы настолько распространенным, что был бы хорошо опубликованный формальный способ справиться с этим - методика, в которой SSIS превосходен. Пока что я не совсем понял прямого ответа на этот вопрос.

Update #1: Основываясь на комментариях, я настроил примерные данные, чтобы они были более явно денормализованы. Я также удалил «плоский» из «плоского файла», чтобы семантика не мешала вопросу.

Update #2: я усилил интерес к решению, на котором говорят на языке SSIS.

Ответы [ 2 ]

31 голосов
/ 12 июля 2011

Вот один из возможных вариантов, который вы можете рассмотреть при загрузке данных типа «родители-потомки». Эта опция состоит из двух шагов. На шаге first прочитайте исходный файл и запишите данные в родительскую таблицу. На шаге second снова прочитайте исходный файл и используйте преобразование поиска для извлечения родительской информации, чтобы записать данные в дочернюю таблицу. В следующем примере используются данные, представленные в вопросе. Этот пример был создан с использованием базы данных служб SSIS 2008 R2 и SQL Server 2008.

Пошаговый процесс:

  1. Создайте образец плоского файла с именем Source.txt, как показано на скриншоте # 1 .

  2. В базе данных SQL создайте две таблицы с именами dbo.Parent и dbo.Child, используя сценарии, приведенные в разделе SQL Scripts . Обе таблицы имеют автоматически генерируемый столбец идентификаторов.

  3. В пакете поместите OLE DB connection для подключения к SQL Server и Flat File connection для чтения исходного файла, как показано на скриншоте # 2 . Настройте соединение с плоским файлом, как показано на скриншотах # 3 - # 9 .

  4. На вкладке Поток управления разместите два Data Flow Tasks, как показано на скриншоте # 10 .

  5. Внутри задачи потока данных с именем Родитель поместите источник плоского файла, преобразование сортировки и место назначения OLE DB, как показано на скриншоте # 11 .

  6. Настройте источник плоского файла, как показано на снимках экрана # 12 и # 13 . Нам нужно прочитать исходный файл.

  7. Настройте преобразование сортировки, как показано на скриншоте # 14 . Нам нужно исключить повторяющиеся значения, чтобы в родительскую таблицу вставлялись только уникальные записи dbo.Parent.

  8. Настройте пункт назначения ole db, как показано на снимках экрана # 15 и # 16 . Нам нужно вставить данные в родительскую таблицу dbo.Parent.

  9. Внутри задачи потока данных с именем Дочерний поместите источник плоских файлов, преобразование «Уточняющий запрос» и назначение OLE DB, как показано на скриншоте # 17 .

  10. Сконфигурируйте источник плоских файлов, как показано на скриншотах # 12 и # 13 . Эта конфигурация аналогична источнику плоского файла в предыдущей задаче потока данных.

  11. Настройте преобразование поиска, как показано на скриншотах # 18 и # 20 . Нам нужно найти родительский идентификатор из таблицы dbo.Parent, используя другие ключевые столбцы, присутствующие в файле. Ключевыми столбцами здесь являются учетная запись, имя и адрес электронной почты. Если в файле есть уникальный столбец, вы можете просто использовать этот столбец для получения родительского идентификатора.

  12. Настройте пункт назначения ole db, как показано на скриншотах # 21 и # 22 * ​​1107 *. Нам нужно вставить столбец Email вместе с идентификатором Parent в таблицу dbo.Child.

  13. Снимок экрана # 23 показывает данные в таблицах до выполнения пакета.

  14. Снимки экрана # 24 и # 25 показывают пример выполнения пакета.

  15. Снимок экрана # 26 показывает данные в таблицах после выполнения пакета.

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

Сценарии SQL:

CREATE TABLE [dbo].[Child](
    [ChildId] [int] IDENTITY(1,1) NOT NULL,
    [ParentId] [int] NULL,
    [Email] [varchar](21) NULL,
CONSTRAINT [PK_Child] PRIMARY KEY CLUSTERED ([ChildId] ASC)) ON [PRIMARY]
GO

CREATE TABLE [dbo].[Parent](
    [ParentId] [int] IDENTITY(1,1) NOT NULL,
    [Account] [varchar](12) NULL,
    [Name] [varchar](12) NULL,
    [Membership] [varchar](14) NULL,
CONSTRAINT [PK_Parent] PRIMARY KEY CLUSTERED ([ParentId] ASC)) ON [PRIMARY]
GO

Скриншот № 1:

1

Скриншот №2:

2

Скриншот № 3:

3

Снимок экрана № 4:

4

Скриншот № 5:

5

Снимок экрана № 6:

6

Снимок экрана № 7:

7

Снимок экрана № 8:

8

Скриншот №9:

9

Снимок экрана № 10:

10

Снимок экрана № 11:

11

Снимок экрана № 12:

12

Снимок экрана № 13:

13

Снимок экрана № 14:

14

Скриншот № 15:

15

Снимок экрана № 16:

16

Снимок экрана № 17:

17

Снимок экрана № 18:

18

Снимок экрана № 19:

19

Снимок экрана № 20:

20

Снимок экрана № 21:

21

Снимок экрана № 22:

22

Снимок экрана № 23:

23

Снимок экрана № 24:

24

Снимок экрана № 25:

25

Снимок экрана № 26:

26

0 голосов
/ 12 июля 2011

Если данные отсортированы, а Account # - целое число, я бы:

Вставьте электронные письма в таблицу (добавьте столбец с автоинкрементом, это лучший метод).

1  101    alpha@foo.com
2  101    bravo@foo.com
3  101    charlie@yay.com
etc.

Тогда я бы вставил другие записи в родительскую таблицу.

  • используя Account # в качестве первичного ключа
  • без адреса электронной почты
  • пропуск дубликатов (легко, если данные отсортировано).

Если у вас настроена связь с внешним ключом, вам сначала нужно будет выполнить второй шаг (чтобы не было записей о потерях).

Мои два цента: я не знаю, каковы ваши требования, но это выглядит немного чрезмерно нормализованным. Если существует небольшое ограничение на количество адресов электронной почты, я бы рассмотрел добавление нескольких столбцов электронной почты в основную таблицу ... для скорости и простоты.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...