Идентификаторы в алмазной взаимосвязи между таблицами - PullRequest
0 голосов
/ 10 декабря 2008

У меня есть четыре таблицы (A, B, C, D), где A является родителем отношений один-ко-многим с B и C. C и D являются родителями отношения один-ко-многим с таблицей D. Концептуально, основной ключи этих таблиц могут быть:

  • A: Помощь
  • B: Помощь, bnum (с внешним ключом к A)
  • C: Помощь, cnum (с внешним ключом к A)
  • D: Aid, bnum, cnum (с внешними ключами к B и C)

Где столбцы 'num' автоматически увеличиваются на основе каждого родительского идентификатора в отношении, а не на каждой записи. Я использовал этот подход в предыдущем приложении, и это не было проблемой, поскольку создание записей B и C выполнялось последовательным процессом путем генерации нового значения 'num' с помощью запроса 'select max ()'. Я никогда не был действительно удовлетворен подходом, но это сделало работу.

Для конкретного случая, над которым я сейчас работаю, записи в таблицах A и B вводятся пользователями, поэтому автоматическая генерация идентификаторов не является проблемой. В случае таблиц C и D записи в этих таблицах генерируются несколькими параллельными пакетными процессами, поэтому их идентификаторы должны быть сгенерированы каким-либо образом. Предыдущий метод, который я перечислил, не работает в зависимости от состояния гонки.

Обратите внимание, что это для базы данных Oracle, поэтому я буду использовать последовательности, а не столбцы с автоинкрементом.

Учитывая приведенные выше ограничения, как бы вы разработали таблицы для представления A, B, C и D так, чтобы отношения между сущностями были должным образом применены И для создания идентификаторов не требовался код приложения?

Ответы [ 2 ]

0 голосов
/ 11 декабря 2008

Если я правильно понимаю, у вас было решение, в котором у вас может быть

Table A
-------
100
101
102

Table B
-------
100 1
100 2
101 1

Table C
-------
100 1
100 2
101 1


Table D
-------
100 1 1
100 2 1
100 1 2
101 1 1

и т.д.

Теперь, имеет ли значение, являются ли значения 'num' маленькими и в последовательности без пропусков? Если нет, то просто используйте последовательности для них тоже. Таким образом, вы можете получить

Table B
-------
100 29125
100 29138
101 29130

Table D
-------
100 29125 401907
100 29138 404911
101 29130 803888

Я бы использовал отдельные последовательности для bnum и cnum. При выборе вы можете (при желании) использовать что-то вроде

SELECT AID, 
      RANK(BNUM) OVER (PARTITION BY AID ORDER BY BNUM) bnum_seq,
      RANK(CNUM) OVER (PARTITION BY AID ORDER BY CNUM) cnum_seq
0 голосов
/ 10 декабря 2008

Последовательности или Autonumbers должны всегда генерироваться системой базы данных, а не приложением. Для MSSQL это можно сделать с помощью хранимой процедуры и возврата «select @@ identity» из хранимой процедуры, чтобы дать приложению идентификатор вставленной строки.

Последовательности отлично подходят для первичных ключей, но есть лагеря, которые поклоняются богу «естественных ключей».

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

Лично я бы сделал последовательности первичных ключей в каждой таблице и учел бы внешние ключи, которые не являются частью первичного ключа. Вы определяете свои таблицы по основным объектам (таким как сотрудник, товар, магазин), и тогда отношения между ними будут состоять из комбинаций. Таким образом, у сотрудника в магазине будет таблица «storeemployee», и первичный ключ будет empid , storeid без определенной последовательности. Обычно я думаю об этом с точки зрения вещей как объектов (которые всегда имеют последовательности для первичных ключей) и отношений между объектами (с использованием идентификаторов других таблиц в качестве комбинированных первичных ключей).

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

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

...