Подтвердить что ты не робот

Как сохранить настройки сайта в базе данных?

Я обсуждаю три разных подхода к сохранению настроек sitewide для веб-приложения.

Таблица поиска пары ключ/значение, каждая клавиша представляет настройку.

  • Простые Простые для реализации
  • Против Нет ограничений для отдельных настроек

Таблица настроек одной строки.

  • Плюсы В настройках по умолчанию и ограничениях
  • Минусы - Множество настроек будет означать много столбцов. Не уверен, что Postgres будет иметь проблемы с этим

Просто жестко запрограммируйте его, так как настройки не будут часто меняться.

  • Плюсы Простота настройки и добавления дополнительных параметров.
  • Минусы Намного сложнее изменить

Мысли о том, куда идти?

4b9b3361

Ответ 1

Я использовал таблицу поиска пары ключ/значение в значительной степени так, как вы описываете с хорошими результатами.


В качестве дополнительного бонуса в таблице был столбец "имя конфигурации", который предоставил простой способ выбора/активации определенного набора параметров конфигурации. Это означало, что prod, dev и test могут жить в одной таблице, хотя именно приложение должно выбрать, какой набор использовать. В нашем случае аргумент JVM имел смысл. Возможно, имеет смысл хранить разные "наборы" настроек конфигурации в той же таблице DB; то, возможно, это не так.


Если вы думаете о конфигурации на основе файлов, мне нравится INI или YAML. Вы все равно можете сохранить его в базе данных, хотя вы, вероятно, не найдете тип столбца INI или YAML (как это было бы возможно для XML).

Ответ 2

Поскольку ваш вопрос помечен как база данных /sql, я предполагаю, что у вас не возникнет проблем с доступом к таблице sql для поиска и управления настройками... Угадайте здесь, но я бы начал с таблицы типа:

settingName  value   can_be_null   minvalue maxvalue  description
TheAnswer      42       no            1       100     this setting does...
...

Если вы думаете об управлении большим количеством настроек, вам потребуется больше информации о каждом из них, чем о их текущем значении.

Ответ 3

Я включаю в себя использование отдельного PHP script только с настройками:

$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";

Итак, это ваш третий вариант.

Я действительно не вижу, что вы усердно пытаетесь изменить эти значения; на самом деле это самый простой способ администрировать эти параметры. Это не те данные, которые вы хотите, чтобы ваши пользователи (с разными ролями) менялись через веб-интерфейс. Такие продукты, как PHPMyAdmin и Joomla, с радостью используют этот подход.

Ответ 4

Перейдите к # 1. Если вам нужны ограничения на основе простых типов, то вместо того, чтобы иметь простую строку в качестве значения, добавьте также поле даты и числа. Отдельные свойства будут "знать", какую ценность они хотят. Нет причин получать всю информацию об этом.

Ответ 5

Я бы пошел с первой опцией - таблицей поиска пары ключ/значение. Это, по-моему, самое гибкое и масштабируемое решение. Если вас беспокоит стоимость запуска множества запросов здесь и там для получения различных значений конфигурации, вы всегда можете реализовать какой-то кеш, например, сразу же загрузить всю таблицу в память. Помимо ключа и значения, вы можете добавить столбцы, такие как "Описание" и "Значение по умолчанию" и т.д., И создать общий экранный редактор, который отображает описания и т.д. На экране, чтобы помочь пользователю отредактировать конфигурацию значения.

Я видел некоторые коммерческие приложения с однострочной конфигурационной таблицей, и, хотя у меня нет прямого опыта в работе над разработкой, это показалось мне менее масштабируемым и более трудным для чтения.

Ответ 6

Если бы мне пришлось выбирать, я бы выбрал первый вариант. Легко добавлять/удалять строки по мере необходимости. В то время как одна строка может стать кошмаром и, вероятно, намного менее масштабируема. И для варианта 3: Возможно, вы будете сожалеть о жестком кодировании ваших настроек в будущем, поэтому вы определенно не хотите вставлять себя.

Хотя вы не указали в качестве опции, доступен ли XML? Он легко настраивается и дает несколько дополнительных параметров, так как вы можете устанавливать настройки в настройках.

Ответ 7

Лучше всего использовать смешанный подход. Вы должны учитывать, что лучше всего подходит для каждой настройки, что в значительной степени сводится к тому, кто изменит настройки каждого сайта.

Если у вас есть сервер разработки и живой сервер, добавление новых настроек приложения может быть неудобным, если они находятся исключительно в db. Вам необходимо либо обновить базу данных, прежде чем обновлять код, либо иметь весь код, обрабатывающий ситуацию, когда параметр недоступен. Очевидно, что одним общим параметром sitewide является имя базы данных и не может быть сохранено в базе данных!

Вы можете легко получить различные настройки в тестовой и живой среде. До этого момента я удалил настройки из базы данных и в текстовые файлы.

Я бы рекомендовал иметь значения по умолчанию в файле с жестким кодом, который затем переопределяется таблицей поиска пары ключ/значение.

Таким образом, вы можете активировать новый код без необходимости изменения настроек, хранящихся в базе данных.

Если существует различное количество значений или значения, которые всегда меняются в одно и то же время, я бы сохранил значения как JSON или другую сериализованную форму.

Ответ 8

Я использовал смешанный подход, прежде чем я включил все настройки (которые вряд ли могут измениться) в отдельный файл PHP. Отдельные настройки (которые могут измениться) в качестве пары ключ/значение. Таким образом, я мог бы сократить записи из базы данных, тем самым сократив общее время запроса, и это помогло мне сохранить размер ключа небольшим.

Ответ 9

Следуя идее Майка, вот script, чтобы создать таблицу для сохранения пар ключа/значения. Это интегрирует механизм (ограничение), чтобы проверить, что значения в порядке по отношению к 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';