Как сохранить настройки сайта в базе данных? - PullRequest
13 голосов
/ 01 августа 2011

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

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

  • Плюсы Простота реализации
  • Минусы Нет ограничений на отдельные настройки

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

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

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

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

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

Ответы [ 9 ]

11 голосов
/ 06 февраля 2014

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

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

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

7 голосов
/ 01 августа 2011

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


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


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

0 голосов
/ 13 июля 2015

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

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

0 голосов
/ 06 февраля 2014

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

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

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

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

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

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

0 голосов
/ 01 февраля 2014

Я, в том числе, использую отдельный скрипт 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";

Так что это ваш третий вариант.

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

0 голосов
/ 01 августа 2011

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

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

0 голосов
/ 01 августа 2011

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

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

0 голосов
/ 01 августа 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...