在用户表中存储用户属性

时间:2011-12-30 02:46:27

标签: database database-normalization

在与用户(具有宗教信息等属性)创建数据库时,存储这些属性及其可能值的最佳方法是什么?

以下是方法和问题:

方法1:如果您有一个用户,比如一个基督徒,您可以将此值存储在名为“Religion”的列下的users表中。这种方法的问题是在用户表中会出现很多很多“基督徒”这个词,这对我来说似乎是多余的。

问题1:此外,使用这种方法,数据库中没有任何地方存储所有可能的值,如“佛教徒”,“穆斯林”等。这将使下拉列表难以填充,如果不是不可能的话。

方法2:我想出的另一种方法是索引这些值。将users表中的“Religion”列更改为“ReligionID”并对其进行编号。 Christian = 1,穆斯林= 2等。然后使用查找值与另一个表建立外键关系。

问题2:此方法的问题在于,必须有许多表链接到users表,其中包含其他类似属性的外键值,例如眼睛颜色。虽然使用此方法填充下拉列表很容易,但这似乎创建了太多的连接,并且似乎是设计此数据库的一种丑陋方式。

最好的方法是什么?如果这些方法不是最佳的,请随意提出自己的方法。谢谢!

4 个答案:

答案 0 :(得分:1)

数据库规范化就是权衡。我看待它的方式,我总是尽可能接近3nf(即方法2)。当我的数据大小或我的性能要求发生变化时......我会考虑非规范化(即方法1)。

当你到达那一点时,你的应用程序需要对数据完整性负责...取决于你对数据库客户端的控制程度,这可能是也可能不容易。但这就是为什么你得到了巨额的报酬; - )

答案 1 :(得分:1)

我将在这里添加另一个答案,以便为讨论做出贡献。在评论中,您提到您可能需要多达10-15个连接才能获得外键的所有显示名称。

我经常使用的一种技术是加入客户端。这就是我的意思:

  1. 查询没有加入的表...这意味着您只需获取许多值的ID。
  2. 当您显示数据时,只要您需要显示文本友好值,请尝试从缓存中抓取它。
  3. 如果它不存在,那就抓住整个查找表,然后将其缓存一小时或一天(无论什么都有意义)。
  4. 缓存的值可以像字典一样简单,因此您可以从缓存中获取字典,并提取字符串说明以供显示。
  5. 这是违反直觉的...但你可以在这里获得两全其美。设计精美的数据库具有出色的数据完整性,并且性能卓越,因为您没有在服务器上进行任何连接。

答案 2 :(得分:0)

如果您的表单允许任意输入(即您尚未想到的信仰,某人可以输入自己的信仰或其他自由格式文本),方法1将正常工作。

如果您只想支持一组信仰,并且/或者您希望控制何时添加新信仰,方法2将正常工作。

您可以从方法1开始,如果您觉得合适,可以稍后将其转换为方法2。取决于您的应用程序,它的使用方式,以及它如何影响性能和完整性:在人们真正开始定期使用它之前,您可能不知道答案的问题。

答案 3 :(得分:0)

您可以使用数据库字段类型enum()来存储用户的属性,以设置宗教列表http://dev.mysql.com/doc/refman/5.0/en/enum.html。此字段仅接受您在创建列时指定的值。它还可以通过修改数据库中的列来轻松添加更多类型。

在PHP中,您可以使用http://akinas.com/pages/en/blog/mysql_enum中的此函数填充下拉列表以获取要循环的枚举值数组:

function enum_select( $table , $field ){
    $query = " SHOW COLUMNS FROM `$table` LIKE '$field' ";
    $result = mysql_query( $query ) or die( 'error getting enum field ' . mysql_error() );
    $row = mysql_fetch_array( $result , MYSQL_NUM );
    #extract the values
    #the values are enclosed in single quotes
    #and separated by commas
    $regex = "/'(.*?)'/";
    preg_match_all( $regex , $row[1], $enum_array );
    $enum_fields = $enum_array[1];
    return( $enum_fields );
}