基本上我拥有的是一个图片库。刚刚尝试创建一个用于学习目的。我现在所拥有的是,当他/她单击类别时,将触发以下用于选择画廊的 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/