mysql中用于存储多个用户随时间变化的身高和体重(等)的数据结构

mysql中用于存储多个用户随时间变化的身高和体重(等)的数据结构,mysql,structure,normalization,Mysql,Structure,Normalization,我正在尝试为我的localhost开发一个应用程序,在该应用程序上,我可以跟踪身体属性(ht、体重、身体水分、身体脂肪等)随时间的变化,以便与热量摄入进行比较,以便制定膳食计划等。以下是我现在拥有的: DB surname TBL home memberID (tiny int, 1, auto increment, primary key) name (varchar, 30) gender (char, 1) ->value should be m or f, but t

我正在尝试为我的localhost开发一个应用程序,在该应用程序上,我可以跟踪身体属性(ht、体重、身体水分、身体脂肪等)随时间的变化,以便与热量摄入进行比较,以便制定膳食计划等。以下是我现在拥有的:

DB surname
 TBL home
  memberID (tiny int, 1, auto increment, primary key)
  name (varchar, 30)
  gender (char, 1) ->value should be m or f, but this isn't defined anywhere
  birthdate (datetime)
为了在一段时间内存储物理数据,我考虑过使用一个带有三列主键(date、person、type of measurement)的表,每列上都有常规的单列索引,这样我就可以查找日期、person或measurement type的所有条目。像这样:

DB surname
 TBL stats (or something to that effect)
  date (datetime, PK1, index)
  memberFK (tiny int, 1, PK2, index)
  type (varchar, 3, PK3, index) -> possible values should be ht | wt | fat | wat maybe others will also become necessary
  value (decimal, 4/1) -> store all values in nnn.n format in a particular system (ie metric) and do any conversions, add units, etc when the data is called
这似乎仍然会产生大量多余的冗余,因此我考虑将每个用户的测量值存储在他们自己的数据库中的一个表中,如下所示:

DB user1
 TBL stats
  date (datetime, PK1, index)
  type (varchar, 3, PK2, index)
  value (decimal, 4/1)
这似乎通过从外键(以及整个表)中删除一列来稍微清理它,但也阻止我在该表和其他非用户特定的营养相关表之间使用外键。另一方面,我计划为其他家庭主题开发应用程序,其中包含一般数据和特定于用户的数据,因此,如果有这样的数据库之间使用数据的好方法,这可能是最好的方法


因此,这两种方法对我来说都不太合适,但我不知道如何使它们更好。我倾向于第二个示例,前提是我能够找到保持数据完整性的方法。请对您认为有帮助的建议发表意见。谢谢大家!

我会这样做的

DB healthstats
    TABLE user
        memberID (int*, auto increment, unsigned zerofill, primary key)
        name (varchar, 50)
        gender (char, 1) ->value should be m or f, but this isn't defined anywhere
        birthdate (datetime)

    TABLE reading
        readingID (int*, auto increment, unsigned zerofill, primary key)
        memberID (int*, FK: TABLE user)
        date (datetime)

    TABLE stat
        statID (int*, auto increment, unsigned zerofill, primary key)
        readingID (int*, FK: TABLE reading)
        type (varchar, 3)*
        value (decimal 4.1)*
*
这些数据类型由您决定,只需确保主键和外键匹配即可

stat
是一种测量(例如身高、体重、体脂等)。
读数
定义为同时进行的一次或多次
stat
测量


请注意,这一切都在同一个数据库中,它包含三个表。

拥有多个具有相同结构的表几乎总是一个坏主意,因为这将阻止您以规范形式访问来自多个此类表的数据。假设您想要夏季和冬季之间的平均重量差,那么如果您按用户划分表,则必须迭代所有表


我不确定你在你的方法中看到了“多余的冗余”。但是,您可能会更习惯于将各种参数作为列而不是枚举列的值的表。例如,介绍ht、wt、fat、wat列以及您可能需要的其他列。这样,所有这些值就不局限于一个数字类型,也不会在同一列中存储完全不相关单位的值。对于缺少的值,您仍然可以使用
NULL
,这样,如果您不想强制执行该策略,您就不会被迫始终提供所有值。由于整个集合只能显示一次日期和人员,因此只有在您通常对一个人进行多次读取时才有意义。

对于每个用户使用一个数据库似乎是严重的过度使用。您对数据库的典型设计有多熟悉?博客或论坛包的数据库架构可能值得检查。您知道
TINYINT
最多可容纳127个用户(255个未签名用户)?不是很有野心。。。每个用户都有一个db(甚至一张表),这就是疯狂所在。。您对
(成员id、度量值类型、日期、值)
的第一直觉是准确的,一点也不复杂。我正在学习数据库设计,我已经断断续续地使用mysql大约3年了。我还计划为每个用户存储诸如个人歌曲评级之类的内容,我可能会为每个用户存储诸如喜爱的食物之类的内容,以便在进行膳食规划时快速访问,或者存储特定于用户的其他类型的数据,这就是为什么我考虑为每个用户建立单独的数据库。Tiny Int:这是为家庭或家庭使用的,不是为任何使用互联网的用户使用的,所以Tiny Int是完美的,不是吗?我遗漏了什么吗?Wrikken:3列外键对于只定义一列(值)似乎有点过分了,我错了吗?我明白你所说的跨表拆分数据。在我的第一个示例中,我看到的多余冗余是,只为两个人保留记录,对于我们进行测量的每一天,将至少有8个条目添加到表中,所有条目都具有相同的日期,4个条目具有相同的成员id(另外4个条目具有其他id)。家庭规模越大,跟踪的特征(血糖等)越多,添加记录的频率越高,记录的追溯时间越长,情况就越糟。我确实考虑过每一个测量都有一个列,但是由于零化问题而丢弃它。至于数据类型,4/1个十进制似乎对所有类型都很好:HT=63.5(我的PHP脚本知道HT=英寸),WT=118.2(WT=通过PHP的LBS),WAT=53.2(WAT=%PHP),FAT=25.6(FAT=%PHP)。脂肪和水永远不会超过100%,并且不需要超过一个小数点的精度,ht和wt永远不会需要超过3位数字,也不需要超过一个精度点。让一个表将度量类型与其单位相匹配可能是有意义的,但我还不能确定这一点。如果将这8行拆分为两个表,那么这8行仍然是8行,因此您的拆分建议不会减少冗余。如果担心
NULL
s占用太多空间,可以创建具有可变行长的表。然后将只有一个字节来指示最多八列的
NULL
ness,这些列没有额外的空间。对于
ENGINE=MyISAM
指定
ROW\u FORMAT=DYNAMIC
。我不确定InnoDB内部的
InnoDB
Internal。根据jedwards提供的答案,Reads表中有两个条目,stats表中有8个条目,区别在于日期只输入了两次(允许不同的时间)