Могут ли быть ограничения с тем же именем в БД?

Это дополнительный вопрос из того, который я задал здесь.

Могут ли ограничения в БД иметь одно и то же имя?

Скажи, что у меня есть:

CREATE TABLE Employer
(
    EmployerCode    VARCHAR(20)    PRIMARY KEY,
    Address         VARCHAR(100)   NULL
)


CREATE TABLE Employee
(
    EmployeeID      INT            PRIMARY KEY,
    EmployerCode    VARCHAR(20)    NOT NULL,
    CONSTRAINT employer_code_fk FOREIGN KEY (EmployerCode) REFERENCES Employer
)


CREATE TABLE BankAccount
(
    BankAccountID   INT            PRIMARY KEY,
    EmployerCode    VARCHAR(20)    NOT NULL,
    Amount          MONEY          NOT NULL,
    CONSTRAINT employer_code_fk FOREIGN KEY (EmployerCode) REFERENCES Employer
)

Это допустимо? Зависит ли это от СУБД (я на SQL Server 2005)? Если это недопустимо, есть ли у кого-нибудь предложения о том, как обойти это?

6 ответов

Решение

Нет - ограничение также является объектом базы данных, поэтому его имя должно быть уникальным.

Попробуйте добавить, например, имя таблицы в ваше ограничение, чтобы оно было уникальным.

CREATE TABLE BankAccount
(
    BankAccountID   INT            PRIMARY KEY,
    EmployerCode    VARCHAR(20)    NOT NULL,
    Amount          MONEY          NOT NULL,
    CONSTRAINT FK_BankAccount_Employer 
        FOREIGN KEY (EmployerCode) REFERENCES Employer
)

Мы в основном используем "FK_"(дочерняя таблица)_(родительская таблица)"для именования ограничений и вполне довольны этим соглашением об именах.

Информация из MSDN

То, что имена ограничений должны быть уникальными для схемы (т. Е. Две разные схемы в одной и той же базе данных могут содержать ограничение с одним и тем же именем), явно не задокументировано. Скорее, вы должны предположить, что идентификаторы объектов базы данных должны быть уникальными в пределах содержащей схемы, если не указано иное. Таким образом, имя ограничения определяется как:

Имя ограничения. Имена ограничений должны соответствовать правилам для идентификаторов, за исключением того, что имя не может начинаться со знака числа (#). Если имя_ограничения не указано, сгенерированное системой имя присваивается ограничению.

Сравните это с именем индекса:

Имя индекса. Имена индексов должны быть уникальными в таблице или представлении, но не обязательно должны быть уникальными в базе данных. Имена индексов должны соответствовать правилам идентификаторов.

что явно сужает область действия идентификатора.

Все остальные ответы хороши, но я подумал, что добавлю ответ на вопрос в заголовке, т. Е. "Могут ли быть ограничения с тем же именем в БД?"

Ответ для MS SQL Server - да, но только при условии, что ограничения находятся в разных схемах. Имена ограничений должны быть уникальными в схеме.

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

Затем я прочитал о SQL-99 ASSERTION ограничение, которое похоже на ограничение проверки, но существует отдельно от любой отдельной таблицы. Условия, объявленные в утверждении, должны выполняться последовательно, как и любое другое ограничение, но утверждение может ссылаться на несколько таблиц.

AFAIK не SQL-поставщик реализует ASSERTION ограничения. Но это помогает объяснить, почему имена ограничений охватывают всю базу данных.

Это зависит от СУБД.

Например, на PostgreSQL ответ - да:

Поскольку PostgreSQL не требует, чтобы имена ограничений были уникальными в пределах схемы (но только для каждой таблицы), возможно, существует несколько совпадений для указанного имени ограничения.

Источник: https://www.postgresql.org/docs/current/static/sql-set-constraints.html

Я видел одинаковые имена ограничений Foreign Keys в двух разных таблицах одной и той же схемы.

Зависит ли это от СУБД (я на SQL Server 2005)?

Да, по-видимому, это зависит от СУБД.

Другие ответы говорят, что это не разрешено, но у меня есть база данных MS SQL CE ("Compact Edition"), в которой я случайно успешно создал два FK-ограничения в двух таблицах с одним и тем же именем.

Хорошей практикой является создание имен индексов и ограничений с указанием имени таблицы в начале. Есть 2 подхода, с индексом / типом ограничения в начале или в конце), например.

UQ_TableName_FieldName

или же

TableName_FieldName_UQ

Имена внешних ключей также должны содержать имена упомянутых таблиц / полей.

Одно из хороших соглашений об именах - указывать имена таблиц в форме FullName_3LetterUniqueAlias, например.

Employers_EMR
Employees_EMP
BankAccounts_BNA
Banks_BNK

Это дает вам возможность использовать "предопределенные" псевдонимы в запросах, что улучшает удобочитаемость, а также упрощает именование внешних ключей, например:

EMPEMR_EmployerCode_FK
BNKEMR_EmployerCode_FK
Другие вопросы по тегам