【发布时间】:2012-02-03 22:22:53
【问题描述】:
如果我有一张桌子:
CREATE TABLE Kids (
kid_id int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
kid_name varchar(45) NOT NULL,
kid_favcolors (text) NULL,
PRIMARY_KEY(kid_id)
)
我有一张桌子:
CREATE TABLE Colors (
color_id int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
color_name varchar(45) NOT NULL,
PRIMARY_KEY(color_id)
)
通过逗号分隔的 ID 引用喜欢的颜色的行:
INSERT INTO Kids(kid_name, kid_favcolors) VALUES('Joe','1,2,3,4,5');
INSERT INTO Kids(kid_name, kid_favcolors) VALUES('Mary','1,2,3');
我将如何创建一个语句,该语句将返回 Kid 数据库中的每个条目以及 Kid_favcolors 列中引用的所有 ID 的 Kid_name 和 color_name。
例如:
COLORS:
color_id 颜色名称
1 黄色
2 绿色
3 蓝色
4紫
5红色
6棕色
7 黑色
KIDS:
Kid_id 孩子名字 Kid_favcolors
1 乔 1,2,3,4,5
2 玛丽 1,2,3
我想找回
child_id 孩子名字 favorite_colors 1乔黄、绿、蓝、紫、红 2 玛丽黄、绿、蓝正在对现有数据和数据库结构执行查询。如果没有可行的解决方案,重新排列数据结构是可能的,但我认为会为解决方案增加大量时间。无论哪种方式,都需要一些帮助。
我可以使用以下方法从数据库中检索颜色:
SELECT STUFF((SELECT ', ' + color_name FROM colors WHERE color_id IN (1,2,3,4,5) FOR XML PATH('')),1, 2, '') AS colors
colors
1 yellow, green, blue, purple, red
但是当我尝试更复杂的查询时,我似乎无法通过从 Kids 表中提取 id 来找到合并上述语句的方法。
SELECT kids.kid_id, kids.kid_name, favorite_colors FROM kids JOIN colors ON colors.id IN kids.kid_favcolors as favorite_colors
虽然它看起来对我有用,但不起作用。不知道我是远了还是真的很近。
【问题讨论】:
-
我会说你的设计在这种情况下是不正确的,如果有第三个表有 child_id 和 color_id 不是更好,这样你就可以只选择 color_id 的 child_id = x...
-
与更传统的多对多表相比,您更喜欢通过逗号分隔的 id 引用最喜欢的颜色,这是有原因的吗?
-
就像我说的,这是一个现有的基础设施。上面显示的数据是使用我能想到的第一个场景的娱乐。这个想法是尝试在不重组他们的数据库以及读取和修改它的所有脚本的情况下实施修复。如果这条路线没有解决方案,我将编写一个脚本,将逗号分隔的 id 转换为多对多表,并重写它们的所有管理脚本。
-
如果您使用的是最新版本的 MySQL(或更好的 PostgreSQL),您可以使用多对多重新设计数据库并创建一个显示旧结构的视图。然后你只需要改变他们的脚本来引用视图的名字而不是表的名字,为你节省了大量的重写工作。
标签: mysql database database-design data-structures