В рамках одного веб-приложения, над которым я работаю, все операции с базой данных абстрагируются с использованием некоторых общих репозиториев, определенных в Entity Framework ORM.
Однако, чтобы иметь простой дизайн для общих репозиториев, все задействованные таблицы должны определять уникальное целое число ( Int32
в C #, int
в SQL). До сих пор это всегда был ПК таблицы, а также IDENTITY
.
Внешние ключи интенсивно используются, и они ссылаются на эти целочисленные столбцы. Они необходимы как для согласованности, так и для генерации навигационных свойств ORM.
Прикладной уровень обычно выполняет следующие операции:
- начальная загрузка данных из таблицы (*) -
SELECT * FROM table
- Обновление -
UPDATE table SET Col1 = Val1 WHERE Id = IdVal
- Удалить -
DELETE FROM table WHERE Id = IdVal
- Вставить -
INSERT INTO table (cols) VALUES (...)
Менее частые операции:
- Массовая вставка - с
BULK INSERT ... into table
последующей (*) загрузкой всех данных (для получения сгенерированных идентификаторов) - Массовое удаление - это обычная операция удаления, но «громоздкая» с точки зрения ORM:
DELETE FROM table where OtherThanIdCol = SomeValue
- Массовое обновление - это обычная операция обновления, но «громоздкая» с точки зрения ORM:
UPDATE table SET SomeCol = SomeVal WHERE OtherThanIdCol = OtherValue
* все небольшие таблицы кэшируются на уровне приложения и почти все SELECTs
не доходят до базы данных. Типичным шаблоном является начальная загрузка и множество INSERT
s, UPDATE
s и DELETE
s.
Исходя из текущего использования приложения, существует очень малая вероятность достижения 100M записей в любой из таблиц.
Вопрос: С точки зрения администратора баз данных, существуют ли серьезные проблемы, с которыми я могу столкнуться, имея такое ограничение дизайна таблицы?
[РЕДАКТИРОВАТЬ]
Прочитав ответы (спасибо за отличную обратную связь) и ссылки на статьи, я чувствую, что должен добавить больше деталей:
Текущая специфика приложения - я не упомянул о текущем веб-приложении, потому что хочу понять, можно ли повторно использовать модель и для других приложений. Тем не менее, мой частный случай - это приложение, которое извлекает много метаданных из DWH. Исходные данные довольно грязные (странным образом денормализованы, имеют некоторые несоответствия, во многих случаях нет естественного идентификатора и т. Д.), И мое приложение генерирует четко разделенные сущности. Также
IDENTITY
отображаются многие из сгенерированных идентификаторов ( ), чтобы пользователь мог использовать их в качестве бизнес-ключей. Это, помимо масштабного рефакторинга кода, исключает использование GUID .«они не должны быть единственным способом однозначно идентифицировать ряд» (Аарон Бертран ♦) - это очень хороший совет. Все мои таблицы также определяют УНИКАЛЬНОЕ ОГРАНИЧЕНИЕ, чтобы гарантировать, что бизнес-дубликаты не допускаются.
Дизайн, ориентированный на внешние приложения, и дизайн, основанный на базе данных - выбор дизайна обусловлен этими факторами
Ограничения Entity Framework - допускается использование нескольких столбцов PK, но их значения не могут быть обновлены
Пользовательские ограничения - наличие единого целочисленного ключа значительно упрощает структуры данных и код, отличный от SQL. Например: все списки значений имеют целочисленную клавишу и отображаемые значения. Что еще более важно, это гарантирует, что любая таблица, помеченная для кэширования, сможет быть помещена в
Unique int key -> value
карту.
Сложные запросы на выборку - это почти никогда не произойдет, потому что данные всех небольших таблиц (<20-30K записей) кэшируются на уровне приложения. Это немного усложняет жизнь при написании кода приложения (сложнее писать LINQ), но база данных гораздо лучше:
Представления списка - не будут генерировать
SELECT
запросы при загрузке (все кэшируется) или запросы, которые выглядят так:SELECT allcolumns FROM BigTable WHERE filter1 IN (val1, val2) AND filter2 IN (val11, val12)
Все остальные необходимые значения выбираются с помощью поиска в кэше (O (1)), поэтому сложные запросы не будут создаваться.
Редактировать представления - сгенерирует
SELECT
утверждения вроде этого:SELECT allcolumns FROM BigTable WHERE PKId = value1
(все фильтры и значения int
s)