2016-05-13 5 views
0

私はユーザがのタスクを作成して編集できるプログラムを持っています。各タスクは0〜n の質問を割り当てられます。テーブルに挿入 - キーがnullの場合の重複を破棄

ユーザがタスクを編集しているときに、(1)削除または(2)編集のいずれかの質問のリストが提示されます。また、(3)質問のリストに新しい質問を追加することもできます。

各質問には、割り当てられたメンバーとの関係があるため、進捗状況を追跡することができます。これはtask_data_tableで行われます。テーブルの

task_data_table 
============================================================================ 
| Field    | Type   | Null | Key | Default | Extra   | 
============================================================================ 
| id    | int(11)  | no | PRI | Null | auto_increment | 
| completion_date | timestamp | yes |  |   |    | 
| answer   | varchar(255) | yes |  |   |    | 
| task_id   | int(11)  | yes | MUL |   |    | 
| question_id  | int(11)  | yes | MUL |   |    | 
| member_id   | int(11)  | yes | MUL |   |    | 
---------------------------------------------------------------------------- 

内容は次のようになります。それは特定のために他のに対して、全体としてのタスクのために使用されているため、上記

========================================================================= 
| id | completion_date  | answer | task_id | question_id | member_id | 
========================================================================= 
| 1 | 2016-05-13 11:00:00 | NULL | 20  | NULL  | 2   | 
| 2 | 2016-05-13 11:00:00 | yes | 20  | 8   | 2   | 
| 3 | 2016-05-13 11:00:00 | no  | 20  | 9   | 2   | 
------------------------------------------------------------------------- 

最初のエントリはNULLに等しいquestion_idを有します質問。また、それぞれの質問はタスクに固有のものです。


私は変更を提出する際に、ループやデータベースに対して行われ、不要なチェックの量を減らすことによって、いくつかのバックエンドのロジックとクエリ時間を最適化しようとしています。私がこれをやってみた1つの方法は、INSERT INTOを実行する前に、上記のメンバーと質問のtask_dataが既に存在する場合、データベースに対してチェックを行う必要がないように、question_idとの組み合わせでtask_idを与えることでした。だから私はやった:

ALTER TABLE task_data_table ADD UNIQUE unique_index (question_id, student_member_id); 

しかし、私はちょうどドキュメントから出た:

UNIQUEインデックス私が見てきた

NULLを含めることができる列に対して複数のNULL値を許可しますこの問題を解決する方法を紹介しましたが、NULLの代わりに0をデフォルト値として使用することを提案しました。残念ながら、task_idquestion_idの両方が外部キーであるため、これは不可能です。

IF NOT EXISTSまたはNOT INで見つかったクエリを試しましたが、機能しませんでした。この問題をどうやって解決するのですか?

+0

MySQLでは、この機能にはトリガーが必要だと思います。 –

+0

@GordonLinoff、うーん...このトリガーがどのように機能するのか説明できますか? – Chris

答えて

1

他のデータベースにはこれに対するより良い仕組みがあります。 MySQLでは、おそらくquestionsに偽の行を追加することをお勧めします。

この行のIDは、0または-1である必要があります。次に、外部キー制約とユニーク制約を使用して、必要な動作を取得できます。

カラムの値がNULLの場合は、注意が必要です。これを回避する一つの方法は、ビューを使っている:

create view v_task_data_table as 
    select . . ., 
      (case when question_id = -1 then NULL else question_id end) as question_id 
    from task_data_table; 

その後、NULL値はビューを使用して、それを持っているでしょう望んで任意のコードを。

+0

これは本当に残念です。偽の列を持つことは私の考えを超えましたが、実際には潜在的に危険なアプローチのように思えます。アンチパターン。私は描画ボードに戻っています。 – Chris

+0

@Chris。 。 。他のデータベースでは、フィルタリングされたインデックスと計算カラムがサポートされています。実際には、MySQLは最新のバージョンの計算カラムをサポートしているため、最新バージョンのソリューションがあるかもしれません。 –

関連する問題