БОЛЬШОЙ ВСТАВИТЬ в несколько связанных таблиц? - PullRequest
0 голосов
/ 01 марта 2019

Мне нужно сделать BULK INSERT из нескольких сотен тысяч записей в 3 таблицах.Простая разбивка таблиц будет выглядеть следующим образом:

TableA
--------
TableAID (PK)
TableBID (FK)
TableCID (FK)
Other Columns

TableB
--------
TableBID (PK)
Other Columns

TableC
--------
TableCID (PK)
Other Columns

Проблема с массовой вставкой, конечно, заключается в том, что она работает только с одной таблицей, поэтому FK становится проблемой.

Я искал способы обойти это, и из того, что я почерпнул из различных источников, использование SEQUENCE колонка может быть лучшей ставкой.Я просто хочу убедиться, что я правильно соединил логику из различных тем и постов, которые я прочитал на эту тему.Дайте мне знать, если у меня есть правильная идея.

Сначала изменим таблицы так, чтобы они выглядели так:

TableA
--------
TableAID (PK)
TableBSequence
TableCSequence
Other Columns

TableB
--------
TableBID (PK)
TableBSequence
Other Columns

TableC
--------
TableCID (PK)
TableCSequence
Other Columns

Затем из кода приложения я сделаю пять вызововбаза данных со следующей логикой:

  • Запрос X порядковых номеров из TableC, где X - известное количество записей, которые нужно вставить в TableC.(1-й вызов БД.)

  • Запрос Y порядковых номеров из Таблицы B, где Y - известное количество записей, которые нужно вставить в TableB (2-й вызов БД.)

  • Измените существующие объекты для A, B и C (которые являются моделями, сгенерированными для зеркального отображения таблиц) с известными теперь порядковыми номерами.

  • Массовая вставка в TableA.(3-й вызов БД)

  • Массовая вставка в TableB.(4-й вызов БД)
  • Массовая вставка в TableC.(5-й вызов БД)

И тогда, конечно, мы всегда присоединяемся к Последовательности.

У меня есть три вопроса:

  1. Правильна ли базовая логика?

  2. В таблицах B и C я бы удалил кластеризованный индекс из PK и вставил бы вместо него последовательность?

  3. После того, как порядковые номера запрашиваются из таблиц B и C, они каким-то образом блокируются между запросом и массовой вставкой?Мне просто нужно убедиться, что между запросом и вставкой какой-то другой процесс не запрашивает и не использует те же номера.

Спасибо!

РЕДАКТИРОВАТЬ:

После того, как я набрал это и опубликовал его, я начал читать глубже документ SEQUENCE .Я думаю, что я неправильно понял это сначала.ПОСЛЕДОВАТЕЛЬНОСТЬ не тип столбца.Для фактического столбца в таблице я бы просто использовал INT (или, возможно, BIGINT) в зависимости от количества записей, которые я ожидаю иметь).Фактический объект SEQUENCE - это совершенно отдельный объект, задача которого - генерировать числовые значения по запросу и отслеживать, какие из них уже были сгенерированы.Итак, если я правильно понимаю, я бы сгенерировал два объекта SEQUENCE, один из которых будет использоваться вместе с таблицей B, а другой - таблицей C.

Так что это ответит на мой третий вопрос.

Ответы [ 2 ]

0 голосов
/ 01 марта 2019

Извините, сначала неправильно прочитал ваш вопрос.Теперь я вижу, что вы пытаетесь сгенерировать свои собственные PK, а не позволяете MS SQL генерировать их для вас.Поцарапайте мой комментарий выше.

Как уже упоминал Дэвид Браун, вы можете использовать промежуточный стол, чтобы избежать нагрузки, которую вы возьмете на кучу своего приложения.Используйте tempdb и вносите изменения непосредственно в таблицу, используя одну транзакцию для каждой таблицы.Затем скопируйте промежуточные таблицы к их цели или используйте MERGE, если добавляете.Если вы применяете FK, вы можете временно удалить эти ограничения, если решите вставить их в обратном порядке (C => B => A).Вы также можете рассмотреть возможность временного удаления индексов, если возникают проблемы с производительностью во время вставки.Наконец, рассмотрите возможность использования SSIS вместо пользовательского приложения.

0 голосов
/ 01 марта 2019

Правильна ли базовая логика?

Да.Другим распространенным подходом здесь является массовая загрузка данных в промежуточную таблицу и выполнение чего-то подобного на стороне сервера.

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

В таблицах B и C я бы удалил кластеризованный индекс из PK

Нет, как вы позже заметили, последовательность просто предоставляет значения PKдля вас.

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