经典的狭义与广义辩论。让我们以您当前的设计为例。您有一个宽表,其中包含 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。尝试添加一列。和上面的结果一样
最后,对于数百行来说,这些都不重要,但实践使用正确的设计总是一个好主意。