sql >> データベース >  >> RDS >> PostgreSQL

複合PRIMARYKEYは、関連する列にNOTNULL制約を適用します

    必要の場合 NULL値を許可するには、 UNIQUEを使用します 制約 PRIMARY KEYの代わりに (そして代理PK列を追加します。serialをお勧めします )。これにより、列をNULLにすることができます:

    CREATE TABLE distributor (
       distributor_id serial PRIMARY KEY
     , m_id integer
     , x_id integer
     , UNIQUE(m_id, x_id)
    );

    ただし、(ドキュメントごとに):

    一意性制約の目的で、null値は等しいとは見なされません。

    あなたの場合、(1, NULL)のようなものを入力することができます (m_id, x_id)の場合 制約に違反することなく何度でも。 Postgresは2つのNULL値を等しいと見なすことはありません -SQL標準の定義に従います。

    NULLを処理する必要がある場合 このような「重複」を禁止するのと同じ値、2つのオプションが表示されます

    1。 2つの部分インデックス

    さらに UNIQUEへ 上記の制約:

    CREATE UNIQUE INDEX dist_m_uni_idx ON distributor (m_id) WHERE x_id IS NULL;
    CREATE UNIQUE INDEX dist_x_uni_idx ON distributor (x_id) WHERE m_id IS NULL;
    

    しかし、これはNULLになる可能性のある3つ以上の列ですぐに手に負えなくなります。参照:

    • null列を使用して一意の制約を作成する

    2。複数列のUNIQUE 式のインデックス

    UNIQUE制約の代わりに。 -1のように、関連する列には決して存在しない無料のデフォルト値が必要です。 。 CHECKを追加します それを禁止するための制約:

    CREATE TABLE distributor (
       distributor serial PRIMARY KEY
     , m_id integer
     , x_id integer
     , CHECK (m_id &lt> -1)
     , CHECK (x_id &lt> -1)
    );
    CREATE UNIQUE INDEX distributor_uni_idx ON distributor (COALESCE(m_id, -1)
                                                          , COALESCE(x_id, -1))
    

    特定のRDBMSが物事を処理する方法 は、適切な動作を示すための有用な指標であるとは限りません。 Postgresのマニュアルはこれを示唆しています:

    つまり、一意の制約が存在する場合でも、制約された列の少なくとも1つにnull値を含む重複行を格納することが可能です。この動作はSQL標準に準拠していますが、他のSQLデータベースがこのルールに従わない可能性があると聞いています 。したがって、ポータブルを目的としたアプリケーションを開発する場合は注意が必要です。

    大胆な強調鉱山。




    1. PostgreSQLデータベースのプロファイルを作成する方法は?

    2. SQL ServerのCAST()とTRY_CAST():違いは何ですか?

    3. SQLネットワークインターフェイス、エラー:50-ローカルデータベースランタイムエラーが発生しました。自動インスタンスを作成できません

    4. SQLiteでのDateTime()関数のしくみ