【问题标题】:What is the proper way to store user preferences in a database?在数据库中存储用户偏好的正确方法是什么?
【发布时间】:2015-03-20 04:07:38
【问题描述】:

我有一个 MySQL 数据库,用于存储我的服务提供的用户电子邮件和新闻文章。我希望用户能够保存/收藏他们以后想阅读的文章。

我的计划是在我存储用户电子邮件的表中创建一个列,其中包含以逗号分隔的唯一 ID 字符串,其中唯一 ID 是在添加到每篇文章时分配给它们的值数据库。这些文章存储在单独的表中,我使用UUID_SHORT() 生成BIGINT 类型的唯一ID。

例如,假设在我存储文章的表中,我有

ArticleID             OtherColumn
4419350002044764160   other stuff
4419351050184556544   other stuff

在我存储用户数据的表中,我会有

UserEmail             ArticlesSaved                                   OtherColumn
examlple1@email.com   4419350002044764160,4419351050184556544,...     other stuff
examlple2@email.com   4419350002044764160,4419351050184556544,...     other stuff

表示前两个用户保存了 ID 为 44193500020447641604419351050184556544 的文章。

这是在数据库中存储此类内容的正确方法吗?如果有更好的方法,谁能解释一下?

我正在考虑的另一个选项是为每个用户创建一个单独的表,我可以将他们保存的文章的 ID 存储到一个列中,尽管这篇文章的答案是这不是很有效:Database efficiency - table per user vs. table of users

【问题讨论】:

  • 为什么不为 UserArticle 创建单独的 XREF 表,在那里您可以存储 UserID 和相应的 ArticleID。
  • 外部参照表是否与常规表相同?我仍在浏览这个网站以了解它们:developerdrive.com/2011/12/the-xref-table-for-mysql
  • 是的,只是一个带有交叉引用的常规表。像这样:CREATE TABLE UserArticle(UserID INT, ArticleID BIGINT)

标签: php mysql sql database storage


【解决方案1】:

我会为用户推荐一张桌子和一张他/她收藏的文章。

用户

id - int autoincrement
user_email - varchar50

偏好

id int autoincrement
article_index (datatype that you find accurate according to your  structure)
id_user (integer)

通过这种方式,用户可以轻松地为文章添加书签和取消添加书签。通过 users 中的 id 和首选项中的 id_user 连接两个表。确保首选项/书签中的每一行都是一篇文章(不要做任何逗号分隔的操作)。这样做可以为您节省很多时间/并发症 - 我保证!

获取用户书签页面的典型查询如下所示。

SELECT u.id,p.article_index,p.id_user FROM users u
LEFT JOIN preferences ON u.id=p.id_user
WHERE u.id='1' //user id goes here, make sure it's an int.. apply appropriate security to your queries.

【讨论】:

  • 也许 unsigned bigint 更适合 auto_increment idx
  • 因为一个 id(尤其是一个自动递增的)永远不会是负数(因此unsigned)并且仅仅是因为BIGINT 允许存储更多更多的记录:cf the signed int max vs unsigned bigint max => 2,147,483,64718,446,744,073,709,551,615。我知道,signed int max 在 99.99% 的情况下就足够了,但因成功而失败是一件可怕的事情,在这种情况下:相对容易避免(或至少推迟)
  • 好吧.. 我明白了。我总是对我的唯一 ID 使用自动增量。我发现它非常方便,并且无论如何肯定可以创建相当大的数字。至少总是满足我的需求!
  • @PiJoules: 取决于您的数据库设置 => 如果您在集群上工作,您可以使用 auto_increment,但 id 的顺序并不总是反映创建记录的顺序。有时您可以使用不包含 AI 字段的唯一索引,而是引用相关表的 id 组合。那些表可以使用 AI 字段,不过...... TL;TR:这是你的选择
  • 我的偏好是使用 auto_increment 作为每个条目的 id,而 Elias 建议使用不同的方法。就像我说的,我发现自动递增唯一 ID(指特定条目)非常方便。
【解决方案2】:

“正确”是一个古怪的词,但您建议的方法存在很大缺陷。生成的数据库甚至不再满足第一范式,并且即使您没有立即看到它们也可以预测实际问题。您可能会遇到的一些问题是

  • 每个用户可以“保存”的文章数量将受到ArticlesSaved 列的数据类型的限制;
  • 您将遇到重复“已保存”文章 ID 的问题;和
  • 关于保存哪些文章的查询将更难以表述,并且可能运行速度较慢;部分原因是
  • 您无法对ArticlesSaved 列进行有意义的索引。

建模多对多关系(例如用户和文章之间)的常用方法是通过单独的表。在这种情况下,这样的表将为每个(用户、保存的文章)对保留一行。

【讨论】:

  • 感谢您列出我会遇到的问题
【解决方案3】:

在数据库字段中以 CSV 格式保存数据(几乎)从来都不是一个好主意。你应该有 3 张桌子:

  • 1 个表格描述用户,其中包含与用户直接相关的所有内容
  • 1 个表格描述带有相关数据的文章
  • 1 个表,其中 2 列“userid”和“articleid”链接两者。如果用户为 10 篇文章添加书签,则此表将有 10 条记录,每次都有不同的 aticleid。

【讨论】:

    猜你喜欢
    • 2020-01-19
    • 2013-02-01
    • 2011-05-29
    • 2016-12-15
    • 1970-01-01
    • 2016-05-31
    • 2020-01-25
    • 1970-01-01
    相关资源
    最近更新 更多