4

任何人都可以推荐存储一般站点首选项的最佳实践吗?例如,如果脚本没有设置默认页面标题,或者在内容框中显示的特色项目的数量,或者在上传图片时系统应该制作的缩略图大小列表。集中这些值有一个明显的好处,即允许人们轻松更改可能在许多页面上使用的首选项。

我的默认方法是将这些首选项作为属性/值对放在 *gulp* EAV 表中。

这张表不太可能变得很大,所以我不太担心性能。我的架构的其余部分是关系的。不过,它确实会产生一些该死的丑陋查询:

$sql = "SELECT name, value FROM preferences"
.    " WHERE name = 'picture_sizes'"
.    " OR name = 'num_picture_fields'"
.    " OR name = 'server_path_to_http'"
.    " OR name = 'picture_directory'";
$query = mysql_query($sql);
if(!$query) {
    echo "Oops! ".mysql_error();
}
while($results = mysql_fetch_assoc($query)) {
    $pref[$results['name']] = $results['value'];
}

任何人都可以提出更好的方法吗?

4

7 回答 7

8

在我的应用程序中,我使用这种结构:

CREATE TABLE `general_settings` (
  `setting_key` varchar(255) NOT NULL,
  `setting_group` varchar(255) NOT NULL DEFAULT 'general',
  `setting_label` varchar(255) DEFAULT NULL,
  `setting_type` enum('text','integer','float','textarea','select','radio','checkbox') NOT NULL DEFAULT 'text',
  `setting_value` text NOT NULL,
  `setting_options` varchar(255) DEFAULT NULL,
  `setting_weight` int(11) DEFAULT '0',
  PRIMARY KEY (`setting_key`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

示例数据:

mysql> select * from general_settings;
+-----------------------------+---------------+------------------------------+--------------+-------------------------------+---------------------------------------+----------------+
| setting_key                 | setting_group | setting_label                | setting_type | setting_value                 | setting_options                       | setting_weight |
+-----------------------------+---------------+------------------------------+--------------+-------------------------------+---------------------------------------+----------------+
| website_name                | website       | Website Name                 | text         | s:6:"DeenTV";                 | NULL                                  |              1 | 

setting_value我在列中存储了一个序列化值。我从 wordpress 中得到了这个技巧来保存数据库中的设置。

setting_options列用于selectradiocheckbox setting_type。它将包含一个序列化的数组值。在 admin 中,此值将显示为选项,因此 admin 可以选择其中之一。

由于我使用 CodeIgniter,我有一个模型可以从特定的 中获取单个值setting_key,因此它非常易于使用。

于 2010-02-11T14:47:37.347 回答
2

我认为这是一个完全可以接受的结构,尤其是对于像您这样的少量配置。

您还可以将这些设置存储在.ini文件中并调用parse_ini_file. 如果您需要比 INI 允许的更多的灵活性(例如:嵌套数组等),那么您可以将它们全部放入一个.php文件中并包含它。

如果您仍然想使用数据库中的配置,那么(假设只有少数行)也许只需一次读取所有记录并缓存它。

$config = array();
$result = mysql_query("SELECT * FROM config");
while ($row = mysql_fetch_assoc($result)) {
    $config[$row['name']] = $row['value'];
}
于 2010-02-11T14:35:53.437 回答
2

你这样做的方式看起来很好。

如果您担心您的查询看起来很难看,您可以尝试清理一下您的 SQL。

这是您在问题中提供的查询的更简洁版本:

SELECT name, value FROM preferences
WHERE name IN ('picture_sizes','num_picture_fields','server_path_to_http','picture_directory')";

或者也许创建一个存储函数来返回一个偏好值;例如,使用这样的存储函数:

DELIMITER $$

CREATE FUNCTION `getPreference` (p_name VARCHAR(50)) RETURNS VARCHAR(200)
BEGIN
  RETURN (SELECT `value` FROM preferences WHERE `name` = p_name);
END $$

DELIMITER ;

您可以使用如下查询获取您的偏好:

SELECT getPreference('server_path_to_http')

通过不将您的偏好硬编码(显然),您牺牲了一点速度。但是,如果您计划启用“站点管理员”来更改默认首选项 - 您应该将它们保存在数据库中。

于 2010-02-11T15:05:26.157 回答
1

我认为使用包含的文件将为您节省更多麻烦 - 特别是如果您想将数组作为变量之一包含在内。如果您打算即时更改配置变量,那么最好对它进行 db,但如果它保持相对静态,我会推荐一个“config.php”文件

于 2010-02-11T14:46:13.433 回答
1

许多应用程序,包括例如 Wordpress,都使用序列化和反序列化。它允许您创建一个非常简单的表结构,甚至可能只有一条记录(例如,为您的项目提供一个 site_id)。

数组中的所有(很多很多)变量都被序列化为字符串并存储。然后获取并反序列化回您的数组结构。

优点:你不必事先计划完美的配置结构,做很多 ALTER TABLE 的东西。

缺点:你不能通过 SQL 搜索你的序列化数组结构。

命令:

string serialize  ( mixed $value  )
mixed unserialize  ( string $str  )

也适用于您的对象。反序列化对象可以使用 __wakeup() 方法。

于 2010-02-11T15:07:03.733 回答
0

只需创建一个配置类并将您想要的每个值存储在类的变量中。

将此类包含在所有正在调用的文件中。

您现在可以在所有文件中访问此类,并且通过在所有函数中声明全局,您可以访问配置类。

希望这有帮助。

于 2010-02-11T14:32:08.080 回答
0

我解决这个问题的方法是创建一个表,其中每个配置变量都有一个单独的列,就像您对任何其他数据集所做的那样,并以这样的方式设置主键,即该表不能包含多个条目. 我通过将主键设置为只有一个允许值的枚举来做到这一点,如下所示:

CREATE TABLE IF NOT EXISTS `global_config` (
  `row_limiter` enum('onlyOneRowAllowed') NOT NULL DEFAULT 'onlyOneRowAllowed',#only one possible value
  `someconfigvar` int(10) UNSIGNED NOT NULL DEFAULT 0,
  `someotherconfigvar` varchar(32) DEFAULT 'whatever',
  PRIMARY KEY(`row_limiter`)#primary key on a field which only allows one possible value
) ENGINE = InnoDB;

INSERT IGNORE INTO `global_config` () VALUES ();#to ensure our one row exists

完成此设置后,任何值都可以使用简单的 UPDATE 语句修改,使用简单的 SELECT 语句查找,连接到其他表以用于更复杂的查询等。

这种方法的另一个好处是它允许正确的数据类型、外键和所有其他东西,以及正确的数据库设计,以确保数据库的完整性。(请确保将您的外键设为 ON DELETE SET NULL 或 ON DELETE RESTRICT 而不是 ON DELETE CASCADE)。例如,假设您的配置变量之一是站点主要管理员的用户 ID,您可以使用以下内容扩展示例:

CREATE TABLE IF NOT EXISTS `global_config` (
  `row_limiter` enum('onlyOneRowAllowed') NOT NULL DEFAULT 'onlyOneRowAllowed',
  `someconfigvar` int(10) UNSIGNED NOT NULL DEFAULT 0,
  `someotherconfigvar` varchar(32) DEFAULT 'whatever',
  `primary_admin_id` bigint(20) UNSIGNED NOT NULL,
  PRIMARY KEY(`row_limiter`),
  FOREIGN KEY(`primary_admin_id`) REFERENCES `users`(`user_id`) ON DELETE RESTRICT ON UPDATE CASCADE
) ENGINE = InnoDB;

INSERT IGNORE INTO `global_config` (`primary_admin_id`) VALUES (1);#assuming your DB is set up that the initial user created is also the admin

这可以确保您始终拥有有效的配置,即使配置变量需要引用数据库中的某些其他实体。

于 2015-10-07T15:18:45.630 回答