mysql - PHP - MySQL 查询三个表

标签 mysql sql create-table

基本上我拥有的是一个图片库。刚刚尝试创建一个用于学习目的。我现在所拥有的是,当他/她单击类别时,将触发以下用于选择画廊的 mysql 查询:

    SELECT ID, name, gallery_thumb FROM galleries WHERE
    category1=$category_id OR category2=$category_id OR
    category3=$category_id ORDER BY ID DESC

这只是我拼凑的一个快速而糟糕的解决方案。基本上我希望一个画廊出现在多个类别中。在这里,我是这样做的,因为我创建了一个画廊,我可以将它添加到三个或更少的类别中,因此一个画廊可能会出现在不同的类别中。但是这个灵魂不是我想要的。

图库表:

    CREATE TABLE `galleries` (
`ID` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(1000) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL, `description` varchar(1000) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL, `category1` varchar(500) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL, `category2` varchar(500) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL, `category3` varchar(500) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL, `web_link` varchar(3000) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL, `gallery_thumb` varchar(2000) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL, `reg_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`ID`) )

如果我获得了我想要的功能,则 category2 和 category3 将是不必要的并被删除。

标签表:

    CREATE TABLE `gallery_tags` (
    `ID` int(11) NOT NULL AUTO_INCREMENT,
    `tag_name` varchar(100) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
    PRIMARY KEY (`ID`)
    )

标签和图库引用表:

    CREATE TABLE `gallery_tag_reference` (
    `ID` int(11) NOT NULL AUTO_INCREMENT,
    `gallery_id` int(11) NOT NULL,
    `tags_id` int(100) NOT NULL,
    PRIMARY KEY (`ID`)
    )

我添加了标签功能。当我现在创建画廊时,我可以向画廊添加任意数量的标签。现在画廊将只有一个主要类别和许多与之相关的标签。但我希望画廊也根据我在创建画廊时添加的标 checkout 现在其他类别中。这些类别将具有一个或多个预定义的标签。我现在想做的是,当访问者点击类别时,将选择相同的数据,而之前只有查询过滤部分会有所不同。

示例:

Category1 将有标签:car, blue, shiny
gallery1 将有标签:蓝色、红色、快速。
gallery1 不属于类别 1,但因为它在表“gallery_tags”中添加了一个标签“blue”,所以当访问者单击类别 1 按钮时,它会出现在执行的查询结果中。

示例 2:

Category1 没有标签。
Category2 将没有标签。
Category3 将没有标签。
Category4 将具有预定义标签:黄色、红色。
类别 5 将具有预定义标签:高、高。

Gallery1 没有标签,但它属于 Category1。
Gallery2 没有标签,但它属于 Category2。
Gallery3 将有标签:yellow, tall, field
Gallery3 属于 Category3。

当访问者点击 Category4 按钮时,选中的是属于 Category4 的画廊以及带有标签“黄色”或“红色”的画廊。因为这里我们没有属于类别 4 的画廊,但我们有标签为黄色的画廊 3,并且类别 4 也有预定义标签“黄色”,点击时画廊 3 显示在类别 4 中。

与 Category5 相同。它没有直接属于它的任何画廊,但是因为 gallery3 有一个标签“tall”与之相关,并且 Category5 也有预定义标签“tall”,所以 gallery3 也显示在 Category5 中。

我希望我已经清楚地描述了我想要实现的目标。由于我在 MySQL 方面不是很有经验,所以我很难将必要的查询放在一起。我希望有人能帮助!

最佳答案

好的,所以您选择的基本单位是标签类别 - 让我们从为它们创建表格开始

CREATE TABLE tags (
  id INT PRIMARY KEY AUTO_INCREMENT,
  name VARCHAR(100) NOT NULL,
  -- Maybe some other things you want? Tag description?
  UNIQUE INDEX name
);

这给了我们一个tags表,我们可以用

填充它
INSERT INTO tags(name) VALUES
  ('car'),('blue'),('shiny'),('red'),('fast'),('yellow'),('tall'),('high'),('field')
;

基本上相同的事情发生在类别上:

CREATE TABLE categories (
  id INT PRIMARY KEY AUTO_INCREMENT,
  name VARCHAR(100) NOT NULL,
  -- Maybe some other things you want? Description?
  UNIQUE INDEX name
);

INSERT INTO categories(name) VALUES
  ('cars'),('people'),('colors'),('landscapes'),('misc')
;

现在我们可以看看画廊了:

  • 每个画廊都应该属于 1 个类别(现在),每个 类别可以有很多画廊。所以它是一个 1:n 关系 类别的 POV,因此我们需要在 n 端有一个指针字段 的关系,画廊。我在这里不使用外键 只是为了简洁,强烈建议您考虑使用它们。
  • 每个画廊可以有很多标签,每个标签可以属于很多画廊 - 所以这是一个 n:m 关系,我们不需要直接在表中的字段,但我们需要一个连接表。
  • 每个类别可以有多个标签,每个标签可以属于多个类别——所以是一回事

所以我们这样做:

CREATE TABLE galleries (
  id int(11) PRIMARY KEY AUTO_INCREMENT,
  name varchar(100)  NOT NULL,
  category` INT NOT NULL,
  -- the other fields you want: description, web_link, gallery_thumb,reg_time
  UNIQUE INDEX(name)
)

