Схема таблицы для пользовательских настроек - PullRequest
0 голосов
/ 09 декабря 2018

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

Вот оно:

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, и это не идеально, потому что в некоторых случаях параметр может быть представлен какфлажок в пользовательском интерфейсе, или что-то еще, что требует более конкретного типа.Я не хочу использовать жестко закодированные значения, такие как «истина» и «ложь» в подобных ситуациях, потому что это делает код хрупким.Я бы предпочел проверить конкретный логический тип.

Так что это мое предлагаемое решение.

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.Идея состоит в том, что данному параметру может быть назначен тип данных (в данном случае, логический тип данных - я мог бы создать больше таблиц, представляющих другие типы данных), и значение этого параметра будет сохранено в таблице типов данных.

На самом деле я еще не тестировал его, поэтому у меня нет запросов для этого варианта (хотя это будет несколько похоже на первый набор запросов), но теоретически это похоже на работу.

Мне было просто интересно, приходилось ли кому-то делать что-то подобное, и / или есть ли у кого-то мнение по этому проекту.

Спасибо!

1 Ответ

0 голосов
/ 09 декабря 2018

вместо bool вы можете использовать битовый формат.вам нужно будет вставить 0 или 1, но ответ будет истинным или ложным (по крайней мере, в SQL Server Express, я не знаю точно, в Qracle SQL).а для пользовательского интерфейса вы можете использовать раскрывающееся меню с истиной или ложью в зависимости от того, какой пользователь выберет вы будете вставлять в БД.

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