2009-09-09 10 views
31

Questa è una domanda successiva a quella che ho chiesto a here.Possono esserci vincoli con lo stesso nome in un DB?

I vincoli in un DB possono avere lo stesso nome?

Dire che ho:

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 
) 

È questo ammissibile? Dipende dal DBMS (sono su SQL Server 2005)? Se non è consentito, qualcuno ha qualche suggerimento su come aggirarlo?

risposta

37

No: un vincolo è anche un oggetto di database e pertanto il suo nome deve essere univoco.

Prova ad aggiungere per es. il nome della tabella per il vincolo, in questo modo sarà unico.

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 
) 

Abbiamo praticamente utilizziamo "FK _" (tabella figlio) _ (tabella padre)" per nominare i vincoli e sono abbastanza contento di questa convenzione di denominazione.

informazioni da MSDN

Quello i nomi dei vincoli devono essere univoci per lo schema (cioè due schemi diversi nello stesso database possono entrambi contenere un vincolo con lo stesso nome) non sono esplicitamente documentati. Piuttosto è necessario assumere che gli identificatori degli oggetti del database debbano essere univoci all'interno del schema se non specificato erwise. Quindi il nome del vincolo è defined come:

È il nome del vincolo. I nomi dei vincoli devono seguire le regole per gli identificatori, tranne per il fatto che il nome non può iniziare con un segno di cancelletto (#). Se constraint_name non viene fornito, al vincolo viene assegnato un nome generato dal sistema.

Confrontare questo al nome di un index:

è il nome dell'indice. I nomi degli indici devono essere unici all'interno di una tabella o vista, ma non devono essere univoci all'interno di un database. I nomi degli indici devono seguire le regole degli identificatori.

che restringe esplicitamente l'ambito dell'identificatore.

+0

+1: Abbiamo utilizzato le prime lettere delle parole che rendono il nome della tabella come prefisso. –

7

Sono sempre stato perplesso perché i nomi dei vincoli devono essere univoci nel database, poiché sembrano associati alle tabelle.

Poi ho letto del vincolo di SQL-99 ASSERTION, che è come un vincolo di controllo, ma esiste a prescindere da una singola tabella. Le condizioni dichiarate in un'asserzione devono essere soddisfatte in modo coerente come qualsiasi altro vincolo, ma l'asserzione può fare riferimento a più tabelle.

AFAIK nessun fornitore SQL implementa i vincoli ASSERTION. Ma questo aiuta a spiegare perché i nomi dei vincoli sono di ambito del database.

+1

bene, anche se il vincolo di asserzione non è implementato: vorresti volere avere tre vincoli di chiave esterna con lo stesso nome? Se ottieni un errore di violazione FK che indica il nome dell'FK, come fai a sapere quale dei tre è realmente? Penso che l'applicazione di nomi di vincoli univoci sia una "buona cosa (tm)" :-) –

+0

Sì, sicuramente. Stavo dicendo che "è nello standard ANSI SQL in questo modo", ma il tuo punto è ancora più pratico. –

0

È buona norma creare nomi di indici e vincoli specificando il nome della tabella all'inizio. Ci sono 2 approcci, con tipo di indice/vincolo all'inizio o alla fine) es.

UQ_TableName_FieldName 

o

TableName_FieldName_UQ 

esteri chiavi nomi dovrebbero contenere anche i nomi di riferimento Tabella/Field (s).

Una delle buone convenzioni di denominazione è fornire i nomi di tabella sotto forma di FullName_3LetterUniqueAlias ​​es.

Employers_EMR 
Employees_EMP 
BankAccounts_BNA 
Banks_BNK 

Questo darà la possibilità di utilizzare gli alias "predefiniti" nelle query che migliora la leggibilità e anche rende Naming delle chiavi esterne più facile, come:

EMPEMR_EmployerCode_FK 
BNKEMR_EmployerCode_FK 
16

Le altre risposte sono tutti buoni, ma ho pensato che 'd aggiungi una risposta alla domanda nel titolo, vale a dire, 'può esserci vincoli con lo stesso nome in un DB?'

la risposta per MS SQL Server è sì - ma solo fino a quando i vincoli sono in diversi sch EMAS. I nomi dei vincoli devono essere univoci all'interno di uno schema.

1

Dipende dal DBMS (Sono su SQL Server 2005)?

Sì, a quanto pare non dipende dal DBMS.

Altre risposte dicono che non è consentito, ma ho un database MS SQL CE ("Compact Edition") in cui ho accidentalmente creato due contrappesi FK, in due tabelle, con lo stesso nome di contraint.

0

Dipende dal DBMS.

Ad esempio, su PostgreSQL, la risposta è :

Perché PostgreSQL non richiede i nomi di vincolo per essere unico all'interno di uno schema (ma solo per-tavolo), è possibile che c'è più di una corrispondenza per un nome di vincolo specificato.

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

Chiavi esterne nomi di vincoli che ho visto è uguale su 2 tavoli differenti all'interno dello stesso schema.

Problemi correlati