【问题标题】:Multiple relations in MySQL DBMySQL 数据库中的多个关系
【发布时间】:2018-03-10 13:24:28
【问题描述】:

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

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

问题是:

我创建了一个表“Shop”,其中包含“id”(自动递增的主键)、“name”(文本类型)、“type”(文本类型)和“location”(文本类型)列。

同样,又制作了两张桌子:

1)“类型”,它再次包含“id”作为主键和“类型”。例如:

id   type
1    supermarket
2    grocery
3    bookshop

2) “位置”也带有“id”和“城市”。像这样的:

id   city
1    London
2    Nottingham
3    Southampton

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

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

【问题讨论】:

  • 鉴于要求,不需要多张桌子。鉴于您对第一个表的实现,不需要其他两个。
  • 但是如果我接下来调整我的表格:“类型”将包含 type_id,“位置” - location_id,因此,我的“商店”表格的“类型”和“位置”将变成索引“ type_id”和“location_id”。或者这只是浪费时间?
  • 浪费时间。您只是让检索数据变得更加昂贵和复杂。

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


【解决方案1】:

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

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

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

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

也就是说,您必须在您的Shop 表中添加一个typeId 列,并在您的数据库中定义外键约束。与位置的关系也是如此:将 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'

关于加入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(或者重命名其他两个表以赋予它们复数名称)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-15
    • 1970-01-01
    • 2018-11-08
    • 1970-01-01
    • 2021-06-13
    • 2018-08-02
    • 1970-01-01
    相关资源
    最近更新 更多