Нормализация базы данных для инструмента учета рабочего времени и обеспечения целостности данных - PullRequest
1 голос
/ 01 марта 2010

Я создаю приложение расписания. У меня есть следующие лица (среди прочих):

  • Компания
  • Сотрудник = сотрудник, связанный с компанией
  • Клиент = клиент, связанный с компанией

Пока у меня есть следующая (сокращенная) настройка базы данных:

Company
 - id  
 - name

Employee
 - id  
 - companyId (FK to Company.id)  
 - name

Client
 - id  
 - companyId (FK to Company.id)  
 - name

Теперь я хочу, чтобы сотрудник был связан с клиентом, но только , если этот клиент связан с компанией, в которой работает сотрудник. Как бы вы гарантировали целостность данных на уровне базы данных? Или я должен просто зависеть от приложения, чтобы гарантировать целостность данных?

Я думал о создании таблицы «многие ко многим» следующим образом:

EmployeeClient  
 - employeeId (FK to Employee.id)  
 - companyId  \  (combined FK to Client.companyId, Client.id)
 - clientId   /  

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

UPDATE
Сценарий выглядит следующим образом:

  • В компании несколько сотрудников. Сотрудники будут связаны только с одной компанией.
  • Компания также имеет несколько клиентов. Клиенты будут связаны только с одной компанией.

    (Компания, так сказать, песочница).

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

Другими словами:
Приложение позволит компании создавать / добавлять сотрудников и создавать / добавлять клиентов (следовательно, companyId FK в таблицах Employee и Client). Затем компании будет разрешено назначать определенных клиентов некоторым своим сотрудникам (таблица EmployeeClient).

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

Ответы [ 2 ]

0 голосов
/ 01 марта 2010

(Это не ответ, но он не совсем подходит как комментарий к вопросу.)

Данные, представленные для вашего вопроса о дизайне, задают ряд вопросов:

  • Должны ли сотрудники быть связаны с компаниями и клиентами? Или ...
  • Связаны ли сотрудники только с клиентами, и (таким образом) ли компания связана с этим клиентом?
  • Если сотрудники и клиенты связаны с компаниями, является ли сотрудник таким образом связанным со всеми сотрудниками этой компании, или вы должны выбирать?

Обновление

Что касается моделирования данных, кажется, что все, что вам нужно, это расширить внешний ключ EmployeeClient в Employee следующим образом:

EmployeeClient
 - companyId
 - employeeId
 - clientId

Составной первичный ключ во всех трех столбцах.

Внешний ключ (companyId, clientId) в клиенте
Внешний ключ ( companyId , employeeId) в Employee

Таким образом, все отношения, определенные в EmployeeClient, требуют, чтобы и Клиент, и Сотрудник имели один и тот же идентификатор клиента.

0 голосов
/ 01 марта 2010

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

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

...