如何使用Innodb确保MySQL中的多个表列是唯一的(或重构我的表)?

时间:2016-02-16 14:10:57

标签: mysql database foreign-keys innodb

我目前有两个单独的表,其中第三个用于存储配方,项目和custom_meal(要创建的那个)。

我希望创建一个膳食计划器,用户可以在其中添加食谱,物品或自定义项目作为特定日期的早餐/午餐/晚餐。

我对下面的新表有一个想法,虽然沿着这条路走下去,但我无法确保meal_planner.id只能是食谱,物品或自定义。
通过编写良好的查询,我意识到永远不应该允许这是一个问题,尽管对于仍然需要了解数据库的人来说,我更倾向于使用一种解决方案来确保数据可能永远不会被输入。< / p>

我正在使用的表格中感兴趣的当前列是:

recipe.id  
item.id
user.id

我目前对“膳食计划者”表的看法是:

表:meal_planner

id - primary key
user_id - foreign key user.id
mdate - the day which the meal is planned for
mtime - whether the meal is breakfast, lunch or dinner.
mcomment (can be null)

表:meal_is_recipe

meal_id - foreign key meal_planner.id
recipe_id - foreign key recipe.id

表:meal_is_custom

meal_id - foreign key meal_planner.id
custom_id - foreign key custom_meal.id

表:meal_is_item

meal_id - foreign key meal_planner.id
item_id - foreign key item.id

表:custom_meal

id - primary key
user_id - foreign key user.id
name - varchar to hold the name of the meal

这应该允许我使用连接来获取显示所需的所有数据,尽管如上所述它让我觉得它们没有限制停止用餐。在配方,项目和/或习惯中使用。

1 个答案:

答案 0 :(得分:0)

好的,所以发布后我发现了“触发器”。

触发器与存储过程类似,但在触发器情况下,它们将在满足设置条件时自动触发,例如在完成对表的插入,更新或删除之前。

在我的情况下,我创建了六个触发器,每个meal_is_x表有两个触发器来检查其中一个table_id是否已经存在并返回错误而不是插入错误。

我没有通过phpmyadmin查询使用示例运气,所以我通过选择数据库,单击Triggers选项卡,单击添加新触发器然后输入以下内容(在每个不同的表中略微修改)在phpmyadmin中创建我的触发器以及它是用于插入还是更新。)

触发器名称:meal_is_recipe_BeforeInsert

表:meal_is_recipe

时间:BEFORE

活动:INSERT

定义:

BEGIN
    DECLARE custom_match INT;
    DECLARE item_match INT;
    SELECT COUNT(1) INTO custom_match FROM meal_is_custom
    WHERE meal_id = NEW.meal_id;
    IF custom_match > 0 THEN
        SIGNAL SQLSTATE '45000'
        SET MESSAGE_TEXT = 'A Custom record with that meal id already exists';
    ELSE
        SELECT COUNT(1) INTO item_match FROM meal_is_item
        WHERE meal_id = NEW.meal_id;
        IF item_match > 0 THEN
            SIGNAL SQLSTATE '45000'
            SET MESSAGE_TEXT = 'An Item record with that meal id already exists';
        END IF;
    END IF;
END

定义者:我把这个空白留给了查询的用户,如果运行触发器那么好。

我相信我也应该能够在MySQL查询中得到相同的结果,但正如我提到的那样,这在phpmyadmin中不能直接用于我,而不是进一步调查触发器选项卡很简单:

DELIMITER //
CREATE TRIGGER meal_is_recipe_BeforeInsert BEFORE INSERT ON meal_is_recipe
BEGIN
    DECLARE custom_match INT;
    DECLARE item_match INT;
    SELECT COUNT(1) INTO custom_match FROM meal_is_custom
    WHERE meal_id = NEW.meal_id;
    IF custom_match > 0 THEN
        SIGNAL SQLSTATE '45000'
        SET MESSAGE_TEXT = 'A Custom record with that meal id already exists';
    ELSE
        SELECT COUNT(1) INTO item_match FROM meal_is_item
        WHERE meal_id = NEW.meal_id;
        IF item_match > 0 THEN
            SIGNAL SQLSTATE '45000'
            SET MESSAGE_TEXT = 'An Item record with that meal id already exists';
        END IF;
    END IF;
END//
DELIMITER ;

正如我在问题中所提到的,我使用数据库的知识还有很长的路要走,所以虽然我用我最初的问题模式进行了测试并且它有效,但我无法保证这是实现结果的最有效方法。