Mysql 如何将多值属性放在查询的一列中?
例如,在我的数据库中有3个表 用于存储有关书籍的数据的图书表 用于存储有关标记的数据的标记表 以及链接表,该链接表是图书标签表,用于存储关于具有多个标签的图书的信息。 下面的图片说明了这一点。。。箭头上方的M表示关系的多个方面Mysql 如何将多值属性放在查询的一列中?,mysql,sql,database,Mysql,Sql,Database,例如,在我的数据库中有3个表 用于存储有关书籍的数据的图书表 用于存储有关标记的数据的标记表 以及链接表,该链接表是图书标签表,用于存储关于具有多个标签的图书的信息。 下面的图片说明了这一点。。。箭头上方的M表示关系的多个方面 BOOKS BOOK_TAGS TAGS +----+---------+ +---------+----------+ +----+-----
BOOKS BOOK_TAGS TAGS
+----+---------+ +---------+----------+ +----+---------------+
|ID | Title | |Book_Id | Tags_Id | |ID | Tag_Name |
+----+---------+ +---------+----------+ +----+---------------+
|1 | Book_1 | 1 M |1 | 1 | M 1 |1 | Tag_Name_1 |
|1 | Book_1 |<--------|1 | 2 |-------->|2 | Tag_Name_2 |
+----+---------+ |1 | 3 | |3 | Tag_Name_3 |
|2 | 1 | +----+---------------+
|2 | 3 |
+---------+----------+
而不是像这样
+---------------------------------------------------------+
|ID | Book_Title | Tags |
+---------------------------------------------------------+
|1 | Book_1 | Tag_Name_1, Tag_Name_2, Tag_Name_3|
|2 | Book_2 | Tag_Name_1, Tag_Name_3 |
+---------------------------------------------------------+
+----------------------------------+
|ID | Book_Title | Tags |
+----------------------------------+
|1 | Book_1 | Tag_Name_1 |
|2 | Book_1 | Tag_Name_2 |
|3 | Book_1 | Tag_Name_3 |
|4 | Book_2 | Tag_Name_1 |
|5 | Book_2 | Tag_Name_3 |
+----------------------------------+
您可以使用GROUPBY子句聚合结果并执行字符串追加。比如:
SELECT bk.Book_Title, GROUP_CONCAT(bt.Book_Id SEPARATOR ', ') FROM BOOK_TAGS bt
JOIN BOOKS bk ON bk.ID = bt.Book_Id
JOIN TAGS t ON t.ID = bt.Tags_Id
GROUP BY bt.Book_Id
您可以使用GROUPBY子句聚合结果并执行字符串追加。比如:
SELECT bk.Book_Title, GROUP_CONCAT(bt.Book_Id SEPARATOR ', ') FROM BOOK_TAGS bt
JOIN BOOKS bk ON bk.ID = bt.Book_Id
JOIN TAGS t ON t.ID = bt.Tags_Id
GROUP BY bt.Book_Id
下面是具有自动增量ID的sql查询 选择@temp:=@temp+1作为ID,书籍标题,标签从选择标题作为 Book_Title、GROUP_CONCATtag_name作为标签从SELECT BOOKS.Title、, TAGS.tag\u图书中的名称\u标签连接图书上的图书.id= BOOK\u TAGS.BOOK\u id将标记加入标记上的标记。id=BOOK\u TAGS.tag\u id tbl组 按标题作为tbl交叉连接选择@temp:=0作为虚拟
下面是具有自动增量ID的sql查询 选择@temp:=@temp+1作为ID,书籍标题,标签从选择标题作为 Book_Title、GROUP_CONCATtag_name作为标签从SELECT BOOKS.Title、, TAGS.tag\u图书中的名称\u标签连接图书上的图书.id= BOOK\u TAGS.BOOK\u id将标记加入标记上的标记。id=BOOK\u TAGS.tag\u id tbl组 按标题作为tbl交叉连接选择@temp:=0作为虚拟
这是一个SQL反模式。这样做打破了关系数据库设计的基本最佳实践。您不想要的结果实际上是最佳实践规范。@从报告的角度来看,Dems的结果可能很好-只要您不将其存储在DB中,它就不是真正的反模式。用户界面显示可能会显示图书名称,然后是多个标记,用逗号分隔。我可能只是将其作为UI代码的一部分,但有时字符串聚合对于结果集是有意义的。@NWest-也就是说,我认为这是一个观点、观点等问题。但我建议,在数据库中格式化数据也是一种反模式-它限制了代码的重复使用,等等;将结果集保持为“纯”规范化集可以重用代码、简化调试等。格式化属于表示层,数据属于数据层。但是,根据使用情况,层间的强分离应用可能过于热情@Dems这是否意味着我不应该使用此方法来显示数据库的内容?有没有其他方法可以获得相同的结果?..@curzedpirate-我建议返回您说不喜欢的结果。然后,在客户机/应用程序/前端,获取数据并重新格式化。您可能只需要一个逗号分隔的列表,如图所示,您可能需要一个树视图或一些xml。通过将“从数据库获取数据”步骤保持为标准化的形式,您可以更轻松地调整和更改客户端/应用程序/前端,以任意方式显示它。这是一种SQL反模式。这样做打破了关系数据库设计的基本最佳实践。您不想要的结果实际上是最佳实践规范。@从报告的角度来看,Dems的结果可能很好-只要您不将其存储在DB中,它就不是真正的反模式。用户界面显示可能会显示图书名称,然后是多个标记,用逗号分隔。我可能只是将其作为UI代码的一部分,但有时字符串聚合对于结果集是有意义的。@NWest-也就是说,我认为这是一个观点、观点等问题。但我建议,在数据库中格式化数据也是一种反模式-它限制了代码的重复使用,等等;将结果集保持为“纯”规范化集可以重用代码、简化调试等。格式化属于表示层,数据属于数据层。但是,根据使用情况,层间的强分离应用可能过于热情@Dems这是否意味着我不应该使用此方法来显示数据库的内容?有没有其他方法可以获得相同的结果?..@curzedpirate-我建议返回您说不喜欢的结果。然后,在客户机/应用程序/前端,获取数据并重新格式化。您可能只需要一个逗号分隔的列表,如图所示,您可能需要一个树视图或一些xml。通过将“从数据库获取数据”步骤保持为标准化形式,您可以更轻松地修改和更改您的客户端/应用程序/前端,以任意方式显示它。