web-dev-qa-db-ja.com

DBに同じ名前の制約がありますか?

これは、私が尋ねた質問 here からの後続の質問です。

DBの制約に同じ名前を付けることはできますか?

私が持っていると言います:

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
)

これは許されますか? DBMSに依存していますか(SQL Server 2005を使用しています)?それが許されない場合、それを回避する方法について誰かが何か提案はありますか?

47
Andrew

いいえ-制約もデータベースオブジェクトであるため、その名前は一意である必要があります。

追加してみてください制約に対するテーブル名。そのようにすると、一意になります。

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からの情報

制約名はスキーマに固有である必要があります(つまり、同じデータベース内の2つの異なるスキーマに同じ名前の制約を含めることができます)は明示的に文書化されていません。むしろ、特に指定しない限り、データベースオブジェクトの識別子は包含スキーマ内で一意でなければならないと想定する必要があります。したがって、制約名は defined のようになります。

制約の名前です。制約名は、名前の先頭に番号記号(#)を付けることができないことを除いて、識別子の規則に従う必要があります。 constraint_nameが指定されていない場合、システム生成の名前が制約に割り当てられます。

これを index の名前と比較します。

インデックスの名前です。インデックス名はテーブルまたはビュー内で一意である必要がありますが、データベース内で一意である必要はありません。インデックス名は識別子の規則に従う必要があります。

これにより、識別子の範囲が明示的に絞り込まれます。

52
marc_s

他の答えはすべて良いですが、私はタイトルに質問への答えを追加したいと思いました、つまり、「DBに同じ名前の制約がありますか?

MS SQL Serverの答えは「はい」ですが、制約が異なるスキーマにある場合に限ります。制約名はスキーマ内で一意でなければなりません。

23

私はいつも困惑しましたなぜ制約名はテーブルに関連付けられているように見えるため、データベース内で一意である必要があります。

次に、SQL-99のASSERTION制約について読みました。これは、チェック制約に似ていますが、単一のテーブルとは別に存在しています。アサーションで宣言された条件は、他の制約と同様に一貫して満たされる必要がありますが、アサーションは複数のテーブルを参照できます。

私の知る限り、SQLベンダーはASSERTION制約を実装していません。しかし、これは、制約名のスコープがデータベース全体である理由を説明するのに役立ちます。

10
Bill Karwin

DBMSに依存していますか(SQL Server 2005を使用しています)?

はい、明らかにそれはDBMSに依存しています。

他の回答では、これは許可されていませんが、MS SQL CE( "Compact Edition")データベースを使用していますが、2つのFK制約を2つのテーブルに同じ制約名で誤って作成しました。

2
ChrisW

DBMSによって異なります。

たとえばPostgreSQLでは、答えはyesです。

PostgreSQLは制約名がスキーマ内で一意である必要はないが(テーブルごとのみ)、指定された制約名に複数の一致が存在する可能性があります。

ソース: https://www.postgresql.org/docs/current/static/sql-set-constraints.html

外部キー制約名が同じスキーマ内の2つの異なるテーブルで等しいことを確認しました。

2
Guillaume Husta

最初にテーブル名を指定してインデックスと制約名を作成することをお勧めします。最初または最後にインデックス/制約タイプを使用する2つの方法があります)。

UQ_TableName_FieldName

または

TableName_FieldName_UQ

外部キーの名前には、参照されるテーブル/フィールドの名前も含める必要があります。

良い命名規則の1つは、FullName_3LetterUniqueAliasの形式でテーブル名を付けることです。

Employers_EMR
Employees_EMP
BankAccounts_BNA
Banks_BNK

これにより、クエリで「事前定義された」エイリアスを使用できるようになり、読みやすさが向上し、次のような外部キーの命名も簡単になります。

EMPEMR_EmployerCode_FK
BNKEMR_EmployerCode_FK
0
Niikola