Нормализация ваших операционных таблиц, как предлагает Transact Charlie, является хорошей идеей и со временем избавит от многих головных болей и проблем, но есть такие вещи, как интерфейсные таблицы, которые поддерживают интеграцию с внешними системами, и таблицы отчетов , которые поддерживают такие вещи, как аналитика обработки; и эти типы таблиц не обязательно должны быть нормализованы - на самом деле, очень часто это гораздо, гораздо удобнее и эффективнее для них не быть .
В этом случае, я думаю, предложение Transact Charlie для ваших операционных столов является хорошим.
Но я бы добавил индекс (не обязательно уникальный) к CompetitorName в таблице Competitors для поддержки эффективных объединений на CompetitorName в целях интеграции (загрузки данных из внешних источников), и я бы добавил в интерфейс таблицу интерфейсов: CompetitionResults.
CompetitionResults должен содержать любые данные о ваших соревнованиях. Смысл таблицы интерфейса, подобной этой, состоит в том, чтобы максимально быстро и просто обрезать и перезагружать ее из листа Excel, файла CSV или любой другой формы, в которой вы храните эти данные.
Эта интерфейсная таблица не должна рассматриваться как часть нормализованного набора операционных таблиц. Затем вы можете присоединиться к CompetitionResults, как предложено Ричардом, чтобы вставить записи в конкурентов, которые еще не существуют, и обновить те, которые существуют (например, если у вас действительно есть дополнительная информация о конкурентах, например, их номер телефона или адрес электронной почты).
Я хотел бы отметить одну вещь - на самом деле, имя конкурента, как мне кажется, вряд ли будет уникальным в ваших данных . Например, из 200 000 участников у вас может быть 2 или более Дэвида Смита. Поэтому я бы порекомендовал вам собрать больше информации от конкурентов, например, номер телефона или адрес электронной почты, или что-то, что с большей вероятностью будет уникальным.
В вашей операционной таблице «Конкуренты» должен быть только один столбец для каждого элемента данных, который вносит вклад в составной естественный ключ; например, он должен иметь один столбец для основного адреса электронной почты. Но в таблице интерфейса должен быть слот для старых и новых значений для основного адреса электронной почты, чтобы старое значение можно было использовать для поиска записи в конкурентах и обновления этой части до нового значения.
Таким образом, CompetitionResults должны иметь некоторые «старые» и «новые» поля - oldEmail, newEmail, oldPhone, newPhone и т. Д. Таким образом, вы можете сформировать составной ключ в Competitors, от CompetitorName, Email и Phone.
Затем, когда у вас есть результаты соревнований, вы можете обрезать и перезагрузить таблицу CompetitionResults из таблицы Excel или чего-то еще, и запустить одну эффективную вставку, чтобы вставить всех новых конкурентов в таблицу Конкурентов, и одно эффективное обновление для обновления. Вся информация о существующих конкурентах из CompetitionResults. И вы можете сделать одну вставку, чтобы вставить новые строки в таблицу CompetitionCompetitors. Это можно сделать с помощью хранимой процедуры ProcessCompetitionResults, которая может быть выполнена после загрузки таблицы CompetitionResults.
Это своего рода элементарное описание того, что я много раз делал в реальном мире с Oracle Applications, SAP, PeopleSoft и списком других корпоративных программных пакетов.
Последний комментарий, который я хотел бы сделать, - это то, что я сделал ранее для SO: Если вы создаете внешний ключ, который гарантирует, что в таблице «Конкуренты» существует конкурент, прежде чем вы сможете добавить строку с этим «конкурентом» в CompetitionCompetitors, убедитесь, что внешний ключ установлен для каскадного обновления и удаления . Таким образом, если вам нужно удалить конкурента, вы можете сделать это, и все строки, связанные с этим конкурентом, будут автоматически удалены. В противном случае по умолчанию внешний ключ потребует от вас удаления всех связанных строк из CompetitionCompetitors, прежде чем он позволит вам удалить конкурента.
(Некоторые люди думают, что не каскадные внешние ключи - это хорошая мера предосторожности, но мой опыт показывает, что это просто ужасная боль в заднице, которая чаще всего не является результатом недосмотра, и они создают кучу трудовой работы. для администраторов баз данных. Работа с людьми, случайно удаляющими материал, - вот почему у вас есть такие вещи, как диалоги «Вы уверены» и различные типы регулярных резервных копий и избыточных источников данных? Гораздо чаще встречается фактическое желание удалить конкурента, чьи данные все напутал, к примеру, чем это случайно удалить одно и потом сказать: «О, нет! Я не хотел этого делать! А теперь у меня нет результатов их соревнований! А-а-а-а!» Последнее, конечно, достаточно распространено, поэтому Вы должны быть готовы к этому, но первое гораздо более распространено,так что самый простой и лучший способ подготовиться к первому, imo, это просто сделать каскадные обновления и удаления внешних ключей.)
NVARCHAR(64)
столбец вашим первичным (и, следовательно, кластеризованным) ключом !! Прежде всего - это очень широкий ключ - до 128 байт; а во-вторых, это переменный размер - опять же: не оптимально ... Это самый худший из возможных вариантов - ваша производительность будет ужасной, а фрагментация таблиц и индексов будет постоянно на уровне 99,9% .....