¿Puede haber restricciones con el mismo nombre en una BD?


Esta es una pregunta de continuación de la que hice aquí.

¿Pueden las restricciones en una BD tener el mismo nombre?

Digamos que tengo:

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
)

Es esto permitido? ¿Depende del DBMS (estoy en SQL Server 2005)? Si no es permisible, ¿alguien tiene alguna sugerencia sobre cómo evitarlo?

Author: Community, 2009-09-09

6 answers

No - una restricción también es un objeto de base de datos, y por lo tanto su nombre debe ser único.

Intente agregar, por ejemplo, el nombre de la tabla a su restricción, de esa manera será único.

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
)

Básicamente usamos "FK_"(tabla secundaria)_(tabla principal)" para nombrar las restricciones y estamos bastante contentos con esta convención de nomenclatura.

Información de MSDN

Que los nombres de restricción tienen que ser únicos para el esquema (es decir. dos esquemas diferentes en la misma base de datos pueden contener un restricción con el mismo nombre) no está explícitamente documentado. En su lugar, debe asumir que los identificadores de los objetos de la base de datos deben ser únicos dentro del esquema que los contiene a menos que se especifique lo contrario. Así que el nombre de la restricción es definido como:

Es el nombre de la restricción. Los nombres de restricción deben seguir las reglas de los identificadores, excepto que el nombre no puede comenzar con un signo de número (#). Si no se proporciona constraint_name, se asigna un nombre generado por el sistema a limitación.

Compare esto con el nombre de un índice :

Es el nombre del índice. Los nombres de índice deben ser únicos dentro de una tabla o vista, pero no tienen que ser únicos dentro de una base de datos. Los nombres de índice deben seguir las reglas de los identificadores.

Que reduce explícitamente el alcance del identificador.

 45
Author: marc_s,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-07-08 09:56:52

Las otras respuestas son todas buenas, pero pensé en agregar una respuesta a la pregunta en el título, es decir, " ¿puede haber restricciones con el mismo nombre en una base de datos?"

La respuesta para MS SQL Server es sí, pero solo mientras las restricciones estén en esquemas diferentes. Los nombres de restricción deben ser únicos dentro de un esquema.

 17
Author: Anthony Geoghegan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-31 12:31:11

Siempre me sorprendió por qué los nombres de restricciones deben ser únicos en la base de datos, ya que parecen estar asociados con tablas.

Luego leí sobre la restricción ASSERTION de SQL-99, que es como una restricción de verificación, pero existe aparte de cualquier tabla individual. Las condiciones declaradas en una aserción deben cumplirse consistentemente como cualquier otra restricción, pero la aserción puede hacer referencia a varias tablas.

AFAIK no SQL vendor implementa restricciones ASSERTION. Pero esto ayuda a explicar por qué los nombres de restricción tienen un alcance que abarca toda la base de datos.

 7
Author: Bill Karwin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-09-09 05:57:55

¿Depende del DBMS (estoy en SQL Server 2005)?

Sí, aparentemente depende del DBMS.

Otras respuestas dicen que no está permitido, pero tengo una base de datos MS SQL CE ("Compact Edition") en la que accidentalmente creé con éxito dos contraints FK, en dos tablas, con el mismo nombre de contraint.

 2
Author: ChrisW,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-06 18:59:43

Depende del DBMS.

Por ejemplo en PostgreSQL, la respuesta es :

Porque PostgreSQL no requiere que los nombres de restricción sean únicos dentro de un esquema (pero solo por tabla), es posible que haya más de una coincidencia para un nombre de restricción especificado.

Fuente : https://www.postgresql.org/docs/current/static/sql-set-constraints.html

He visto nombres de restricciones de claves foráneas iguales en 2 tablas diferentes dentro del mismo esquema.

 2
Author: Guillaume Husta,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-07 11:45:13

Una buena práctica es crear nombres de índice y restricción especificando el nombre de la tabla al principio. Hay 2 enfoques, con índice / tipo de restricción al principio o al final) por ejemplo.

UQ_TableName_FieldName

O

TableName_FieldName_UQ

Los nombres de claves foráneas también deben contener nombres de Tablas/Campos referenciados.

Una de las buenas convenciones de nomenclatura es dar nombres de tabla en forma de FullName_3LetterUniqueAlias eg.

Employers_EMR
Employees_EMP
BankAccounts_BNA
Banks_BNK

Esto le da la oportunidad de usar alias "predefinidos" en consultas que mejora la legibilidad y también facilita el nombramiento de claves foráneas, como:

EMPEMR_EmployerCode_FK
BNKEMR_EmployerCode_FK
 0
Author: Niikola,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-09-09 06:54:54