【问题标题】:What is the best way to model the database of complex user interaction?对复杂用户交互的数据库进行建模的最佳方法是什么?
【发布时间】:2012-03-23 01:24:03
【问题描述】:

在我的 Web 应用程序中,我将拥有用户,每个用户都将拥有相册,并且每个用户还将拥有与相册相关的权限的各种用户。我不太清楚用一堆以用户 ID 为前缀的表(即 10384792_albums)对我的数据库建模是否更有效,或者我是否应该有一个包含一堆数据的表(专辑,其中包含一个用户ID)。我之前的例子是关于相册的,但相对来说,同样的事情也适用于 users 的 users。

请记住,相册本身可能有很多行数据,例如名称、描述、创建日期等。我使用的是 MySQL 和 PHP。我想这更像是一个问题,我想指出好的设计概念,它是标量而不牺牲接收数据的速度。对不起,如果问题有点模糊,我真的不知道从哪里开始,任何帮助将不胜感激。

编辑1:用户表的用户很有趣。可以这样想:对于该网站上的每个用户,他们将拥有自己独特的登录表单,客户可以在其中访问特定相册。客户永远不会使用与我网站用户相同的表单登录我的网站。

【问题讨论】:

  • 你肯定想要为每个用户单独的表。

标签: mysql database database-design


【解决方案1】:

这样的?

User table
----------
ID (primary key)
Username
(more columns with more user info)

Album table
-----------
ID (primary key)
AlbumName
(more columns with more album info)
OwnerID (foreign key to User.ID)

AlbumPermission table
---------------------
ID (primary key)
AlbumID (foreign key to Album.ID)
UserID (foreign key to User.ID)
(more columns indicating permissions)

使用此布局,您可以将用户和相册作为实体和一个链接它们的表(多对多链接表),其中包含权限。 (这个表也是一种元实体。它本身基本上没有意义,但在用户或相册的上下文中,它包含有关用户可以访问的相册或可以访问该相册的用户的信息。)

每个相册都有一个用户作为其所有者,并且在 AlbumPermission 表中链接了零个或多个用户,这些用户具有与其关联的各种权限。

编辑:

根据您对分层用户的评论,可能是这样的......

Client table
------------
ID (primary key)
ClientName
(more columns with more client info)

User table
----------
ID (primary key)
ClientID (foreign key to Client.ID)
IsAdmin (boolean)
Username
(more columns with more user info)

Album table
-----------
ID (primary key)
AlbumName
(more columns with more album info)
OwnerID (foreign key to User.ID)

AlbumPermission table
---------------------
ID (primary key)
AlbumID (foreign key to Album.ID)
UserID (foreign key to User.ID)
(more columns indicating permissions)

这里的区别是添加了一个客户表,用户记录在该表下分组。用户记录现在具有客户端记录的外键,因此每个用户都是一个客户端的成员(客户端到用户是一对多),以及一个 IsAdmin 字段指示该用户是否是管理级用户为该客户(即能够为客户创建/修改用户记录)。

预计每个客户至少有一个用户。在此设计中不一定需要一个,但在创建客户端(注册客户端的用户)时创建初始用户记录是有意义的。

您可以通过对客户和用户记录的更多动态权限进一步扩展此功能,但这应该足够简单,可以让您继续前进。

【讨论】:

  • 大卫,精彩的回应。谢谢你。但我可能应该提到,用户的用户实际上不会由用户组成(第一个表)。请看,本网站上的每个用户帐户都可以为其特定帐户创建用户。例如,本网站上的每个用户都会有一个登录屏幕供其用户使用。把它想象成我们的用户有客户,他们通过自己的表单登录。抱歉,我可能应该解决这个问题...
  • @cereallarceny:你不想把这两个东西都称为用户,这会导致进一步的混乱。我喜欢让父母称为客户的想法,每个客户可以有多个用户。我会更新答案...
  • 假设用户有多个客户端,这个模型是否仍然有效?
  • @cereallarceny:取决于“用户”和“客户”的含义。我认为在您的评论中,用户是客户的父母。在我的设计中,Client 是 User 的父级。您可以随意交换术语。只要确保你是一致的。另一方面,您是否需要子对象有多个父对象父对象有多个子对象?也就是说,客户和用户是多对多的吗?
  • @cereallarceny:在这种情况下,我在答案中的第二个设计应该可以解决问题(尽管您可以进一步修改它以满足您的需要)。如果您认为 User 应该是父级而 Client 应该是子级,则可以简单地切换 User 和 Client 概念(表名和其他表上的外键名)。这一切都归结为这些术语对所代表的业务概念的真正含义
【解决方案2】:

当然听起来不错。 我会说你的关系看起来像这样 usersTable->OneToMany->albumsTable->oneToMany->permissionsTable 然后是permissionsTable->oneToMany->usersTable 这是基于键的基本规范化。 一切都在 pk 上建立索引-除非您的联接更复杂,可以纳入数百万条记录。如果删除是计划的一部分,请制定索引优化策略并确保所有内容都保留在内存中。 如果 pk 以外的元素在连接中,请查看索引权限表(即 - pk,权限级别)。 你真的认为你需要更复杂的东西吗?

如果您真的担心 mysql 中的滚雪球现象,请查看 tcp 代理以用作 mysql 前面的队列,因为它往往无法很好地处理并发请求:请参阅此处http://flavio.tordini.org/a-more-stable-mysql-with-haproxy

建议您不要因为相关的开销而增加设计的复杂性。坚持久经考验的真实。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-04-29
    • 1970-01-01
    • 2011-04-26
    • 1970-01-01
    • 1970-01-01
    • 2010-09-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多