在数据库中存储用户首选项的正确方法是什么?

Leo*_*Han 2 php mysql sql database storage

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

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

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

ArticleID             OtherColumn
4419350002044764160   other stuff
4419351050184556544   other stuff
Run Code Online (Sandbox Code Playgroud)

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

UserEmail             ArticlesSaved                                   OtherColumn
examlple1@email.com   4419350002044764160,4419351050184556544,...     other stuff
examlple2@email.com   4419350002044764160,4419351050184556544,...     other stuff
Run Code Online (Sandbox Code Playgroud)

表示前两个用户已保存 ID 为4419350002044764160和 的文章4419351050184556544

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

我想到的另一个选择是为每个用户建立一个单独的表,我可以将他们保存到列中的文章的 ID 存储在其中,尽管这篇文章的答案是这不是很有效:数据库效率 - 每个用户的表 vs . 用户表

ent*_*ull 5

我建议为用户提供一张表,为他/她添加书签的文章提供一张表。

用户

id - int autoincrement
user_email - varchar50
Run Code Online (Sandbox Code Playgroud)

优先

id int autoincrement
article_index (datatype that you find accurate according to your  structure)
id_user (integer)
Run Code Online (Sandbox Code Playgroud)

这样,用户就可以轻松地为文章添加书签和取消书签。连接两个表是通过users 中的id 和preferences 中的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.
Run Code Online (Sandbox Code Playgroud)

  • 也许“unsigned bigint”对于 auto_increment idx 会更好 (2认同)

Joh*_*ger 5

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

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

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