选择一种存储用户档案的方法?

7

我正在为一个网站设计用户个人资料系统,正在考虑采取哪种更好(可扩展)的方法。我想到了两种解决方案,希望得到意见或指出可能遗漏的内容。

以下创建表语句并不可执行,仅用于说明所涉及表格的布局。

我的初步想法是这样的:

CREATE TABLE user(
    id INT UNSIGNED NOT NULL AUTO_INCREMENT,

    user_email VARCHAR(320),

    user_joined DATATIME,
    user_last_seen DATATIME,

    user_name_first VARCHAR,
    user_name_last VARCHAR,

    user_name_alias VARCHAR,

    user_location_country VARCHAR,
    user_location_region VARCHAR,
    user_location_city VARCHAR

    # ...
);

显然,这种方法根本不具有可扩展性,并且添加其他属性也很烦人。唯一的优势是我可以快速搜索与特定属性集匹配的用户。我做了一些调查,发现这是一种相当常见的方法(例如WordPress)。

我的第二种方法(我目前正在尝试的方法)要可扩展得多,但我有一点担心性能问题:

CREATE TABLE user(
    id INT UNSIGNED NOT NULL AUTO_INCREMENT,

    user_email VARCHAR(320)
);

CREATE TABLE user_profile(
    user_id INT UNSIGNED NOT NULL,

    visibility ENUM('PRIVATE', 'PUBLIC'),

    name VARCHAR,
    value VARCHAR
);

使用这种方法,每个用户都有一组与其关联的键值对,这使得添加其他属性变得轻松,并在登录时加载用户配置文件。然而,我失去了第一种方法中所有的类型信息(例如DATETIME现在被存储为格式化字符串),因此某些搜索变得很烦人。这确实让我更加掌控选择哪些属性要公开显示给用户。
采用混合方法是否更好,可以平衡两种方法的优缺点?SO使用哪种方法?还有没有其他方法可以实现这一点,我是否考虑或错过了什么?
扩展:使用混合方法,将用户表中的属性插入到用户资料表中以控制其对其他用户的可见性是否有优势,或者可能被视为额外的开销?
4个回答

4

我建议采用混合方式。将一些基本属性,例如用户名、电子邮件、上次登录日期等添加到您的用户表中。次要重要性的项目可以作为键/值对添加。

这样,您仍然可以轻松搜索最基本的信息,并在不更改架构的情况下继续添加配置文件项。


3
混合方案不是一个好的选择。本质上,您正在将其他属性存储到属性包表中。从长远来看,这将使报告和查询变得复杂。此外,将日期、整数、小数、ntext等存储为varchar并不能以可接受的性能换取可扩展性。如果需要,您将如何在该表上创建关系?
更好的方法是为用户信息创建一个用户表。随着需求的扩展,创建代表新功能的新类。这些新类很可能有相应的表。这样,当与用户相关的属性属于它们自己的空间时,您的“用户”类不会呈指数级增长。是的,在未来,您可能真的会有一个新属性属于用户表。那时,您需要返回并调整架构和DBAL,但这是易于理解的代码的代价。
在您的示例中,第一个用户表中有用户的地址信息。我做的一件事是,我知道我不仅需要为用户存储地址。所以我会有一个单独的Address表,然后在User表中包含一个可为空的AddressId。这样,当我有一个Stores表、Events表时,我也可以在那里包括AddressId关系。这种方法的一个副作用是,当我返回并向Address对象添加lat/long时,我的数据模型中的每个人都会获得这些新属性。

我认为(如果我错了请纠正)这种方法随着时间的推移会受到“表膨胀”的影响,因为需要添加许多表来实现不同的功能? - Kevin Loney
我不确定表膨胀是否真的是一个问题。如果你有一个拥有1000个特征点但只有5个表的应用程序,我会非常怀疑表的规范化。马丁·福勒在这里讨论了表模块设计模式:http://martinfowler.com/eaaCatalog/tableModule.html。 - DavGarcia

0

出于性能和设计可扩展性的原因,我也会选择混合解决方案。

我倾向于将像users这样的表(我也喜欢在表名上使用复数形式)分解为其他对象通常操作的核心数据集,以及规范中那些基本上只写入的扩展数据,如“region”、“middleinitial”、“shoesize”,可以转移到一个可扩展且更新频率较低的区域。


0
为什么不使用XML字段来存储非必要的附加信息呢?
这可以在配置文件中进行配置,甚至可以进一步从配置生成UI控件。

XML不是适合此任务的正确工具,如果我需要处理那些非必要信息,将会导致非常荒谬的查询。在执行任何操作之前,我必须为每个结果解析XML,这将影响性能。 - Kevin Loney
微软在其成员身份验证提供程序中使用了相同的方法。您可以看一下。像上面的人们所解释的那样,该提供程序也有类似的解决方案。您关于性能的想法可能是正确的,因此建议仅在XML中存储您不希望查询的信息。 - Brendan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接