Могут ли быть ограничения с тем же именем в БД?
Это дополнительный вопрос из того, который я задал здесь.
Могут ли ограничения в БД иметь одно и то же имя?
Скажи, что у меня есть:
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