16

我只是想知道为我的 Web 应用程序存储用户特定设置的最佳方式是什么?只是用户可能有的偏好。我想到了两个选择:

  1. 用户表- 我将为我的用户准备一个表。创建一个名为“preferences”的列并将序列化数据存储在 key => value 对中

  2. 设置表- 有一个名为 settings 的单独表,其中包含 user_id 列。以同样的方式保存设置

任何输入将不胜感激。谢谢 :)!

--

编辑:只是补充一点,如果我没有序列化/json 或任何要放入数据的数据,我必须为每个设置都有一个列。

4

6 回答 6

29

对于始终每个Users用户设置的任何内容,您应该按照通常的规范化将其保留在表中。至于可选配置,我倾向于喜欢下面的表结构:

TABLE Users:
  id INT AI
  name VARCHAR
  ...

TABLE User_Settings
  user_id INT PK,FK
  name VARCHAR PK
  type BOOL
  value_int INT NULL
  value_str VARCHAR NULL

WhereUser_Settings.type指定是否应该引用整数或字符串字段。

IE:

INSERT INTO Users (id, name) VALUES (1, 'Sammitch');
INSERT INTO User_Settings (user_id, name, type, value_int) VALUES (1, 'level', 1, 75);
INSERT INTO User_Settings (user_id, name, type, value_str) VALUES (1, 'lang', 0, 'en');

对于插入/更新问题:

INSERT INTO User_Settings (user_id, name, type, value_str) VALUES (1, 'lang', 0, 'fr')
  ON DUPLICATE KEY UPDATE value_str='fr';

此外,正如大多数其他人所说,序列化和存储首选项并不是一个特别好的主意,因为:

  1. 您无法通过查询检索单个值,您必须检索整个序列化字符串,对其进行反序列化并丢弃不必要的数据。
  2. 它很容易损坏,并且很难从中恢复。
  3. 编写原始查询是一件很痛苦的事,即:全局修复某个设置。
  4. 您将本质上是表格数据的内容存储在单个表字段中。

2016 年 9 月回顾编辑:

在此期间,我与人们就如何最好地存储可选设置以及上面定义的通用表结构进行了一些争论。

虽然该表结构不是完全的,但也不是很好。它试图充分利用糟糕的情况。只要您可以适应这些设置,可选设置的序列化就可以工作:

  1. 一次性加载所有内容,无需挑选或选择。
  2. 不可索引,不可搜索或易于修改

然后,您可能会考虑optional_settingsUsers包含设置的序列化 [例如:JSON] 形式的表中添加一个字段。您确实权衡了上述内容,但这是一种更直接的方法,您可以存储更复杂的设置。

此外,如果您使用像TEXT存储这样的 LOB 类型,则数据不一定存储在“行中”,至少在 MySQL 中。

无论如何,由决定您的应用程序的要求和约束是什么,并根据这些信息做出最佳选择。

于 2013-01-02T16:21:40.747 回答
2

这完全取决于数据库的设置和架构。无论您做什么,我都建议您不要按照您的建议 1 序列化数据,如果您序列化数据,您将无法再针对它编写查询,并且您需要使用与序列化它的语言相同的语言来反序列化它(或编写类似的东西)那种语言)。

我推荐的选项是将设置放在 users 表中,每列 1 个设置。这样做的缺点是当您向应用程序添加新设置时,您必须编写一些 DDL 脚本来添加新列。这样做的一个(非常好的)优点是每个设置都可以有自己的数据类型。如果此设置是可选的,这也会产生存储损失。

正如您所建议的,另一个选项可能是使用设置表,主键为 (user_id, setting_name),第三列设置值。此解决方案假定所有设置都具有相同的数据类型。您无需编写 DDL 脚本来添加新设置,只需使用新的键名即可。

于 2013-01-02T16:08:03.330 回答
1

这总是同一个问题:您需要多久更改一次这些数据?在我看来,拥有一个单独的表总是一个很好的解决方案,因为它分隔了应用程序的不同方面。

恕我直言,拥有preferences列不是一个好主意,因为每当您的用户更改其设置时,您都必须序列化他的所有数据以将它们存储在users表中,无论它只是update一个单独的。如果您真的想将所有内容存储在 中users,则应将设置划分为不同的列。

于 2013-01-02T16:07:42.060 回答
0

第二个选项,但通过单独存储设置进行了修改。不要在字段中存储序列化数据,因为在这种情况下是不好的做法。

想一想:您拥有它,并且将用户所在的国家/地区存储在那里,或者它是否已注册到您的时事通讯中。稍后..您需要知道有多少人来自俄罗斯。你做什么工作?把它们一一解码并增加一个计数器?(或者使用你的第二种方法,只运行一个简单的 SELECT COUNT(id) 查询?)

于 2013-01-02T16:06:42.920 回答
0

我会使用设置表,因为它可以让以后更容易访问。当您尝试在单个列中创建名称值对等操作时,您可能会在稍后尝试执行设计查询以访问数据时遇到问题。

于 2013-01-02T16:07:04.233 回答
0

这可能不适合您当前的情况,但 NoSQL 数据库(如 Mongo)非常适合此情况。例如,这是一个 mongo 数据库,每个用户对象实际上可以具有不同的属性,您仍然可以搜索它们。

也就是说,对于您所处的情况,过去我一直遵循这里的其他答案的建议,并有一个单独的表格。这可以通过两种方式完成,有一个单独的表,您可以更方便地修改其中的列,然后加入它。或者,一个更简单的解决方案,有一个单独的表,例如,

用户、参数、值。

然后每个用户可以有不同的额外价值。

最佳方法取决于您所需的性能等。

于 2013-01-02T16:14:00.423 回答