【问题标题】:One table with many field or two table with fewer fields?一张有很多字段的表还是两张有更少字段的表?
【发布时间】:2016-12-24 19:07:37
【问题描述】:

我的问题很简单,目前,我有一个数据库,其中包含一个“用户”表,其中包含有关每个用户(电子邮件、用户名、密码)的重要信息,一个包含名字、姓氏、生日的“身份”表... 一个用户,以及一个“媒体”表,其中当前包含“facebook”、“googlePlus”、“twitter”、“youtube”等字段......实际上是用户所有媒体的地址。

但是,我的问题是:如果我将表“Medias”减少为 2 个字段:“address”、“type”(和“user_id”),并且类型可以是“twitter”,也许数据库会设计得更好,“脸书”...

如果我有数百个用户,最佳方法是什么?在速度和内存使用方面?

【问题讨论】:

  • 当您说媒体时,您的意思是社交媒体帐户,对吗?
  • e4c5 > 是的,对不起 :) Sammitch > 谢谢 :)

标签: php mysql sql database optimization


【解决方案1】:

经典的狭义与广义辩论。让我们以您当前的设计为例。您有一个宽表,其中包含 user_id 和其他四个用于社交媒体链接的列。也许是这样的:

数据

medias
  user_id int
  twitter varchar
  google_plus varchar

如果 varchar 列可以为空,则您的存储处于最佳状态。如果您的用户没有 twitter 帐户但有 google 帐户,则只有 google_plus 列会有数据。其他为空,varchar空字段不占用任何存储空间。

现在让我们来看看窄设计

medias
  user_id
  media_type
  link

这有三列,但它们总是被填满。您计划用“twitter”、“google”等填充 media_type。这意味着您使用的存储空间比宽设计要多。如果用户有两个社交媒体帐户,则 user_id 会存储两次。您可以通过使用常量来减少这一点。

twitter=1
google_plus=2
yahoo=3

将这些数字存储在 media_type 列中。然后该字段可以是smallint,它占用的空间非常小。如果您预计会有大量媒体帐户,则不能使用这样的常量,而是需要为它们创建一个单独的表并在此表中仅输入您的 ID。

索引

拥有广泛的设计并想知道有多少用户拥有 google 帐户或 twitter 帐户?现在您需要在 twitter 和 google_plus 列上都有一个索引,而这些索引将会非常大。与索引的大小相比,您通过存储空值保存的内容将非常小。 (可以通过仅索引列的一部分来克服)

试试这样的方法:找出有多少用户至少拥有三个社交媒体帐户。这是一个宽表的艰难查询,不是吗?但是很简单,桌子很窄。

另一方面,窄表猜测只有 media_type 列需要索引,这是一个非常小的索引。如果你做这种查询,你肯定想要一个窄表。

其他注意事项

假设 Yahoo 倒闭了,您会希望将该列删除到您的宽表中,对吗?曾经尝试过在具有 100 万行的表上删除一列吗?您输入 alter table 命令,出去吃午饭,当您回来时,您会发现它仍在运行,而您的网站没有响应。

假设另一家社交媒体公司启动并接管了 Facebook。尝试添加一列。和上面的结果一样

最后,对于数百行来说,这些都不重要,但实践使用正确的设计总是一个好主意。

【讨论】:

  • 哇侯!谢谢你的时间 :)。实际上,我肯定会在我的表“媒体”中添加列,因为我的网站功能是利用每个用户的所有媒体。所以明天,也许我会编写一个支持 github 帐户的插件(示例)。并在我的表中添加一行“github”。因此,根据您的回答,我认为最好的方法是窄桌。你同意吗?
  • 哈哈,好吧,我会那样做的;)
【解决方案2】:

你可以选择任何一种方式,这只是一个偏好问题。就性能而言,它可能可以忽略不计,但我认为一张包含所有内容的表将是最有效的。您可能希望创建一个包含以下列的媒体表:

用户 ID、媒体名称、媒体值

1,谷歌,whoever@google.com

1、youtube、youtube/我的频道

这可能更具可扩展性,您只需为用户添加媒体(如果有)。

【讨论】:

    【解决方案3】:

    我建议使用许多具有 3-9 列的表。一切都取决于你想要什么。 任何或多或少都会是无效的,因为访问表格并以人类的身份阅读表格会很耗时。 此外,桌子越重,加载所需的时间就越长。 根据您要保存的内容找到要使用的最佳且有效的列数,例如,与将所有内容保存在一个表中相比,为每个类别创建一个表会更好。 速度和友好。 RAM 和处理能力取决于您的流量和 php 计算(如果复杂),并且仅在您与数千或数百万用户打交道时才重要。 万事如意

    【讨论】:

    • 我的贡献如下: 1. 我在 cmets 中提供了一个链接,指导 OP 研究数据库规范化。这是一个非常广泛的概念,并且在链接中比我能够更好地解释。 2. 我否决了你糟糕、糟糕的想法,这样其他人就不太可能看到它们。 3. 我评论了你所说的一切都被证明是错误的,因此任何确实设法向下滚动到这里的人都会被警告不要实际尝试实施其中任何一个。
    • 我到底哪里错了?并且不要将我重定向到其他地方,这几乎与不发表评论一样无用。
    猜你喜欢
    • 1970-01-01
    • 2011-06-20
    • 2011-03-14
    • 2012-04-04
    • 1970-01-01
    • 2011-04-30
    • 2012-02-18
    • 2018-11-11
    • 1970-01-01
    相关资源
    最近更新 更多