2009-01-09 69 views
7

我正在为一个网站的用户配置文件系统工作,并且正在思考什么是一种更好的(可伸缩的)方法。我已经提出了两种解决方案,正在寻找任何输入或者可能指向我可能错过的东西。选择一种方法来存储用户配置文件?

下面的create table语句并不是可执行的,但仅仅是为了给出所涉及的表格布局的概念。

我最初的想法是这样的:

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使用什么方法?还有没有想过或错过的另一种方法?

扩展:采用一种混合的方法会是有利的,也插入来自用户表的属性到user_profile表来控制自己的知名度给其他用户,或者可以说有可能被看作是额外的开销?

回答

3

混合解决方案不是一个好的解决方案。从本质上讲,您将其他属性存储到属性包表中。这将使报告和查询从长远来看变得复杂。此外,将日期,int,decimal,ntext等存储为varchar并不会成为可伸缩性的可接受交换。如果需要出现,你将如何在该桌子上创建关系?

更好的方法是为用户信息提供用户表。然后根据您的需求扩展创建代表新功能的新类。这些新班级可能会有相应的表格。这样,当与用户关联的属性属于他们自己的空间时,您的“用户”类不会呈指数级扩展。是的,将来你可能真的拥有属于用户表的新属性。此时,您需要返回并调整您的架构和DBAL,但那是易于理解的代码价格。

在您的示例中,您在第一个用户表中具有用户的地址信息。我做的一件事是我知道我需要存储地址,而不仅仅是用户。所以我将有一个单独的地址表,然后在用户表中包含可空的AddressId。这样,当我有一个Stores表,一个Events表时,我也可以包含AddressId关系。这种方法的一个副作用是,当我回去并向地址对象添加纬度/经度时,我的数据模型中的每个人都可以获得这些新属性。

+0

它让我感到(并纠正我,如果我错了),这种方法会随着时间的推移而受到'表膨胀'与大量的表被添加到数据库添加不同的功能? – 2009-01-09 23:30:16

+0

我不确定那张桌子是否真的有问题。如果你有一个拥有1000个特征点但只有5个表的应用程序,我会对表格的规范化持怀疑态度。 Martin Fowler在这里讨论表模块设计模式:http://martinfowler.com/eaaCatalog/tableModule.html – DavGarcia 2009-01-09 23:51:19

4

我会使用混合方法。一些基本的属性,如用户名,电子邮件,lastlogindate等应添加到您的用户表。次要重要项目可以添加为键/值对。

通过这种方式,您仍然可以轻松搜索最基本的信息,并在不更改模式的情况下继续添加配置文件项目。

0

由于性能和设计可扩展性的原因,我也会使用混合解决方案。

我倾向于认为像users这样的表(我也喜欢表名上的复数)需要被分解成其他对象常用的核心数据集,以及那些基本上只写数据的扩展位像“区域”,“中间初始化”,“鞋大小”这样的规范可以转移到一个可扩展和不太频繁更新的区域。

0

为什么不用XML字段来存储不必要的附加信息。

这可以在配置文件中配置,你甚至可以更进一步并从配置文件生成UI控件。