2013-07-17 3 views
0

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

Рассмотрите наличие двух объектов «Предмет» и «Процесс», имеющих определенные атрибуты. Каждый «Предмет» может быть связан с несколькими «Процессами». В зависимости от выбора «Процесс» существует различное количество объектов «Process-Property». Другими словами, когда Пользователь связывает «процесс» с «субъектом», он должен только иметь возможность редактировать связанные с ним «свойства».

В конце концов я хочу, чтобы пользователь мог сделать 3 вещи:

  1. Создание новых «Процессы» и конкретизирующие «Свойства» asscociated с ним
  2. Список всех «Процессы» определенного «Subject "даже если нет„Свойства“, связанные с ним
  3. Associate„процесс“с„Subject“и разрешить только предопределенные„Свойства“, чтобы быть оценены

Так конструкция стола должна быть что-то вроде:

  • tblSubject = {SubjectID, ...}
  • tblProcess = {ProcessID, ...}
  • tblProcessProperty = {PropertyID, ...}
  • tblRelationProcessProperty = {RelationProcessPropertyID, ProcessID, PropertyID}
  • tblRelationSubjectProcessProperty = {RelationID, RelationProcessPropertyID, SubjectID, PropertyValue}

Это делает, очевидно, работайте до тех пор, пока существует «Свойство», связанное с каждым «Процессом». Поэтому моя ошибка заключается не в том, чтобы напрямую связывать «Subject» с «Process», но тогда я не могу получить дизайн стола прямо.

Любая помощь приветствуется.

+0

Что значит, вы не можете получить дизайн стола прямо? –

+0

То, как я структурировал свои таблицы, не предоставляет мне необходимую мне функциональность. Это должно быть что-то вроде: Назначить «Процесс» «Субъекту». Если «Процесс» имеет «Свойства», назначьте их также «Субъекту». – JonBlumfeld

ответ

1

Мне кажется, что вы пытаетесь реализовать своего рода дизайн EAV (Entity-Attribue-Value).

Ваш стол выглядит нормально, но этот дизайн по своей сути требует сложного SQL.

Существуют разные способы сделать это, но на основе ваших рассказов выше я бы пошел с чем-то подобным.

Subject --< Process --<RelationshipProcessProperty>-- Property 

Ваше имущество будет просто выглядеть следующим образом:

"Property" 
    PK PropertyId 
    Name 

Ваш RelationshipProcessProperty может выглядеть следующим образом:

"RelationshiipProcessProperty" 
    PK RelationshipProcessProperty 
    FK Process 
    FK Property 
    Value 

Ваш SQL, где это будет получить сложнее. Выполнение такого «общего» дизайна, как это, имеет свои последствия, поскольку вы ищете несколько значений в одной таблице.

; with Property1 as(
    SELECT 
    proc.Id as ProcessId, 
    prop.Name, 
    rrp.Value 
    FROM Subject s 
    LEFT JOIN Process proc 
    ON s.SubjectId = proc.SubjectId 
    LEFT JOIN RelationshipProcessProperty rpp 
    on proc.ProcessId = rpp.ProcessId 
    LEFT JOIN Property prop 
    on rpp.PropertyId = prop.PropertyId 
    WHERE 
    s.Name = "Subject1" 
    AND 
    proc.Name = "Process1" 
    AND 
    prop.Name = "Property1" 
    ) 

    , Property2 as(
    SELECT 
    proc.Id as ProcessId, 
    prop.Name, 
    rrp.Value 
    FROM Subject s 
    LEFT JOIN Process proc 
    ON s.SubjectId = proc.SubjectId 
    LEFT JOIN RelationshipProcessProperty rpp 
    on proc.ProcessId = rpp.ProcessId 
    LEFT JOIN Property prop 
    on rpp.PropertyId = prop.PropertyId 
    WHERE 
    s.Name = "Subject1" 
    AND 
    proc.Name = "Process1" 
    AND 
    prop.Name = "Property2" 
    ) 

    SELECT 
    p1.Name, 
    p1.Value, 
    p2.Name, 
    p2.Value 
    FROM 
    Property1 p1 
    LEFT JOIN Property2 p2 
    on p1.ProcessId = p2.ProcessId 

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

Для того, чтобы иметь определенные свойства для указанного процесса, вам нужно будет создать Тип процесса Таблица:

"ProcessType" 
    PK ProcessType 
    Type 

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

"EligibleProcessProperties" 
    PK EligibleprocessPropertiesId 
    FK ProcessType 
    Fk Property 

Тогда, чтобы узнать все доступные свойства для этого типа процесса, вы бы относительно простой запрос

SELECT 
    p.Name 
    FROM 
    ProcessType pt 
    LEFT JOIN EligibleProcessProperties epp 
    on pt.ProcessTypeId = epp.ProcessTypeId 
    LEFT JOIN Property p 
    on epp.PropertyId = p.PropertyId 
    WHERE 
    pt.Type = "Type1" 

Я думать, что это своего рода вещь, которую вы ищете для (хотя я мог быть полностью выключен). Если это то, что вы ищете, есть действительно хорошая статья here, которая дает хорошие очки.

Кроме того, у меня почти 100% есть лучшие способы сделать мой длинный ', с' запросом, - но это все, что я знаю. Надеюсь, кто-то другой может обеспечить лучший. Дело в том, что с этой конструкцией вам будет так или иначе нужны суб-запросы.

+0

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

+0

Ага не беспокоится, я просто надеюсь, что это то, что вы ищете, и я не отправил вас по неправильному пути. Пожалуйста, проголосуйте за меня, если вы обнаружите, что это полезно - с конкуренцией с некоторыми коллегами на работе. :) –

1

Если у вас уже есть представление о том, что вы хотите хранить в схеме, хорошая стратегия для создания самой схемы является:

  1. Нарисуйте ваши требования, как ER-диаграмма (https://en.wikipedia.org/wiki/Entity%E2%80%93relationship_model)
  2. Перевести диаграмма в SQL схеме
  3. при необходимости ввести в 3-й нормальной форме (http://en.wikipedia.org/wiki/Database_normalization)

в вашем случае, на шаге 1 вы должны иметь что-то вроде

______  ___________   _______  _____ ____________ 
| Subj. |____/ associated \_______| Proc. |___/ has \__| Proc.prop. | 
|_______| \____________/  |_______| \_____/ |____________| 

Если у вас есть разные типы процессов, вы можете подумать об специализации объекта Process. Если вы действительно хотите выбрать конкретные свойства процесса для каждого процесса, вы должны, вероятно, сделать -связью мощности m: n.

В ER-диаграмме проверка действительности (ваш 3-й элемент) не может быть выполнена, даже если у вас были другие отношения. В схеме SQL вы можете использовать контрольные ограничения для обеспечения этого, или пусть приложение обрабатывает валидность перед вставкой новых процессов.

+0

Фактическая загрузка E-R-диаграммы была бы лучшей идеей. Я сделаю это в следующий раз, спасибо. Похоже, мне придется закодировать решение ... – JonBlumfeld

Смежные вопросы