создать внешний ключ, используя более двух таблиц - PullRequest
0 голосов
/ 05 октября 2011

У меня есть следующие таблицы.

система таблиц

  • sys_id
  • имя

основной (sys_id)

запросы таблицы

  • sys_id
  • request_id
  • субъект

основной(sys_id, request_id)внешний ключ запросы.sys_id -> system.sys_id

поле таблицы

  • sys_id
  • field_id
  • name

основной (sys_id, field_id)внешний ключ field.sys_id -> system.sys_id

таблица запросов_props

  • sys_id
  • request_id
  • field_id
  • field_value

primary (sys_id, request_id, field_id)внешний ключ questions_props (sys_id, request_id) -> запросы (sys_id, request_id)


До этого момента все было хорошо.Поэтому здесь я могу

  1. создать систему с определенным sys_id (в табличной системе)
  2. создать некоторые поля (свойства) в этой системе (в полях таблицы)
  3. добавить запрос в систему (в табличных запросах)
  4. установить значения полей (свойства) для каждого запроса, соответствующего field_ids этой системы.(в таблице reports_props)

Теперь я хочу создать набор для черновых запросов.Таким образом, каждый запрос может иметь несколько черновиков для него.Черновики - это не что иное, как временные запросы.Поэтому я выбрал следующую схему

черновики таблиц

  • draft_id
  • sys_id
  • request_id

основной (draft_id)черновики внешнего ключа (sys_id, request_id) -> запросы (sys_id, request_id)

таблица drafts_props

  • draft_id
  • field_id
  • field_value

primary (draft_id, field_id)внешний ключ drafts_props (draft_id) -> черновики (draft_id) внешний ключ ??????????между drafts_props и таблицей полей ??????????????

здесь я хочу создать отношение внешнего ключа между таблицей * drafts_props * до таблица полей , где я могу убедиться, что * drafts_props * имеет тот же * field_id *, который разрешен ассоциацией * draft_id's * между таблицей drafts и таблицей * drafts_props * и * sys_id* связанный с этим черновиком.

то есть, чтобы найти действительные field_ids, которые могут быть в таблице drafts_props, мне сначала нужно соединить таблицу drafts_props с таблицей drafts на drafts_id и найти связанный sys_id с этим черновиком, а затем найтиfield_ids, связанный с этим sys_id в таблице полей.Это даст мне действительные значения field_ids.

, но, насколько я знаю, я не могу использовать 3 таблицы для создания ограничения внешнего ключа.внешний ключ [drafts_props]. [draft_id], [drafts]. [sys_id] ссылки [fields]. [sys_id], [fields]. [field_id]

конечно, я могу включить столбец sys_id в таблицу drafts_propsтакже, чтобы я мог создать такое ограничение, но я не хочу создавать эту избыточность.Также я не могу изменить систему таблиц, запросы, request_props и поля.

заранее спасибо!

Ответы [ 2 ]

3 голосов
/ 05 октября 2011

Проблема включения sys_id в drafts_props не в том, что он займет физическое пространство (что и будет, но это не проблема). Проблема в том, что вы можете получить строку drafts_props, которая ссылается на drafts с одним sys_id, в то же время имея другой sys_id.

Это должно быть законно?

  1. f да, просто включите sys_id в drafts_props, вне его PK.
  2. Если нет, вам нужно изменить модель базы данных, чтобы sys_id естественным образом распространял идентификационную связь и становился частью первичного ключа drafts_props. Примерно так:

    drafts (
        draft_id PK
        sys_id PK
        request_id
        FK (sys_id, request_id) -> requests
    )
    
    drafts_props (
        draft_id PK
        sys_id PK
        field_id PK
        field_value
        FK (draft_id, sys_id) -> drafts
        FK (sys_id, field_id) -> field
    )
    

Дополнительные предложения:

  • Возможно, вы также захотите рассмотреть порядок полей в некоторых из ваших первичных ключей (т. Е. Вы можете поставить sys_id на первое место, в зависимости от типичных шаблонов запросов).
  • Если вас беспокоит физическое пространство хранения, некоторые СУБД (я знаю Oracle, возможно, другие тоже) могут довольно эффективно сжимать составные индексы, которые содержат много повторений (например, предположительно, sys_id в вашем случае). Некоторые могут даже сжать данные таблицы.
0 голосов
/ 05 октября 2011

enter image description here

...