Я работаю над многопользовательским веб-сайтом на базе интернет-баз данных с SQL Server 2008 / LinqToSQL / пользовательскими репозиториями в качестве DAL. Я столкнулся с проблемой нормализации, которая может привести к несогласованному состоянию базы данных, если эксплуатируется правильно, и мне интересно, как решить эту проблему.
Проблема: несколько разных компаний имеют доступ к моему веб-сайту. Они должны иметь возможность отслеживать свои проекты и клиентов на моем сайте. Некоторые (но не все) проекты должны быть назначены клиентам.
В результате получается следующая схема базы данных:
**Companies:**
ID
CompanyName
**Clients:**
ID
CompanyID (not nullable)
FirstName
LastName
**Projects:**
ID
CompanyID (not nullable)
ClientID (nullable)
ProjectName
Это приводит к следующим отношениям:
Companies-Clients (1:n)
Companies-Projects (1:n)
Clients-Projects(1:n)
Теперь, если пользователь злонамеренный, он может, например, вставить проект со своим собственным CompanyID, но с ClientID, принадлежащим другому пользователю, оставив базу данных в несогласованном состоянии.
Проблема возникает аналогичным образом по всей схеме базы данных, поэтому я хотел бы решить эту проблему в общем виде, если это возможно. У меня были следующие две идеи:
Проверка записи в базу данных, которая может привести к несоответствиям в DAL. Это было бы общим, но требует некоторых дополнительных запросов к базе данных перед выполнением обновлений и запросов на создание, поэтому это приведет к снижению производительности.
Создайте дополнительную таблицу для отношений клиенты-проекты и убедитесь, что отношения, созданные таким образом, являются согласованными. Это также требует некоторых дополнительных запросов выбора, но гораздо меньше, чем в первом случае. С другой стороны, он не является универсальным, поэтому в долгосрочной перспективе легче что-то упустить, особенно при добавлении большего количества таблиц / зависимостей в базу данных.
Что бы вы сделали? Есть ли лучшее решение, которое я пропустил?
Редактировать: Вы можете удивиться, почему в таблице Projects указан CompanyID. Это потому, что я хочу, чтобы пользователи могли добавлять проекты с клиентами и без клиентов. Мне нужно отслеживать, к какой компании (и, следовательно, к какому пользователю сайта) относится безлимитный проект, поэтому для проекта нужен идентификатор компании.