数据库设计:多个表与单个表

Sac*_*hin 12 mysql database scalability

我正在建立一个网站,其中有不同类型的项目,如博客,帖子,文章等.用户可以将他们中的任何一个设置为他/她的最爱.现在当我接近这个东西时,我有两个选择

  1. 为每种类型的对象创建一个用户收藏夹表.
  2. 为所有用户创建所有类型对象的公用表.

第一个结构的问题是我将不得不查询很多表来显示特定用户的收藏夹.但它可以让我轻松地将收藏夹分为不同的类别.

但是,如果我必须在一个页面上显示所有收藏夹并将它们全部合并,根据时间排序,则这变得困难.但是如果我使用第二个模型,我可以很容易地获得最新的收藏夹,并且根据对象类型对它们进行分组并不困难,但是我会有一个大的表站点.

这两种策略中哪一种更具可扩展性.

第一个需要多个数据库查询,第二个需要一个大的单个表.

如果它有帮助,我正在使用 MySql

Alf*_*oVR 8

您似乎已经知道了答案,但请记住,保持您设计的系统易于修改,因为业务模型总是随着时间的推移而变化,或者最终会失败(这是一种概括,但您明白了).其中的一个必然结果是,如果你制作一个刚性模型,无论是快速还是慢速,它都是僵化的,变化会更加困难,最终用户也不会看到差异,因此不会实现金钱/幸福的变化,除非这是一个非常糟糕的变化.你的问题不是技术问题,而是查询在引擎上工作的方式,而不是一个哲学问题,容易改变而不是表观速度.问问自己,拥有标准化数据库的优势是什么?考虑一个干净的架构和设计,性能是当今世界中最少的问题,因为处理更便宜,存储也是如此.但设计很昂贵.规范化是为了使系统不依赖于最后时刻的决策,而是依赖于结构化设计过程.大表对于MySql来说并不是什么大问题,但它们对于维护,修改和扩展来说是一个大问题.它不只是添加一个列,而是关于数据本身的刚性结构.最终,您将只添加包含索引的列,这些索引将指向小表.无论如何,MySql将抄袭所有数据.所以我会选择第一个,很多小桌子,多对多.


bow*_*rae 5

我的网站上有这个设计。我的模块有:新闻、文章、视频、照片、下载、评论、测验、民意调查等。所有这些都在单独的表格中。我有一个喜欢的表,用户可以在其中喜欢或不喜欢某个帖子(在您的情况下为收藏夹)。获取这些的查询并不那么复杂。

首先,我的大部分模块表的结构都是相同的:

  • ID
  • 标题
  • 内容
  • user_id(作者)
  • 日期
  • ETC

但有一些例外,有时标题被称为问题,或者没有内容栏。这不会引起任何问题。

我的喜欢表是这样设置的:

  • ID
  • 页面ID
  • module_id(它来自哪个表...我有一个模块表,其中每个模块都有一个标题、关联的 id、目录等)
  • post_id(对应模块表id)
  • user_id(点赞或发帖的用户)
  • 状态(0 = 喜欢,1 = 不喜欢)
  • 日期(喜欢/不喜欢发生的时间)

模块表示例:

  • ID
  • 标题
  • 目录
  • 帖子类型

例子

id      title              directory         post_type
 1       News                news               news
 2     Episode Guide       episodes            episode
 3       Albums           discography/albums    album
Run Code Online (Sandbox Code Playgroud)

本质上,您的系统会有类似的设置,根据需要修改表结构。

查询以获取特定用户的所有喜欢或收藏:

$getlikes = mysql_query("SELECT DISTINCT post_id, module_id, page_id FROM likes WHERE user_id = $profile_id ORDER BY id DESC LIMIT $offset, $likes_limit", $conn);
$likes = mysql_num_rows($getlikes);

if($likes == "0"){
echo "<br><Center>$profile_username does not have any liked posts at this time.</center><BR>";
}
else {
echo "<table width='100%' cellspacing='0' cellpadding='5'>

<Tr><th>Post</th><th align='center'>Module</th><th align='center'>Page</th><tr>";

while ($rowlikes = mysql_fetch_assoc($getlikes)) {
   // echo data

$like_page_id = $rowlikes['page_id'];
$like_module_id = $rowlikes['module_id'];
$like_post_id = $rowlikes['post_id'];


// different modules have different fields for the "title", most are called title but quotes is called "content" and polls is called "questions"
if($like_module_id == "11"){
$field = "question";
}
elseif($like_module_id == "19"){
$field = "content";
}
else{
$field = "title";
}





// FUNCTIONS
PostURL($like_page_id, $like_module_id, $like_post_id);
ModTitle($like_module_id);
ModTable($like_module_id);
ModURL($like_page_id, $like_module_id);
fpgURL($like_page_id);


$getpostinfo = mysql_query("SELECT $field AS field FROM $mod_table WHERE id = $like_post_id", $conn);
$rowpostinfo = mysql_fetch_assoc($getpostinfo);
$like_post_title = $rowpostinfo['field'];

// Using my "tiny" function to shorten the title if the module is "Quotes"
if($like_module_id == "19"){
Tiny($like_post_title, "75");
$like_post_title = "\"$tiny\"";
}


if(!$like_post_title){
$like_post_title = "<i>Unknown</i>";
}
else {
$like_post_title = "<a href='$post_url'>$like_post_title</a>";
}

echo "<tr class='$altrow'>
<td>$like_post_title</td>
<td align='center'><a href='$mod_url'>$mod_title</a></td>
<td align='center'>$fpg_url</td>


</tr>";

$altrow = ($altrow == 'altrow')?'':'altrow';

} // end while

echo "<tr><Td align='center' colspan='3'>";

// FUNCTIONS - Pagination links
PaginationLinks("$cs_url/users/$profile_id", "likes");

echo "</td></tr></table>";

} // end else if no likes
Run Code Online (Sandbox Code Playgroud)

好吧,这对你来说可能很难理解,因为我有很多自己的变量,但基本上它从喜欢表中获取模块 id 和帖子 id,然后运行查询来获取帖子的标题和我想要的任何其他信息就像原作者一样。

我设置了“模块”函数,如果您为其提供了 id,它将返回模块的 url 或标题。