插入表 - 丢弃重复项,其中键可以为空

时间:2016-05-13 11:12:48

标签: mysql sql

我有一个程序,用户可以创建和编辑任务。每个任务都可以分配0-n 问题

当用户正在编辑任务时,会向他们显示一个问题列表(先前创建的),他们可以(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         |
-------------------------------------------------------------------------

上面的第一个条目question_id等于NULL,因为它用于整个任务,而其他用于特定问题。此外,每个问题对于任务都是唯一的。

我正在尝试通过减少提交更改时针对数据库进行的循环量和不必要的检查来优化一些后端逻辑和查询时间。我尝试这样做的一种方法是将task_idquestion_id UNIQUE键结合使用,这样如果task_dataINSERT INTO,我就不必对数据库进行检查在执行ALTER TABLE task_data_table ADD UNIQUE unique_index (question_id, student_member_id); 之前,所述成员和问题已经存在。所以我做了:

0

但是,我刚从文档中找到了:

  

UNIQUE索引允许可以包含NULL的列的多个NULL值

我已经研究了解决此问题的方法,但我只找到了使用NULL作为默认值的建议,而不是task_id。不幸的是,这是不可能的,因为question_idIF NOT EXISTS都是外键。

我确实尝试过使用NOT INComment找到的一些查询,但这些查询无效。我该如何解决这个问题?

1 个答案:

答案 0 :(得分: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值的代码都可以使用视图。