2009-11-03 3 views
0

Вопрос базы данных SQL Server 2008.SQL Table Design - Identity Columns

У меня есть 2 таблицы для аргументов ради клиентов и пользователей, где один клиент может иметь от 1 до n пользователей. Таблица Customers генерирует CustomerId, который является засеянным идентификатором с добавлением +1 к нему. То, что мне нужно в таблице «Пользователи», представляет собой составной ключ, содержащий CustomerId и порядковый номер, так что во всех случаях первый пользователь имеет последовательность из 1, а последующие пользователи добавляются в x + 1.

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

  • CustomerId (PK, FK)
  • UserId (PK)
  • Имя

... и если, например, У клиента 485 было три клиента, данные будут похожи на ...

CustomerId | UserId | Name 
---------- 
    485 | 1 | John 
    485 | 2 | Mark 
    485 | 3 | Luke 

Я понимаю, что я могу вручную добавить запись 1,2,3, ..., n для UserId, но я хотел бы, чтобы это произошло автоматически при вставке строки в SQL, так что в показанном примере я мог бы эффективно вставлять строки с CustomerId и именем с SQL Server, защищающим идентификатор и т. д. Есть ли способ сделать это через сам проект базы данных - когда я устанавливаю UserId как идентификатор, он работает от 1 до бесконечности для всех клиентов, что не то, что я ищу для - у меня что-то не получается, или это не вариант?

Надежда, что имеет смысл - спасибо за вашу помощь

+0

Я в замешательстве. Вы хотите, чтобы столбец IDENTITY автоматически увеличивался каждый раз, когда вы вставляете строку? –

+0

В таблице «Пользователи» да, но всегда нужно посеять 1 для каждого другого клиента. Если я устанавливаю UserId в качестве столбца Identity (как часть составного ключа с CustomerId), он, кажется, увеличивается до бесконечности. Извините, мне сложно это объяснить! – Chris

ответ

4

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

Тем не менее, это пахнет мне от Натурализация суррогата ключ - это не всегда хорошая идея.

Больше информации здесь:

http://www.agiledata.org/essays/keys.html

+0

Спасибо. Его единственная роль - обеспечить повторение - поскольку это многопользовательская система (с точки зрения использования интерфейса), я не хочу пытаться блокировать вещи для вставки, если мне приходится вручную ее обрабатывать. – Chris

+0

Ударьте меня, заявив, что это плохая идея. :-) Кроме того, предоставлена ​​ссылка с фоновой информацией (+1). Добавьте предлагаемый альтернативный подход, и вы золотой! – cethegeek

1

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

Наименьшим способом сделать это будет то, что триггер отобразит максимальный идентификатор пользователя из таблицы пользователей для идентификатора клиента на вставленной записи, а затем добавит его к этому. Тем не менее, вы столкнетесь с проблемами параллелизма там, если несколько человек одновременно создают запись пользователя.

Лучшим решением будет иметь столбец NextUserID в таблице клиентов. В вашем триггере вы:

  1. Начните сделку.
  2. Инкремент NextUserID для клиента (блокировка строки).
  3. Выберите обновленный идентификатор следующего пользователя.
  4. используйте это для новой записи пользователя.
  5. совершите транзакцию.

Это должно гарантировать, что одновременное добавление пользователей не приведет к тому, что один и тот же идентификатор пользователя используется более одного раза.

Все, что сказал, я бы рекомендовал вам просто не делать этого. Это больше неприятностей, чем это стоит, и просто пахнет плохими идеями.

+0

Спасибо за это, я был на нем до последнего абзаца, который, как я думаю, бьет по деньгам - время для переосмысления. – Chris

1

Итак, вы хотите сгенерированное поле user_id, которое увеличивается в пределах customer_id.

Я не могу думать о одной базе данных, где существует эта концепция.

Вы можете реализовать его с помощью триггера. Но мой вопрос: ПОЧЕМУ?

Суррогатные ключи не должны иметь никакого значения. Почему вы пытаетесь сделать ключ, который одновременно является суррогатом и подразумевает порядок?

Мои предложения:

  1. Создать DATE_CREATED поле, по умолчанию GetDate(). Это позволит вам узнать порядок (время), в котором был создан каждый user_id.

  2. Создайте порядковое поле, которое можно обновить с помощью триггера, чтобы поддерживать этот порядок.

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

+0

Спасибо - время пересмотреть мой подход, я думаю! – Chris

+0

Нет проблем. Я действительно думаю, что поле date_created сделает трюк ... – cethegeek