MySQL DB中的多个关系

时间:2018-03-10 13:24:29

标签: mysql sql database foreign-keys relational-database

作为我学校科目的入门项目,我被要求创建一个应用程序,用于显示我所在国家/地区的商店列表,并可按地点和类别对其进行排序。更重要的是,它不应该只是一个静态文本,因为用户可能会将他/她自己的商店添加到列表中。

虽然我没有遇到Java应用程序的UI和功能方面的任何问题,但我是数据库的新手,特别是MySQL。尽管我已经仔细检查了一些教程,但我仍然在讨论一个非常原始的问题。

问题是:

我创建了一张桌子" Shop"使用列" id"(具有自动增量的主键),"名称"(文本类型),"键入"(文本类型)和"位置& #34;(文字类型)。

同样,还有两张牌桌:

1)"类型"其中包含" id"再次作为主键和"键入"。例如:

id   type
1    supermarket
2    grocery
3    bookshop

2)"位置"用" id"也是" city"。像这样:

id   city
1    London
2    Nottingham
3    Southampton

我尝试做的是创建"多对1" "类型" /"位置"之间的关系和" Shop"表格(或" 1到1""类型"和"商店"以及"位置"和"商店" ;),因为我想进一步按位置和类型对商店进行分类,因此,在我的应用程序中打印相关商店的列表。但是,我根本找不到如何实现这些连接的逻辑顺序。

期待任何提示。 提前谢谢!

1 个答案:

答案 0 :(得分:1)

您在此处描述的两种关系都是一对多关系:

  • 一家商店只有一种类型。一种类型可以在许多不同的商店中使用。
  • 一家商店只有一个地方。一个位置可以在许多不同的商店使用。

如果您允许商店拥有空的类型或位置,可以额外考虑。为简单起见,我们将考虑这里没有发生(但可以通过使用可以为空的外键来实现)。

通过在两个相关表之间添加外键来实现一对多关系。这是通过在子表中添加一个包含父表的id(主键)的列,并为这些列创建外键约束来实现的。

也就是说,您必须在typeId表中添加Shop列,并在数据库中定义外键约束。与位置关系相同:向locationId添加Shop列和外键约束。

您不应该在Shop表中包含位置和类型名称的文本列,只包含ID列。使用该信息进行搜索时,您将使用不同相关表之间的连接进行查询。有点像这样:

SELECT s.name, t.type, l.city
FROM Shop s
    INNER JOIN Types t ON s.typeId = t.id
    INNER JOIN Location l ON s.locationId = l.id
WHERE t.type = 'supermarket'

有关joins here的更多信息。

如果要创建具有外键的表,或者要修改现有表,则实现外键所需的SQL是不同的。 This page包含两种方法的示例。

使用外键创建表的简单情况:

CREATE TABLE Shop (
    id int NOT NULL,
    name text NOT NULL, 
    typeId int NOT NULL,
    locationId int NOT NULL,
    PRIMARY KEY (id),
    CONSTRAINT FK_TypeShop FOREIGN KEY (typeId)
    REFERENCES Types(id),
    CONSTRAINT FK_LocationShop FOREIGN KEY (locationId)
    REFERENCES Location(id)
)  ENGINE=INNODB;

重要说明:在MySql中,只有InnoDB存储引擎支持外键,因此您必须在SQL命令末尾使用ENGINE=INNODB参数创建表,以便使用外键约束。如果您没有指定,那么将使用默认引擎而不是INNODB,并且您的外键将不起作用。 更新,因为版本5.5.5 InnoDB是默认引擎,所以除非为您的数据库明确更改引擎,否则您不需要显式引擎参数。

This page包含对MySQL中外键的一个很好的解释(可能对你现在需要的内容过于详细,但你可以检查它以获取具体信息)。

作为最佳做法,将所有表格命名为复数或以单数形式命名,但对所有表格使用相同的标准。您可能应该将表Types重命名为Type(或重命名其他两个表以赋予它们多个名称)。