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 以给它们复数名称)。
作为我学校学科的介绍性项目,我被要求创建一个应用程序来显示我所在国家/地区的商店列表,并可以按位置和类别对其进行排序。更重要的是,它不应该只是一个静态文本,因为用户可以将 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 以给它们复数名称)。