注意类别的数据类型INT:它将链接到类别表的主键,也是INT

我们可能不会忘记连接表:

CREATE TABLE galleries_tags (
  gallery INT,
  tag INT,
  PRIMARY KEY(tag, gallery),
  KEY(gallery)
);

CREATE TABLE categories_tags (
  category INT,
  tag INT,
  PRIMARY KEY(tag, category),
  KEY(category)
);

INT 类型的 tag 字段会将这些连接表链接到 tags 表的 id 字段,而 gallery 响应。 category 字段将链接到相应表的 id 字段。

我们再次用INSERT 查询填充表格。 (懒得写出来了)

现在您的数据已存储在数据库中,是时候再次取出它了:

你的用例:用户点击一个类别,你想选择画廊,有

  • 要么被归档在这个类别下
  • 或与该类别共享标签

这很简单,但需要一点思考:

  • 您的目标表是类别
  • 对于按类别选择,您有一个直接选择器:category 字段
  • 要按标签选择,您必须通过上述连接表连接
  • 对于组合选择,如果您不想错过仅类别的选择,则需要LEFT JOIN,但这会降低您的性能。因此,您选择单独的结果并UNION

假设您的用户选择了类别 4:

SELECT * FROM galleries WHERE category=4
UNION
SELECT categories.* 
FROM galleries
INNER JOIN galleries_tags ON galleries.id=galleries_tags.gallery
INNER JOIN categories_tags ON categories_tags.tag=galleries_tags.tag
WHERE categories_tags.category=4

Bob 是你的叔叔。

这个查询是做什么的?第一部分很简单,第二部分选择那些画廊,即

  • 附加标签(INNER JOIN galleries_tags ON ...)
  • 哪些标签附加了类别(INNER JOIN categories_tags ON ...)
  • 哪些类别的id 4

关于mysql - PHP - MySQL 查询三个表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11393172/

相关文章:

MySQL:如果字段为空,则不显示特定数据

c++ - 尝试使用 OTL 连接到我的 PostgreSQL 服务器

mysql - 这条 mySQL create table 语句中我的语法错误是什么?

MySQL 错误 - 字段 'id' 没有默认值

mysql - 使用选择删除(错误 1093)

mysql - 从与外键链接的一个表到多个表的 SELECT 查询

sql - Rails 服务器命令错误

mysql - 在 MySQL 中使用 SELECT 语法创建表

mysql - 在Mysql存储过程中创建临时表

sql - 如何使用 SQL 按最后日期查找可能的反向重复项?