Столбец идентификации как часть первичного ключа - PullRequest
1 голос
/ 21 января 2020

Предположим, у меня есть составной первичный ключ, который состоит из 3 столбцов: [ShardKey], [SiteId] и [ServiceId]. Столбец [ServiceId] является столбцом идентификаторов и должен начинаться с 1 для новой комбинации [ShardKey] и [SiteId], но сервер SQL не работает - столбец [ServiceId] никогда не начинается с 1, он просто увеличивает свое значение независимо от значения что такое первичный ключ Я добавил ограничение для первичного ключа, который содержит все три столбца. Что я должен сделать, чтобы он начинался с 1, когда появляется новая комбинация [ShardKey] и [SiteId]?

[ShardKey] [SiteId] [ServiceId]   [Name]
  1009        1         1         Coffee
  1009        1         2         Tea
  1009        1         3         Cocaine

  1009        2         1         Coffee
  1009        2         2         Tea
  1009        2         3         Cocaine

  1010        1         1         Coffee
  1010        1         2         Tea
  1010        1         3         Cocaine

Это то, что я хочу, чтобы сервер SQL сделал для меня. Значения для [ShardKey] и [SiteId] мне известны, поэтому я всегда могу вставить их в скрипт SQL, но мне нужно, чтобы столбец [ServiceId] начинался с 1 для новой комбинации [ShardKey] и [SiteId]

Ответы [ 2 ]

3 голосов
/ 21 января 2020

Короткий ответ: «Нет, IDENTITY здесь вам ничем не поможет» - IDENTITY для каждой таблицы, а не для уникальных других первичных ключей. Итак: вам придется справиться с этим самостоятельно (предположительно, проверяя максимум ServiceId для этой перестановки), но затем вы попадаете в сложный сценарий состояния гонки ios. Это также делает вставку очень сложной и менее эффективной, поскольку теперь вы делаете select непосредственно перед insert - главным кандидатом для взаимоблокировки на некоторых уровнях изоляции (так что начальный select должен быть UPDLOCK). Тот факт, что первичный ключ будет уникальным, поможет избежать некоторых из более очевидных проблем, но вы все равно можете столкнуться с проблемами, если сделаете предположения о значении, которое вы собираетесь вставить до , когда вы полностью вставил его, или если вы явно не ожидаете, что insert потерпит неудачу.

1 голос
/ 21 января 2020

столбцы IDENTITY не зависят от других столбцов. Кроме того, вы пытаетесь извлечь столбец ServiceID из входящих значений SharedKey, SiteId, а не из существующих значений таблицы.

У вас есть несколько вариантов:

  • , вам нужно определить триггер INSTEAD OF INSERT для обработки этого сценария. Вы должны увидеть, присутствуют ли входящие значения SharedKey, SiteId. Если это так, используйте существующий ServiceId. В противном случае создайте новый.

  • Вы должны иметь этот лог c как часть хранимой процедуры вставки. Вы должны увидеть, присутствуют ли входящие параметры: Sharedkey, SiteId. Если это так, используйте существующий ServiceId. в противном случае создайте новый и вставьте в таблицу.

CAVEAT:

  • Использование триггеров сделает транзакцию более длинной и будет влиять на параллелизм и аналогичным образом, проверка существующих значений в таблице и поиск нового ServiceId сделает транзакцию более длинной.
  • Для хранимых процедур также необходимо позаботиться об аспектах параллелизма (УРОВНИ ИЗОЛЯЦИИ), чтобы что ваш сгенерированный serviceID не создает конфликт первичного ключа. этот тип настройки УРОВНЯ ИЗОЛЯЦИИ также будет влиять на параллелизм.

ИМХО, предлагая вам следующие изменения дизайна:

  • Не до go для этого типа получения столбцов. Составные ключевые составляющие должны быть независимы друг от друга.
  • Вы можете создать суррогатный ключ и использовать эти столбцы как внешние ключи из соответствующих таблиц. Узкие кластерные ключи дают хорошую производительность по сравнению с композитными ключами.
  • Пересмотрите нормализацию и создайте отдельные независимые таблицы и создайте таблицу мостов для обработки такого рода отношения многие-многие
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...