我该如何为这个问题设计数据库结构?

时间:2011-07-18 19:31:47

标签: php mysql database performance database-design

我正在重建拥有大量流量的网站的后台系统。

这是应用程序的核心,我构建数据库的这一部分的方式对于大量代码和即将开展的工作至关重要。下面描述的系统每天必须运行数百万次。我很感激有关此问题的任何意见。

背景是用户可以添加他或她白天吃的东西。

  

简化,这个过程或多或少是这样的:

  1. 用户到达该网站,该网站列出了他/她当天的选择(如果按照以下步骤进行输入,则会显示)。
  2. 用户可以添加一餐(由1份到无限量的食物及其数量组成)。通过搜索字段添加膳食,并以不同类型组织(如“早餐”,“午餐”)。
  3. 在用餐过程中,将显示最常用食物清单(主要由该用户,但其次也包括所有用户)以供快速选择。
  4. 膳食将存储在FoodLog表中,其中包含以下内容:id, user_id, date, type, food_data
  5. 我目前拥有的是一个庞大的数据库,其中包含将从中执行搜索的食品。食品中存储有关于通用名称(如“猪肉片”)和生产者(如“可口可乐”)的信息,以及所需的其他详细信息。

      

    问题摘要:

    我的问题是,我不知道存储数据的最佳方式,以便以我需要的方式轻松访问数据,而且数据库不会失控。

    考虑每天增加1至7餐的100万用户。为了存储每餐的每个食品,每天和每个用户可能每天创建(1 * avg_num_meals * avg_num_food_items)百万行。

    以某种压缩方式存储数据(如food_data是一个json_encoded字符串),会显着减少行数,但同时也难以创建“最常用的食物项目”列表和其他统计数据在飞行中。

    是否应将表拆分为多个表?如果是这种情况,他们将如何互动?

    该网站目前托管在中端CDN上,并使用LAMP(Linux,Apache,MySQL,PHP)骨干网。

4 个答案:

答案 0 :(得分:10)

粗略地说,您需要一个完全规范化的数据结构。您想要一个用户表,一个餐桌用餐(每餐一个条目,参考用户;您可能还希望在此表中有一餐的时间/日期),以及一个MealItems表,只是膳食和食物项目表之间的关联表。

因此,当用户进入并创建帐户时,您在“用户”表中创建一个条目。当用户报告他们吃过的膳食时,您可以在膳食表中创建记录,并在MealItems表中为他们报告的每个项目创建记录。

这种结构使得每餐都可以直接获得可变数量的物品,而不会浪费大量空间。您可以通过相对简单的查询确定膳食中物品的表示,以及确定任何一个用户在任何给定时间内消耗的物品总数。

这个规范化的表结构将支持非常多的记录,并支持对数据库的大量查询。

答案 1 :(得分:3)

首先,

  

以某种压缩方式存储数据(就像food_data一样   json_encoded string)

不是推荐的想法。随着新要求的增加,这将在未来引起无数令人头疼的问题。

你肯定应该有几张桌子。

Users
id, etc

Food Items
id, name, description, etc

Meals
id, user_id, category, etc

Meal Items
id, food_item_id, meal_id

膳食项目会使用ID将膳食与食物项目联系起来。膳食将与使用ID的用户绑定。这使得使用连接变得简单,以获得数据总数,平均值等的详细列表。如果字段被正确编入索引,这应该是支持大量记录的好模型。

答案 2 :(得分:2)

除了been said

之外
  • 明智地使用索引。正确地将这些应用到您的数据库可以显着加快对表的读取访问。
  • 考虑使用特定于语言的功能来最小化空间。你提到你正在使用mysql;考虑在适当时使用ENUM(食物类型,膳食类型)以最小化数据库大小并简化管理。

答案 3 :(得分:1)

我会把你的餐桌分成两张桌子,一张桌子每餐储存一排,第二张桌子为每顿食物用一件食品储存一排,外国人参考用餐用餐英寸

之后,只需确保在连接或WHERE子句中使用的任何表列上都有索引。