PHP - MySQL查询三个表

时间:2012-07-09 10:23:54

标签: 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`)
    )

我添加了标签功能。当我创建一个画廊时,我可以在画廊中添加尽可能多的标签。现在画廊将只有一个主要类别和许多标签。但是我想根据我在创建图库时添加的标签,将图库显示在其他类别中。这些类别将预定义一个或多个标签。我现在要做的是当访问者点击该类别时,将选择相同的数据,这只是在查询过滤部分不同之前。

示例:

Category1将有标签:汽车,蓝色,闪亮
gallery1将有标签:蓝色,红色,快速 gallery1不属于category1,但因为它在“gallery_tags”表中添加了一个标记“blue”,它会出现在访问者点击category1按钮时执行的查询结果中。

例2:

Category1没有标签。
Category2没有标签 Category3没有标签 Category4将有预定义的标签:黄色,红色 Category5将有预定义标签:tall,high。

Gallery1没有标签但属于Category1 Gallery2没有标签但属于Category2 Gallery3将有标签:黄色,高,字段
Gallery3属于Category3。

当访问者点击选择的Category4按钮时,属于Category4的画廊和具有“黄色”或“红色”标签的画廊。因为这里我们没有属于Category4的画廊,但是我们有gallery3,其标签为黄色,而Category4也有预定义的标签“黄色”gallery3在类别4中显示。

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

我希望我说清楚我想要实现的目标。由于我对MySQL不是很有经验,因此无法将必要的查询放在一起。我希望有人会帮忙!

1 个答案:

答案 0 :(得分:2)

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

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)
);

tag类型的INT字段会将这些联接表链接到id表的tags字段,而gallery分别表示category字段。 id字段将链接到相应表格的INSERT字段。

我们再次使用categories查询填充表格。 (懒得把它们写出来)

现在您已将数据存储在数据库中,有时间再次将其取出:

您使用:用户点击某个类别,您想要选择具有

的图库
  • 要么已归入此类别
  • 或与此类别共享标签

这很容易,但需要一点思考:

  • 您的目标表是category
  • 要按类别进行选择,您有一个直接选择器:LEFT JOIN字段
  • 要按标记选择,您必须通过上述联接表加入
  • 对于组合选择,如果您不想错过仅限类别选项,则需要UNION,但这会导致您的性能下降。因此,您选择单独的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 结果

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

INNER JOIN galleries_tags ON ...
鲍勃是你的叔叔。

这个查询有什么作用?第一部分很简单,第二部分选择那些画廊,

  • 附有标签(INNER JOIN categories_tags ON ...
  • 哪些标签附有类别(id
  • 哪些类别包含{{1}} 4