我有一个用户设置设置,其中包含一个所谓的'属性包'我猜。 我想存储我的用户的设置。大多数用户都不会更改默认设置,所以我认为我应该制作一个默认值'对于每个设置。这样我就不会为每个用户存储每个设置的user_setting记录。
这是我的(简化的)mysql数据库:
CREATE TABLE `user` (
`user_id` INT NOT NULL AUTO_INCREMENT,
`username` VARCHAR(45) NOT NULL,
PRIMARY KEY (`user_id`)
);
CREATE TABLE `setting` (
`setting_id` INT NOT NULL AUTO_INCREMENT,
`key` VARCHAR(100) NOT NULL,
`default_value` VARCHAR(100) NOT NULL,
PRIMARY KEY (`setting_id`)
);
CREATE TABLE `user_setting` (
`user_setting_id` INT NOT NULL AUTO_INCREMENT,
`user_id` INT NOT NULL,
`setting_id` INT NOT NULL,
`value` VARCHAR(100) NOT NULL,
PRIMARY KEY (`user_setting_id`),
CONSTRAINT `fk_user_setting_1`
FOREIGN KEY (`user_id`)
REFERENCES `user` (`user_id`)
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT `fk_user_setting_2`
FOREIGN KEY (`setting_id`)
REFERENCES `setting` (`setting_id`)
ON DELETE RESTRICT
ON UPDATE CASCADE
);
INSERT INTO `user` VALUES (1, 'username1'),(2, 'username2');
INSERT INTO `setting` VALUES (1, 'key1', 'somevalue'),(2, 'key2', 'someothervalue');
在我的代码中,我可以轻松查找每个用户的每个设置。通过检查user_setting表中是否有一行,我知道这是默认值。
但有没有办法概述每个用户的所有设置? Normaly我会离开加入用户 - > user_setting - >为每个用户设置表格,但现在我没有为每个用户/设置设置user_setting记录。单个查询可以实现吗?
答案 0 :(得分:1)
如果您刚刚user
与setting
进行了笛卡尔联接,则每个用户/设置组合都会获得一行。然后只需左键加入user_setting
表,就可以在存在时获取被覆盖的值。
这样的事情:
SELECT u.user_id, s.key, s.default_value, us.value
FROM user u, setting s
LEFT JOIN user_setting us
ON(us.user_id=u.user_id AND us.setting_id=s.setting_id)
ORDER BY u.user_id, s.key
您可以使用IFNULL进一步优化此设置,以便获取设置的值,无论它是否被覆盖或默认:
SELECT u.user_id, s.key, IFNULL(us.value , s.default_value) AS value
FROM user u, setting s
LEFT JOIN user_setting us
ON(us.user_id=u.user_id AND us.setting_id=s.setting_id)
ORDER BY u.user_id, s.key
答案 1 :(得分:0)
(回答我自己的问题不是我正常工作的方式,但我不确定这是否是正确的答案,而且它是基于Paul Dixon的回答)
如上所述,用户和设置之间需要进行笛卡尔连接。正确的查询是:
SELECT u.user_id, s.key, IFNULL(us.value , s.default_value) AS value
FROM user u
CROSS JOIN setting s
LEFT JOIN user_setting us ON
(us.user_id=u.user_id AND us.setting_id=s.setting_id)
ORDER BY u.user_id, s.key;