MySQL 数据库中的多个关系

Multiple relations in MySQL DB

作为我学校学科的介绍性项目,我被要求创建一个应用程序来显示我所在国家/地区的商店列表,并可以按位置和类别对其进行排序。更重要的是,它不应该只是一个静态文本,因为用户可以将 his/her 个自己的商店添加到列表中。

尽管我的 Java 应用程序的 UI 和功能没有遇到任何问题,但我是数据库的新手,尤其是 MySQL。尽管我已经仔细研究了一些教程,但我仍然在为一个非常原始的问题苦苦思索。

问题是:

我创建了一个 table "Shop" 列 "id"(自动递增的主键),"name"(文本类型),"type"(文本类型)和 "location"(文本类型)。

同样,还制作了两个 table:

1) "Types" 其中再次包含 "id" 作为主键和 "type"。例如:

id   type
1    supermarket
2    grocery
3    bookshop

2) "Location" 还有 "id" 和 "city"。像这样:

id   city
1    London
2    Nottingham
3    Southampton

我试图做的是在 "Types"/"Location" 和 "Shop" table 之间创建 "many to 1" 关系(或“1 对 1”在 "Types" 和 "Shop" 以及 "Location" 和 "Shop" 之间),因为我还想按位置和类型对商店进行排序,因此打印相关商店的列表我的应用程序。但是,我根本找不到如何实现这些连接的逻辑顺序。

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

你在这里描述的两个关系都是one-to-many:

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

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

One-to-many 关系是通过在涉及的两个 table 之间添加一个外键来实现的。这是通过在包含父 table 的 ID(主键)的子 table 中添加一列,并为这些列创建外键约束来实现的。

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

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

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'

有关联接的更多信息 here

如果您已经使用外键创建 table,或者如果您正在修改现有的 table,那么实现外键所需的 SQL 是不同的。 This page 包含两种方法的示例。

使用外键创建 table 的简单案例:

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 存储引擎支持外键,因此您必须在 [=] 末尾使用 ENGINE=INNODB 参数创建 tables 58=] 命令以便使用外键约束。如果您不指定,则将使用默认引擎而不是 INNODB 并且您的外键将不起作用。 更新: 自版本 5.5.5 InnoDB 以来,InnoDB 是默认引擎,因此除非引擎已针对您的数据库显式更改,否则您不需要显式引擎参数。

This page在MySQL中对外键有很好的解释(可能对你现在需要的来说太详细了,具体信息你可以去查一下)

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