невозможно обеспечить ссылочную целостность в Access - PullRequest
1 голос
/ 14 июня 2009

Я проверил все на наличие ошибок: первичный ключ, уникальность и тип. Кажется, что Access просто не может связать 2 поля, которые у меня есть в моей базе данных. Может кто-нибудь, пожалуйста, посмотрите?

http://www.jpegtown.com/pictures/jf5WKxKRqehz.jpg

Спасибо.

Ответы [ 5 ]

7 голосов
/ 15 июня 2009

Ваша диаграмма отношений показывает, что вы сделали поля идентификаторов первичным ключом во всех ваших таблицах, но не используете их для своих объединений. Таким образом, они не служат абсолютно никакой цели. Если вы не собираетесь использовать «суррогатные ключи» (т. Е. Бессмысленный идентификационный номер, который генерируется базой данных и является уникальным для каждой записи, но не имеет абсолютно никакого значения в отношении данных в вашей таблице), то удалите их , Но если вы собираетесь использовать «естественные ключи» (т. Е. Первичный ключ, составленный из набора полей реальных данных, которые вместе будут уникальными для каждой записи), у вас должен быть уникальный составной индекс для этих полей.

Однако существуют проблемы с обоими подходами:

  1. Суррогатные ключи: суррогатный ПК делает каждую запись уникальной. То есть у вас может быть запись для Дэвида Фентона с идентификатором 1 и запись для Дэвида Фентона с идентификатором 2. Если это тот же Дэвид Фентон, у вас есть дубликаты данных, но, насколько известно вашей базе данных, они уникальны.

  2. Натуральные ключи: некоторые типы сущностей очень хорошо работают с натуральными ключами. Лучше всего, когда есть одно поле, однозначно идентифицирующее запись. Примером может быть «тип сотрудника», где значениями могут быть «сотрудник, менеджер и т. Д.» В этом случае это очень хороший кандидат для использования естественного ключа вместо добавления суррогатного ключа. Единственный аргумент против естественного ключа в этом случае состоит в том, что данные в естественном ключе кандидата очень изменчивы (то есть часто меняются). Хотя каждый современный механизм базы данных обеспечивает функциональность «CASCADE UPDATE» (т. Е. Если значение в поле PK изменяется, все таблицы, для которых это поле является внешним ключом, автоматически обновляются), это накладывает определенные накладные расходы и может вызвать проблемы. Для ключей с одним столбцом это вряд ли является проблемой. Теперь, кроме таблиц поиска, существует очень мало сущностей, для которых естественным ключом будет один столбец. Вместо этого вы должны создать составной индекс, то есть индекс, который охватывает несколько полей данных. В диалоговом окне индекса в дизайне таблицы Access вы создаете составной ключ, присваивая ему имя в первом столбце, а затем добавляете несколько строк во втором столбце (из раскрывающегося списка полей в вашей таблице). Недостатком этого является то, что если какие-либо поля в вашем составном уникальном индексе неизвестны, вы не получите уникальность. То есть, если поле имеет значение Null в двух записях, а остальные поля идентичны, это не будет считаться конфликтом уникальности, поскольку значение Null никогда не равно Null. Это потому, что Null не означает «пустой» - это означает «Неизвестный».

Аллен Браун объяснил все, что вам нужно знать о Nulls:

На графике показано, что вы пытаетесь связать таблицу Company с таблицей PManager. Последняя таблица имеет поле CompanyID, а ваша таблица Company имеет уникальный индекс для своего поля ID, поэтому все, что вам нужно, - это ссылка из поля ID таблицы Company в поле CompanyID таблицы PManager. Чтобы ваш пример работал (что было бы бесполезно, поскольку у вас уже есть уникальный индекс в поле идентификатора), вам нужно создать уникальный составной ключ, охватывающий как ID, так и ShortName в таблице Company.

Кроме того, если ShortName является полем, которое вы хотите быть уникальным (т. Е. Вы не хотите, чтобы две записи компании имели одинаковое ShortName), вам следует добавить уникальный индекс к нему, независимо от того, используете ли вы по-прежнему Поле идентификатора в качестве вашего первичного ключа. Это возвращает меня к пункту № 1 выше, где я описал ситуацию, когда суррогатный ключ может привести вас к вводу дублирующих записей, потому что уникальность устанавливается суррогатным ключом вместе. Каждый раз, когда вы решите использовать суррогатный ключ, вы также должны добавить уникальный составной индекс для любой комбинации полей данных, которая должна быть уникальной (с предупреждением о пустых полях, как описано в пункте № 2).

Если вы думаете, что «суррогатные ключи означают больше индексов», вы правы в том, что у вас есть два уникальных индекса в одной таблице (при условии, что у вас нет проблемы с нулем). Но вы получаете существенную простоту использования при объединении таблиц в SQL, а также значительно меньшее дублирование данных. Кроме того, вы избегаете накладных расходов на CASCADE UPDATE. С другой стороны, если вы просматриваете дочернюю таблицу с естественным внешним ключом, вам не нужно присоединяться к родительской таблице, чтобы иметь возможность идентифицировать родительскую запись, потому что данные, которые идентифицируют эту запись, прямо в поля внешнего ключа. Отсутствие необходимости в объединении может привести к значительному увеличению производительности в определенных сценариях (особенно в случае, когда вам требуется внешнее объединение, поскольку внешний ключ может иметь значение Null).

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

Надеюсь, это поможет.

5 голосов
/ 14 июня 2009

На самом деле вам нужен индекс для полей имени, с обеих сторон

Однако могу ли я предложить, что у вас слишком много объединений? В общем случае должно быть только одно соединение из одной таблицы в другую. Редко иметь более одного объединения между таблицами, и чрезвычайно редко иметь более двух.

Посмотрите на эту ссылку: http://weblogs.asp.net/scottgu/archive/2006/07/12/Tip_2F00_Trick_3A00_-Online-Database-Schema-Samples-Library.aspx

Обратите внимание, как все таблицы объединены в одно отношение?

Каждое из полей, помеченных PK, является первичными ключами. Это AUTONUMBER поля. Каждое из полей, помеченных как FK, являются внешними ключами. Это индексированные числовые поля типа Integer. Первичные ключи связаны с внешними ключами в соотношении 1: 1 (в большинстве случаев).

В 99% случаев вам не понадобятся другие виды соединений. Хитрость заключается в создании таблиц с уникальной информацией. В вашей базе данных много повторяющейся информации.

База данных, которая реорганизована таким образом, называется «нормализованной» базой данных. Есть много хороших примеров на http://www.databaseanswers.org/data_models/

0 голосов
/ 30 сентября 2014

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

  1. Я экспортировал данные из обеих таблиц в Access to Excel. Таблица 1 содержит код Cust и основную информацию о компании. Код Cust в качестве первичного ключа.

  2. Таблица2 содержала всю информацию о том, кто клиенты, связанные с этой компанией.

  3. Я удалил все дубликаты из таблицы 2, экспортированные в Excel.

  4. Используя Vlookup я проверил и обнаружил, что есть 11 код клиента отсутствует в таблице 1.

  5. Я добавил эти коды в таблицу доступа. Я связан Ссылочная целостность и проблема была решена.

Также ищите внешний ключ, если он не работает.

0 голосов
/ 15 июня 2009

Просто присоединитесь к CompanyID. Вы также можете избавиться от поля «Компания» в PManager.

0 голосов
/ 14 июня 2009

Вам необходимо создать ИНДЕКС. Возможно, найдите какую-нибудь кнопку создания индекса и создайте индекс по CompanyID

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...