我正在讨论为网络应用程序存储网站范围设置的三种不同方法。
键/值对查找表,每个键代表一个设置。
单行设置表。
只需硬编码,因为设置不会经常改变。
关于走哪条路的想法?
答案 0 :(得分:11)
由于您的问题是用database / sql标记的,我认为您在查找和管理设置时访问sql表没有问题...在这里猜测,但我从一个表开始:
settingName value can_be_null minvalue maxvalue description
TheAnswer 42 no 1 100 this setting does...
...
如果您考虑管理大量设置,那么您需要的每项信息都需要更多信息,而不仅仅是当前值。
答案 1 :(得分:6)
我使用了一个键/值对查找表,就像你描述的那样,效果很好。
作为一个额外的好处,该表有一个“配置名称”列,它提供了一种选择/激活特定 set 配置设置的简单方法。这意味着prod
,dev
和test
都可以存在于同一个表中,但应用程序可以选择使用哪个集合。在我们的例子中,JVM参数是有意义的。在同一个DB表中存储配置设置的不同“集合”可能是有意义的;然后,它可能不会。
如果您正在考虑基于文件的配置,我喜欢INI或YAML。您仍然可以将其存储在数据库中,但您可能找不到INI或YAML列类型(就像您可能对XML一样)。
答案 2 :(得分:0)
使用#1。如果您想要基于简单类型的约束,那么也可以添加日期和数字字段,而不是将简单字符串作为值。各个属性将“知道”他们想要的价值。没有理由得到关于它的所有元。
答案 3 :(得分:0)
我会选择第一个选项 - 键/值对查找表。在我看来,这是最灵活,最具扩展性的解决方案。如果您担心在这里和那里运行许多查询以检索各种配置值的成本,您可以始终实现某种缓存,例如将整个表一次加载到内存中。除了键和值之外,您还可以添加诸如“描述”和“默认值”等列,并构建一个通用配置编辑器,在屏幕上显示描述等,以帮助用户编辑配置值。
我已经看到一些带有单行配置表的商业应用程序,虽然我没有直接经验来进行开发工作,但它让我感到不那么可扩展且难以阅读。
答案 4 :(得分:0)
如果我必须选择,我会选择第一个选项。您可以根据需要轻松添加/删除行。而单排可能最终成为一场噩梦,而且可能的可扩展性要低得多。对于选项3:您可能会后悔硬编码您的设置,所以您绝对不想自己装箱。
虽然您没有列出作为选项,但XML是否可用?它易于设置,并为您提供更多选项,因为您可以在设置中嵌套设置。
答案 5 :(得分:0)
我包括使用单独的PHP脚本,只包含设置:
$datatables_path = "../lib/dataTables-1.9.4/media";
$gmaps_utils_dir = "../lib/gmaps-utils";
$plupload_dir = "../lib/plupload-1.5.2/js";
$drag_drop_folder_tree_path = "../lib/dhtmlgoodies/drag-drop-folder-tree2";
$lib_dir = "../lib";
$dbs_dir = "../.no_backup/db";
$amapy_api_registration_id = "47e5efdb-d13b-4487-87fc-da7920eb6618";
$google_maps_api_key = "ABQIABBDp7qCIMXsNBbZABySLejWiBSmGz7YWLno";
所以这是你的第三个变种。
我实际上并没有看到你在改变这些价值方面遇到的困难;事实上,管理这些设置是最简单的方法。这不是您希望用户(具有不同角色)通过Web界面更改的数据类型。像PHPMyAdmin和Joomla这样的产品很乐意使用这种方法。
答案 6 :(得分:0)
混合方法最好。您必须考虑每个设置的最佳选择 - 这主要归结为谁将更改每个站点范围的设置。
如果您有开发服务器和实时服务器,如果它们仅在数据库中,则添加新的应用程序设置可能会很麻烦。您需要在更新代码之前更新数据库,或者让所有代码处理设置不可用的情况。显然,一个常见的站点范围设置是数据库名称,并且无法存储在数据库中!
您可以轻松地在测试和实时环境中使用不同的设置。我之前已将设置从数据库转移到文本文件中。
我建议在“硬编码”文件中使用默认值,然后可以通过键/值对查找表覆盖它。
因此,您可以在不首先更改存储在数据库中的设置的情况下推送新代码。
如果有不同数量的值或值总是同时更改,我会将值存储为JSON或其他序列化形式。
答案 7 :(得分:0)
我之前使用过混合方法,我把所有设置(不太可能改变)放到一个单独的PHP文件中。单个设置(可能会更改)作为键/值对。这样我可以减少数据库中的条目,从而减少我的整体查询时间,这也有助于我保持密钥大小。
答案 8 :(得分:0)
根据迈克的想法,这里有一个脚本来创建一个表来保存键/值对。这集成了一个机制(约束)来检查相对于min / max / not null的值是否正常,它还会自动创建一个函数fn_setting_XXXX()来快速获取相应设置的值(正确转换)。
CREATE TABLE settings
(
id serial,
name varchar(30),
type regtype,
value text,
v_min double precision,
v_max double precision,
v_not_null boolean default true,
description text,
constraint settings_pkey primary key(id),
constraint setting_unique unique(name),
constraint setting_type check (type in ('boolean'::regtype, 'integer'::regtype, 'double precision'::regtype, 'text'::regtype))
);
/* constraint to check value */
ALTER TABLE settings
ADD CONSTRAINT check_value
CHECK (
case when type in ('integer'::regtype,'double precision'::regtype) then
case when v_max is not null and v_min is not null then
value::double precision <= v_max and value::double precision >= v_min
when v_max is not null then
value::double precision <= v_max
when v_min is not null then
value::double precision >= v_min
else
true
end
else
true
end
and
case when v_not_null then
value is not null
else
true
end
);
/* trigger to create get function for quick access to the setting */
CREATE OR REPLACE FUNCTION ft_setting_create_fn_get() RETURNS TRIGGER AS
$BODY$
BEGIN
IF TG_OP <> 'INSERT' THEN
EXECUTE format($$DROP FUNCTION IF EXISTS fn_setting_%1$I();$$, OLD.name);
END IF;
IF TG_OP <> 'DELETE' THEN
EXECUTE format($$
CREATE FUNCTION fn_setting_%1$I() RETURNS %2$s AS
'SELECT value::%2$s from settings where name = ''%1$I''' language sql
$$, NEW.name, NEW.type::regtype );
END IF;
RETURN NEW;
END;
$BODY$
LANGUAGE plpgsql;
CREATE TRIGGER tr_setting_create_fn_get_insert
BEFORE INSERT OR DELETE ON settings
FOR EACH ROW
EXECUTE PROCEDURE ft_setting_create_fn_get();
COMMENT ON TRIGGER tr_setting_create_fn_get_insert ON settings IS 'Trigger: automatically create get function for inserted settings';
CREATE TRIGGER tr_setting_create_fn_get_update
BEFORE UPDATE OF type, name ON settings
FOR EACH ROW
WHEN ( NEW.type <> OLD.type OR OLD.name <> NEW.name)
EXECUTE PROCEDURE ft_setting_create_fn_get();
COMMENT ON TRIGGER tr_setting_create_fn_get_update ON settings IS 'Trigger: automatically create get function for inserted settings';