2017-11-29 20 views
0

だが、私はこのようなテーブルがあるとしましょう:MySQLのUNIQUE制約は、列の値に基づいて

CREATE TABLE dept (
    id  VARCHAR(255) NOT NULL PRIMARY KEY, 
    code VARCHAR(255) NOT NULL, 
    active BIT   NOT NULL, 
    ... 
); 

問題:

私はcode列に一意制約を追加します。しかし、activetrueに設定されている場合にのみ適用する必要があります(一意性はアクティブレコード間でのみチェックする必要があります)。 active = falseと多くのレコードがあり、同じcodeなので、複数の列に対して制約を使用することはできません。私が試した何

私は、このような制約が可能であることを証明the documentation内の任意の参照を発見していないが、私はそれがユニークなファンクション索引を使用してother databasesで可能であることを知っています。

もちろん、すべての追加/更新操作で不変条件をチェックするトリガーを書くことはできますが、より効率的なソリューションがあることを願っています。

私はMySQL 5.7.15を使用しています。

+0

これは単純にMySQLでは不可能ですが、私は恐れています。おそらく*おそらく*来る可能性があるのは、ヌル可能な(アクティブなフィールドを置き換える)一意に制約されたカラムを持つことです。 'NULL'のときは' '非アクティブです。' 'NULL''以外のときは一意でなければなりません。それ以外の場合は、ストアドプロシージャを使用してテーブルに読み書きを行うか、トリガを使用して不愉快なことをします。 – wally

+0

おそらくもっとエレガントなものがあるかもしれませんが、より大きな画像(つまり、解決しようとしている全体的な問題)を知っている必要があります。 Big Picture(TM)であなたの質問を更新できますか? – wally

答えて

1

これは単純にMySQLでは不可能ですが、私は恐れています。

これまでNULL解決可能な一意制約付き列(activecodeフィールドの両方を置き換える)を使用することで、これを解決することに「近づいてきました」。 NULL - それが「非アクティブ」のとき、NULL以外のもの - それは一意でなければなりません。

しかし、それはあなたが求めている問題を正確には解決しません。

それ以外の場合は、ストアドプロシージャを使用してテーブルに読み書きします。または、自分自身で提案したように、トリガーで気分が悪いものを実行します。

+0

非アクティブなレコードに対して 'code'を' NULL'に設定することはできません。これはビジネス上の貴重な情報です(例えばレコードを後でアクティブな状態に戻すことができます)。 –

+0

Ah OK - 十分です。より大きな画像を見ることなく、テーブルに対する読み込み/書き込みのためのトランザクションセーフな手順を持つことになり、ユニークな制約を持つ別の列を更新する可能性があります。残念ながら、MySQLと同じくらいうまくいっていますが、他のDBMSの機能の多くは...-) – wally

+0

それは悲しいことです。おそらくMySQLは私たちが作った最良の選択ではありませんでしたが、残念ながら変更するには遅すぎます。これは私のリストの4番目の重要な機能ですが、これはMySQLではなく、他のフリーなDBにあります。一方で、MySQLには他にも重要な機能がいくつか存在するかもしれません。 –

0

CHECK節を使用する必要がありますが、MySQLではサポートしていません。ドキュメントから:

CHECK句は解析されますが、すべてのストレージエンジンで無視されます。第13.1.18項「CREATE TABLE構文」を参照してください。構文句を受け入れても無視する理由は、互換性のため、他のSQLサーバーからコードを移植しやすく、参照付きのテーブルを作成するアプリケーションを実行するためです。

これは、アプリケーションレベルのデータをチェックするか、このテーブルの行をストアドプロシージャによって挿入/更新することによってのみ実行できます。

0

私は申し訳ありませんが、これはあなたの質問を実際に直接答えていませんが:

たぶん、あなたは別のテーブルデザインを持つほうが良いでしょうか?あなたがしたいことがあなたのRDBMSによってサポートされていないという事実は、あなたが間違って使っているという強い証拠です。

アクティブなレコードのみを含むdeptおよびdept_historyテーブルの作成について考えましたか?これは、ユニークな制約の問題を解決します。

+0

オーバーヘッドです。 MySQLが 'CHECK'節をサポートしていないという事実は、DB設計が間違っていることを意味するものではありません。 –

+0

代わりの方法をここに提示するだけです。私はそれを知っていないので、DB-Designを判断できませんが、MySQL(RDBMS)をその機能を超えて使用したいと確信しています。チェック節がそれをサポートするRDBMSにどのようなオーバーヘッドを導入すると思いますか? – Daniel

+0

もちろん、それはトレードオフです。確かな理由があった。このような機能を持っていないBotは責任を開発者に移し、開発者はそれを効率の悪い方法で確実に実装します。私はそれを自分で実装するのではなく、すべてのオーバーヘッド/結果で機能を持たせたいと思っています。 –

関連する問題