我有一个简单的用户设置设计,它可以正常工作。基本上,内部会创建一些设置,每个用户可以为给定的设置指定一个值。
这里是:
CREATE TABLE IF NOT EXISTS setting (
id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
label VARCHAR(191) NOT NULL,
key VARCHAR(191) NOT NULL,
created_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id)
);
CREATE TABLE IF NOT EXISTS user_setting (
id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
user_id INT(10) UNSIGNED NOT NULL,
setting_id INT(10) UNSIGNED NOT NULL,
val VARCHAR(191) NOT NULL,
created_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id),
UNIQUE INDEX idx_user_id_and_setting_id (user_id, setting_id),
CONSTRAINT fk_user_setting_user_id FOREIGN KEY (user_id) REFERENCES user (id) ON DELETE CASCADE,
CONSTRAINT fk_user_setting_setting_id FOREIGN KEY (setting_id) REFERENCES setting (id) ON DELETE CASCADE
);
在上述架构中插入值的查询如下所示:
INSERT INTO user_setting (user_id, setting_id, val)
VALUES (?, ?, ?)
ON DUPLICATE KEY UPDATE val = VALUES(val)
要检索用户的值,可以执行以下操作:
SELECT setting.*, user_setting.*
FROM setting
INNER JOIN user_setting
ON user_setting.user_id = ?
AND user_setting.setting_id = setting.id
我的问题是,现在每个设置的值都必须是VARCHAR
,这并不理想,因为在某些情况下,设置可能由UI中的复选框表示,或者其他需要更具体的类型。我不想在这种情况下使用“ true”和“ false”之类的硬编码值,因为它会使代码变脆。我宁愿检查一个具体的布尔类型。
这是我建议的解决方案。
CREATE TABLE IF NOT EXISTS setting (
id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
label VARCHAR(191) NOT NULL,
key VARCHAR(191) NOT NULL,
created_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id)
);
CREATE TABLE IF NOT EXISTS datatype_bool (
id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
val TINYINT(1) NOT NULL,
created_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id)
);
CREATE TABLE IF NOT EXISTS setting_datatype_bool (
id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
setting_id INT(10) UNSIGNED NOT NULL,
datatype_bool_id INT(10) UNSIGNED NOT NULL,
created_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id),
UNIQUE INDEX idx_steting_id_and_datatype_bool_id (user_id, datatype_bool_id),
CONSTRAINT fk_setting_datatype_bool_user_id FOREIGN KEY (user_id) REFERENCES user (id) ON DELETE CASCADE,
CONSTRAINT fk_setting_datatype_bool_datatype_id FOREIGN KEY (datatype_id) REFERENCES setting_datatype_bool (id) ON DELETE CASCADE
);
CREATE TABLE IF NOT EXISTS user_setting (
id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
user_id INT(10) UNSIGNED NOT NULL,
setting_id INT(10) UNSIGNED NOT NULL,
created_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id),
UNIQUE INDEX idx_user_id_and_setting_id (user_id, setting_id),
CONSTRAINT fk_user_setting_user_id FOREIGN KEY (user_id) REFERENCES user (id) ON DELETE CASCADE,
CONSTRAINT fk_user_setting_setting_id FOREIGN KEY (setting_id) REFERENCES setting (id) ON DELETE CASCADE
);
请注意新的datatype_bool
和setting_datatype
表。想法是可以为给定的设置分配一个数据类型(在这种情况下,为布尔数据类型-我可以创建更多表示其他数据类型的表),并且该设置的值将存储在数据类型表中。
我还没有真正测试过它,所以我没有针对该变体的查询(尽管它与第一组查询有些相似),但是从理论上讲它是可行的。
我只是想知道是否有人必须做这样的事情,和/或是否有人对此设计有意见。
谢谢!
答案 0 :(得分:0)
您可以使用位格式代替bool。您将必须插入0或1,但响应将为true或false(至少在sql server express中,我在qracle sql中不完全知道)。对于UI,您可以根据要插入数据库的用户选择使用具有true或false的下拉菜单。