我正在研究标签功能,这是我目前的数据库结构:
`tags` Table: `content` Table:
id | tagname id | title | tags
------------ -----------------------
1 | fire 1 | Charizard | 1 3
2 | water 2 | Blastoise | 2
3 | flying 3 | Charmander | 1
使用这两个表并为每项内容输出正确标签的最佳方法是什么? 如果我以这种方式调用我的标签:
$query = mysql_query("SELECT * FROM `content`");
while ($tableData = mysql_fetch_array($query)) {
echo $tableData["tags"];
}
显然会分别输出原始文本内容1 3
和2
和1
。
我希望它分别显示 fire flying
和 water
和 fire
。
我应该如何使用内容表中标签列提供的信息来获取这些标签名?
最佳答案
是的,你应该研究归一化并将你的表更改为 3NF。首先,这将为您省去一些巨大的麻烦,其次,规范化真的很酷。以下是您将要执行的操作的快速摘要:
将所有标签放在一个字段中是不好的做法。这意味着将查询您的数据库的所有内容都必须确切地知道您如何存储它们以及如何将它们分开。这也意味着您将无法使用纯 SQL 来询问诸如“有多少口袋妖怪具有火属性”或“哪个标签最受欢迎”之类的问题,因为 SQL 不知道您的空格分隔标签列表是什么方法。相反,您会将 content
分成两个表:monsters
和 attributes
。怪物看起来像这样:
id | name
---|---------
1 |Charizard
2 |Blastoise
...
属性看起来像这样:
monsterid | tagid
----------|----------
1 | 1
1 | 3
2 | 2
...
要获取怪物的属性,您可以在怪物表中找到它的名称,获取它的 ID,然后使用它的 ID 从属性表中查找它的属性。使用 JOIN 这很简单,它使您能够以有趣的方式检索信息。
要回答您最初的问题,您需要执行以下操作:
SELECT monsters.id as monsterid, monsters.name, tags.tagname from monsters
INNER JOIN attributes ON (monsters.id = attributes.monsterid)
INNER JOIN tags ON (tags.id = attributes.tagid)
ORDER BY monsters.id
你会得到一个如下所示的结果表:
monsterid | name | tagname
----------|-----------|--------
1 | charizard | fire
1 | charizard | flying
2 | blastoise | water
....
然后您可以遍历返回的行并执行如下操作:
$monsters = array();
while ($tableData = mysql_fetch_array($query)) {
$monstername = $tabledata['name'];
if(!isset($monsters[$monstername])) { $monsters[$monstername] = array(); }
$monsters[$monstername][] = $tabledata['tagname'];
}
最后你会得到你想要的,一个数组,其中每个元素都由怪物的名字标识,值是一个包含所有怪物标签的数组。
...说真的,我知道与您最初的要求相比,这听起来非常复杂,但我相信这是最简单的方法,不太可能在您面前爆炸。如果我错得很厉害,希望有人会纠正我。
警告 - 这里的代码是我凭空写下来的。它可能有一些错误,但它应该向您展示如何实现解决方案。
关于php - 标签功能 - 存储两个表之间的关系(3NF),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9765242/